8000 CenteredNorm changes by greglucas · Pull Request #24132 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

CenteredNorm changes #24132

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 23, 2022
Merged

CenteredNorm changes #24132

merged 1 commit into from
Nov 23, 2022

Conversation

greglucas
Copy link
Contributor

PR Summary

This updates CenteredNorm to be consistent between all setting/getting of vcenter, halfrange, vmin, and vmax. The norm is defined by vcenter and halfrange, and vmin/vmax are adjusted accordingly.

Currently, if we change the center of the norm, the halfrange also gets updated based on the distance away from the previous vmin/vmax values. This "feature" is hard to maintain in this refactor, so I'm going to propose that this should be changed to not modify halfrange (i.e. if I update vcenter I just pan the center limit and keep the linear scaling out from the center fixed). I'm not sure how easy it would be to deprecate, so I think this needs some discussion and should not be backported to 3.6.

Additionally, now setting vmin or vmax is equivalent to updating the halfrange from either vcenter - vmin or vmax - vcenter.

xref: #24093

PR Checklist

Tests and Styling

  • Has pytest style unit tests (and pytest passes).
  • Is Flake 8 compliant (install flake8-docstrings and run flake8 --docstring-convention=all).

Documentation

  • [N/A] New features are documented, with examples if plot related.
  • [N/A] New features have an entry in doc/users/next_whats_new/ (follow instructions in README.rst there).
  • API changes documented in doc/api/next_api_changes/ (follow instructions in README.rst there).
  • [N/A] Documentation is sphinx and numpydoc compliant (the docs should build without error).

Comment on lines -468 to +489
# set vcenter to 1, which should double halfrange
# set vcenter to 1, which should move the center but leave the
# halfrange unchanged
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what I found odd. Updating vcenter should double the halfrange? Those seem like the two fixed quantities to me and one shouldn't update the other. I think this would better be handled by doing an autoscale after setting vcenter if you want this functionality.

@tacaswell tacaswell added this to the v3.7.0 milestone Oct 9, 2022
@tacaswell tacaswell mentioned this pull request Oct 12, 2022
6 tasks
@greglucas greglucas marked this pull request as ready for review November 3, 2022 21:36
@anntzer
Copy link
Contributor
anntzer commented Nov 10, 2022

Based on today's call I agree with the changes here, though the backcompat issue will need to be decided on.

@greglucas
Copy link
Contributor Author

I added a "behavior change" release note identifying the change in behavior for that specific aspect of this update.


Previously, the halfrange would expand in proportion to the
amount that vcenter was moved away from either vmin or vmax. Now,
the halfrange will not be updated when vcenter is changed. If the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm maybe slightly confused about how vcenter, vmin, vmax, and half range stayed in sync before this change and stay in sync after this change and I think a sentence on each might make the change more clear?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, it is confusing what was happening vs whats new. I added a couple of code blocks to try and demonstrate what previously happened and what is happening now. It seems a bit long though still...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fine, especially since this is the behavior change rather than the whats new and the behavior changes page tends to be not as packed w/ stuff.

# norm.halfrange == 1, vmin == 0, vmax == 2

The **halfrange** can be set manually or ``norm.autoscale()``
can be used to autmatically set the limits after setting **vcenter**.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
can be used to autmatically set the limits after setting **vcenter**.
can be used to automatically set the limits after setting **vcenter**.

spelling

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 fixed, and squashed the commits.

This changes CenteredNorm to use vmin and vmax to represent the
halfrange rather than storing it separately and needing to update
the vmin/vmax in all of the methods.

Additionally, if you now change vcenter, the halfrange does not
automatically update.
Comment on lines +1539 to +1545
def vmin(self, value):
value = _sanitize_extrema(value)
if value != self._vmin:
self._vmin = value
self._vmax = 2*self.vcenter - value
self._changed()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a slight confusion - what happens to half range when these are changed?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

halfrange is an @property which is dynamically computed from vmin/vmax and is not held in memory directly (and inversely sets vmin/vmax in the @halfrange.setter)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

halfrange is defined by vmin/vmax now, so the halfrange is shrunk/expanded accordingly. I added a couple of tests at the end to demonstrate what the expected behavior of this is. (vcenter constant, halfrange changed)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks I missed that part of the code 😅

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, so just to confirm, basically calling self.halfrange(val) updates the min and max, so that then self.halfrange = self.halfrange() which is why there's no self._halfrange - sorry I'm tired

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(though caveat that it is a property, so the syntax is self.halfrange = self.halfrange (which looks odd, but that is why there is a comment) and self.halfrange = val rather than the parentheses version)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants
0