Add keyword argument in PColorMeshItem to enable consistent colormap scaling during animation#2463
Conversation
…scaling during animation.
…s `colorMap` and `limit`
|
Hi @SimenZhor ! I am sure @j9ac9k will jump right in and have a closer look, but I wanted to comment on the What you are looking for are the levels, as described in the Do you think Otherwise this feature seems like a great addition, and indeed quite essential for some applications. Nice to see |
|
Hi @NilsNemitz. Thanks for the encouraging response! You are of course right about the kwarg naming. I'll make an update where I rename to Rewriting I've played around a bit with the # Ex1.1:
## Default behavior (autoscaling with each frame)
[...]
img = pg.ImageItem() # Setting levels here makes no difference to the end result in this example
[...]
def updateData():
[...]
img.setImage(data[i])
# Ex2.1:
## "Keep what you have" behavior
[...]
img = pg.ImageItem(levels=[1000,1500])
[...]
def updateData():
[...]
img.setImage(data[i], autoLevels=False) # autoLevels must be explicitly disabled for each frameCorresponding examples for this PR: # Ex1.2:
## Default behavior (autoscaling with each frame)
[...]
pcmi = pg.PColorMeshItem()
[...]
def updateData():
[...]
pcmi.setData(new_x, new_y, new_z)
# Ex2.2:
## "Set and forget" behavior
[...]
pcmi = pg.PColorMeshItem(levels=(-2,2))
[...]
def updateData():
[...]
pcmi.setData(new_x, new_y, new_z) # No need to explicitly disable autoscalingIf the autoLevels behavior is a well known and expected I'll gladly add it here, although I personally feel like it is slightly counter intuitive to continuously disable a setting. |
…onvention in ImageItem and ColorBarItem
|
I agree that continuously setting In terms of intuition, I guess it depends on which direction you are coming from. Sometimes the API design didn't quite make the leap to "Set the parameters at 100 FPS." Your comparison is awesome. How can we make both of these work the same way and still be intuitive and smooth for what you are trying to do? I don't think we want to have How about making your code work like # Ex2.3:
## Compatible "Set and forget" behavior
[...]
pcmi = pg.PColorMeshItem(enableAutoLevels=False, levels=(-2,2))
[...]
def updateData():
[...]
pcmi.setData(new_x, new_y, new_z) # No need to explicitly disable autoscalingThen we can port the |
|
I think your suggestion sounds like a good middle ground. Should we wait for others to weigh in, or should I suggest an implementation right away? |
Add enableAutoLevels parameter to PColorMeshItem and autoLevels parameter to PColorMeshItem.setData() in order to conform with known APIs from ViewBox and ImageItem
|
@NilsNemitz, I've just pushed a suggestion for what the implementation of this behavior may look like. Let me know if you have any further comments or suggestions 😄 |
j9ac9k
left a comment
There was a problem hiding this comment.
Sorry I've been quiet on this subject despite @NilsNemitz 's repeated poking. This kind of API decision-making is something I'm absolutely rubbish at and I almost always defer to a consensus from other maintainers and contributors.
I have no issue with the proposed change. I just have some nit-picky comments for the docstring.
Thanks for the PR @SimenZhor !
Fix typos and improve code quality
|
I made the improvements that were pointed out by @j9ac9k. Are there any next steps for me now, or just wait for more people to have the time to review my code? :) |
|
Hi @SimenZhor I'm good w/ the PR as is, I'm going to leave it open in hopes to get the nod of agreement from @outofculture whose done a lot of the work with ImageItem if nobody brings up issues in a day or so, I'll merge 👍🏻 Thanks for the submission! |
outofculture
left a comment
There was a problem hiding this comment.
This code looks good. I would say that the only improvement I can think of would be to provide methods for setting the levels and auto-levels attributes. I would like to say this is a trivial thing to add, but part of the job would be refactoring setData to separate out the steps that belong in an _updateDisplayWithCurrentState method from the rest of it, such that you could elsewhere write e.g.:
def setLevels(self, levels):
self.levels = levels
self._updateDisplayWithCurrentState()If you feel up for this challenge, that would be a valuable improvement, but this PR can otherwise be accepted as-is.
|
@outofculture I agree. That makes total sense. I've already started work on a new branch for a future PR where I'm planning to add ColorBar support as well to PColorMeshItem. In this usecase, the I don't know if you prefer to wait for the work on that branch to be done or if we should just merge this one to keep the PRs shorter and cleaner. I suspect there will be a lot more discussion for getting the ColorBar support right. So, if possible, I'd prefer to do that in a different PR. I could of course include the setters in this PR, without doing full support for ColorBar. I'll leave that up to you. |
|
I'm indifferent to that change being part of this PR vs a separate PR. I'll likely squash the PR on merge unless the change is quite massive, and if which case it is, I may ask (and I may be willing to help with) rebasing such that there are only a few commits that contain well-contained changes. |
|
Sounds good, @j9ac9k. I'd still prefer to keep them separate though. I've barely started looking at the new feature, and if the consensus is that this PR is ok as-is (even though it could be improved) I'm happy to continue working on the other stuff at my own pace. |
|
Sounds good to me, I'll merge as is. thanks for the PR @SimenZhor ! |
I've added a new keyword argument to PColorMeshItem that allows absolute scaling of the colormap (in addition to the autoscaling that is already present, and still default). This is especially useful when plotting animations where the absolute value of the z axis (color) matters. I've also modified the PColorMeshItem example to showcase why this feature might be important in certain cases.
I see that ColorBarItem uses both
limitsandlevelsabout the corresponding parameter, so I wasn't exactly sure what to call it, but I ended up withlimitsas I felt that was most self explanatory.This is my first PR in this repo, so I might have missed some mandatory updates. In that case, please let me know, and I will try to amend the mistakes.