Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork7.9k
Colorbar redo again!#20501
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Colorbar redo again!#20501
Uh oh!
There was an error while loading.Please reload this page.
Conversation
4becc5b
to114e8d3
Compareimportnumpyasnpimportmatplotlib.pyplotasplt#from matplotlib.backend_bases import MouseButtondefpick_fn(mouseevent):ifmouseevent.inaxesiscolorbar.ax:print('pick\n\nPICKKKKKKK')print(mouseevent.ydata,mouseevent.button)defmotion_fn(mouseevent):ifmouseevent.inaxesiscolorbar.ax:print(mouseevent.ydata,mouseevent.button)passfig,ax=plt.subplots()canvas=fig.canvasarr=np.random.randn(100,100)axesimage=plt.imshow(arr)colorbar=plt.colorbar(axesimage,ax=ax,use_gridspec=True)# helps you see what value you are about to set the range tocolorbar.ax.set_navigate(True)canvas.mpl_connect("motion_notify_event",motion_fn)colorbar.ax.set_picker(True)canvas.mpl_connect("button_press_event",pick_fn)plt.show() works fine on this PR. |
Uh oh!
There was an error while loading.Please reload this page.
0370b32
to735de0d
Compare@@ -2369,6 +2369,8 @@ def _update_patch_limits(self, patch): | |||
return | |||
patch_trf = patch.get_transform() | |||
updatex, updatey = patch_trf.contains_branch_seperately(self.transData) | |||
if not (updatex or updatey): | |||
return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Calling the transform below blows up needlessly because it is called, and then does nothing....
eab1f92
to32b38d2
Compare32b38d2
to561d771
Compare... interesting wrinkle. If an axes has an |
I have to say, this was actually fewer image changes than I was expecting :) |
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
np.testing.assert_allclose(cb.ax.get_position().extents, | ||
[0.78375, 0.536364, 0.796147, 0.9], rtol=2e-3) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Surely this test was there for a reason, especially saying it was a "funny" error. Makes it seem like this should be investigated and updated rather than removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
This was testing the extend length being correct (its my test). We could go ahead and keep testing this, but it'd properly require an image test.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
lib/matplotlib/colorbar.py Outdated
except TypeError: | ||
pass | ||
lim = self._cbar._long_axis().get_view_interval() | ||
self._cbar._short_axis().set_view_interval(*lim) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Do you also want to update the data interval of the short axis here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I'm not sure what you mean? We need to do this to make the aspect ratio of the colobar correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
OK, this has been removed. See comments
Uh oh!
There was an error while loading.Please reload this page.
lib/matplotlib/colorbar.py Outdated
if self._cbar.orientation == 'vertical': | ||
if aspect: | ||
ax.set_aspect(aspect*shrink) | ||
offset = offset * pos.height |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
*=
or even just explicitly putoffset * pos.height
into the translated call below.
lib/matplotlib/colorbar.py Outdated
# make the inner axes smaller to make room for the extend rectangle | ||
top = elower + inner_length | ||
top = eupper + 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
For consistency I'd suggest either definingbot = -elower
here and using that below or using1 + eupper
in the calculations.
self.ax.outer_ax.add_patch(patch) | ||
antialiased=False, transform=self.ax.transAxes, | ||
hatch=hatches[0], clip_on=False) | ||
self.ax.add_patch(patch) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Because you're settingclip_on=False
here, do you need to adjust the zorder of the patch at all so that it is behind the main axes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I think this is as it was before?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
This seems reasonable with the layer between the patch, the outline, and then the fill-ins for the extensions.
We do not keep a (named) reference to these patches, what do we do if we update the colormap?
Colorbar(cax, cmap=cmap, norm=norm, | ||
boundaries=boundaries, values=values, | ||
extend=extension_type, extendfrac=extendfrac, | ||
orientation='horizontal', spacing=spacing) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Dedent these also.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
lib/matplotlib/colorbar.py Outdated
def __call__(self, ax, renderer): | ||
# make sure that lims and scales are the same |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I'm not sure why this is necessary; I understand from some comments that this is due to aspect ratio handling?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Right, the aspect of the axes is presently set via the usualax.set_aspect
, but that requires the limits and scales of the short and long axes to be the same.
However I'm starting to think that is a mistake, and we should perhaps just use something likeset_box_aspect
and get around all this awkwardness. Or just do it with the new colorbar axes locator.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
See comments, this has all be re-engineered.
182a488
tob573664
Comparejklymak commentedJun 30, 2021 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
latest commit changes the aspect ratio handling from a data-aspect ratio to a box aspect ratio. The "short" side of the colorbar now always has a linear scale and limits from 0-1, and only the "long" side gets a scale and variable data limits. This simplifies a lot of code.. Note I've added a |
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
cax.set_aspect(aspect, anchor=loc_settings["anchor"], adjustable='box') | ||
cax.set_anchor(anchor) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Wasloc_settings["anchor"]
an error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Yeah, I assume thatanchor
was just ignored if passed as a kwarg. I'm not sure what happens if itis passed as a kwarg.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Strange, it should just go through toset_anchor
if it's notNone
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I think what is happening here is correct, and the old code was ignoring the user's specification ofanchor
, but maybe I'm not following...
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Are the
|
This is the same as
I needed to make this method, and didn't see that it needed to be private, but I don't feel strongly about it. Indeed it will only change the scale and not have anything to do with the norm's scale. |
Your new AxesLocator is the only thing calling self.ax.set_box_aspect(aspect)self.ax.set_aspect('auto')
This seems like a real reason not to make this public. In your calls to |
Absolutely. I'm just suggesting it may be more-generally useful as well to be able to set this after creating the colorbar, so why not expose it?
Yes, there is no reason for it to be public, other than user convenience. As I said, I don't feel super strongly about exposing this, but wehave had requests to change the scale without changing the norm. For instance, it is not completely unreasonable to have a linear scale and a logarithmic norm. |
514192f
toe391e62
Compare70621cd
to5a5d1bb
CompareUh oh!
There was an error while loading.Please reload this page.
cax.set_aspect(aspect, anchor=loc_settings["anchor"], adjustable='box') | ||
cax.set_anchor(anchor) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Strange, it should just go through toset_anchor
if it's notNone
.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
f0ca1e0
to914b750
CompareUh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
I assume you'll fix the last thing. |
@QuLogic, sorry, what "last thing"? The anchor passthrough? I think the new code is correct... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
#20501 (comment) |
8caf7dd
to7884314
CompareThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Anyone can merge on CI green!
7884314
tob574177
ComparePrevious overhaul packaged an inner and outer axes in a container"ColorbarAxes" and tried to dispatch methods between them.This overhaul takes the _much_ simpler approach of resizing theimage using a custom _axes_locator that a) calls any existing locatorb) or just uses the axes default position. The custom _axes_locatorthen shrinks the axes in the appropriate direction to make room forextend tri/rectangles. As with the previous fix, the extendtri/rectangles are drawn as patches in axes co-ordinates, rather thanpcolormesh in "data" co-ordinates.
b574177
to277b5eb
CompareThanks@QuLogic and@greglucas for all your help! |
Uh oh!
There was an error while loading.Please reload this page.
PR Summary
OK, third time is the charm.
Previous overhaul packaged an inner and outer axes in a container "ColorbarAxes" and tried to dispatch methods between them.
This overhaul takes themuch simpler approach of resizing the image using a custom _axes_locator that a) calls any existing locator b) or just uses the axes default position. The custom _axes_locator then shrinks the axes in the appropriate direction to make room for extend tri/rectangles. As with the previous fix, the extend tri/rectangles are drawn as patches in axes co-ordinates, rather than pcolormesh in "data" co-ordinates.
This addresses the concerns andcloses#20479
PR Checklist
pytest
passes).flake8
on changed files to check).flake8-docstrings
and runflake8 --docstring-convention=all
).doc/users/next_whats_new/
(follow instructions in README.rst there).doc/api/next_api_changes/
(follow instructions in README.rst there).