Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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

Merged

Conversation

jklymak
Copy link
Member

@jklymakjklymak commentedJun 23, 2021
edited
Loading

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

  • Has pytest style unit tests (andpytest passes).
  • IsFlake 8 compliant (runflake8 on changed files to check).
  • New features are documented, with examples if plot related.
  • Documentation is sphinx and numpydoc compliant (the docs shouldbuild without error).
  • Conforms to Matplotlib style conventions (installflake8-docstrings and runflake8 --docstring-convention=all).
  • New features have an entry indoc/users/next_whats_new/ (follow instructions in README.rst there).
  • API changes documented indoc/api/next_api_changes/ (follow instructions in README.rst there).

@jklymak
Copy link
MemberAuthor

importnumpyasnpimportmatplotlib.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.

@jklymakjklymakforce-pushed thecolorbar-try3-justmod-transform branch 3 times, most recently from0370b32 to735de0dCompareJune 24, 2021 03:28
@@ -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
Copy link
MemberAuthor

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....

@jklymakjklymakforce-pushed thecolorbar-try3-justmod-transform branch 2 times, most recently fromeab1f92 to32b38d2CompareJune 24, 2021 05:17
@jklymakjklymak added this to thev3.5.0 milestoneJun 24, 2021
@jklymakjklymak added the Release criticalFor bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions. labelJun 24, 2021
@jklymakjklymak marked this pull request as ready for reviewJune 24, 2021 05:20
@jklymakjklymakforce-pushed thecolorbar-try3-justmod-transform branch from32b38d2 to561d771CompareJune 24, 2021 14:32
@jklymakjklymak mentioned this pull requestJun 24, 2021
7 tasks
@jklymak
Copy link
MemberAuthor

... interesting wrinkle. If an axes has an_axes_locator that is notNone,tight_layout decides it can't handle it. Here the locator only is supposed to modify things in the direction perpendicular to the onetight_layout needs to worry about, so presumably it should be fine, but the warning still persists and breaks the docs build.

@greglucasgreglucas mentioned this pull requestJun 25, 2021
@greglucasgreglucas linked an issueJun 26, 2021 that may beclosed by this pull request
@greglucas
Copy link
Contributor

I have to say, this was actually fewer image changes than I was expecting :)
I have a bunch of small nitpicks in there, but overall I think this is a great simplification and really makes the logic easier to understand what is going on than the multi-axes dispatching.

np.testing.assert_allclose(cb.ax.get_position().extents,
[0.78375, 0.536364, 0.796147, 0.9], rtol=2e-3)


Copy link
Contributor

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.

Copy link
MemberAuthor

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.

except TypeError:
pass
lim = self._cbar._long_axis().get_view_interval()
self._cbar._short_axis().set_view_interval(*lim)
Copy link
Contributor

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?

Copy link
MemberAuthor

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.

Copy link
MemberAuthor

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

if self._cbar.orientation == 'vertical':
if aspect:
ax.set_aspect(aspect*shrink)
offset = offset * pos.height
Copy link
Contributor

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.

jklymak reacted with thumbs up emoji

# make the inner axes smaller to make room for the extend rectangle
top = elower + inner_length
top = eupper + 1
Copy link
Contributor

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.

jklymak reacted with thumbs up emoji
self.ax.outer_ax.add_patch(patch)
antialiased=False, transform=self.ax.transAxes,
hatch=hatches[0], clip_on=False)
self.ax.add_patch(patch)
Copy link
Contributor

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?

Copy link
MemberAuthor

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?

Copy link
Member

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?

Comment on lines 90 to 93
Colorbar(cax, cmap=cmap, norm=norm,
boundaries=boundaries, values=values,
extend=extension_type, extendfrac=extendfrac,
orientation='horizontal', spacing=spacing)
Copy link
Member

Choose a reason for hiding this comment

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

Dedent these also.

jklymak reacted with thumbs up emoji

def __call__(self, ax, renderer):

# make sure that lims and scales are the same
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 not sure why this is necessary; I understand from some comments that this is due to aspect ratio handling?

Copy link
MemberAuthor

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.

Copy link
MemberAuthor

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.

@jklymakjklymakforce-pushed thecolorbar-try3-justmod-transform branch from182a488 tob573664CompareJune 30, 2021 20:56
@jklymak
Copy link
MemberAuthor

jklymak commentedJun 30, 2021
edited
Loading

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 acolorbar.set_aspect andcolorbar.set/get_scale.These will need whats-new entries (done)

Comment on lines -1468 to +1466
cax.set_aspect(aspect, anchor=loc_settings["anchor"], adjustable='box')
cax.set_anchor(anchor)
Copy link
Member

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?

Copy link
MemberAuthor

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.

Copy link
Member

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.

Copy link
MemberAuthor

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...

@greglucas
Copy link
Contributor

Are theset_scale andset_aspect really necessary public functions on Colorbar and not just on the internal axis?

set_aspect: This is generally on anAxes, so why not leave it oncbar.ax and let the new locator work on that?

set_scale: I feel like this could cause confusion. The norm of the colorbar can be out of sync with the scale now? If I call cbar.set_scale('log')`, the ticks would be located in log-space, but the color normalization still done in linear space I believe.

@jklymak
Copy link
MemberAuthor

Are theset_scale andset_aspect really necessary public functions on Colorbar and not just on the internal axis?

set_aspect: This is generally on anAxes, so why not leave it oncbar.ax and let the new locator work on that?

This is the same ascolorbar(..., aspect=20), so it really is a colorbar method. The equivalent axes method isset_box_aspect, and indeedset_aspect will not work.

set_scale: I feel like this could cause confusion. The norm of the colorbar can be out of sync with the scale now? If I call cbar.set_scale('log')`, the ticks would be located in log-space, but the color normalization still done in linear space I believe.

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.

@greglucas
Copy link
Contributor

Your new AxesLocator is the only thing callingcbar.set_aspect though because you just put it in. I'm suggesting that you can put these two calls up in the locator instead, without introducing new public API. (You added these two calls into ConstrainedLayout already, so I think the same idea could be applied in the Locator)

self.ax.set_box_aspect(aspect)self.ax.set_aspect('auto')

Indeed it will only change the scale and not have anything to do with the norm's scale.

This seems like a real reason not to make this public. In your calls toself.set_scale(), you already have the long axis attribute above, so why not callself._long_axis().set_scale() there instead of introducing the new API?

@jklymak
Copy link
MemberAuthor

I'm suggesting that you can put these two calls up in the locator instead, without introducing new public API.

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?

so why not call self._long_axis().set_scale() there instead of introducing the new API?

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.

@jklymakjklymakforce-pushed thecolorbar-try3-justmod-transform branch from514192f toe391e62CompareJuly 1, 2021 16:44
@jklymakjklymakforce-pushed thecolorbar-try3-justmod-transform branch from70621cd to5a5d1bbCompareJuly 6, 2021 00:32
Comment on lines -1468 to +1466
cax.set_aspect(aspect, anchor=loc_settings["anchor"], adjustable='box')
cax.set_anchor(anchor)
Copy link
Member

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.

@jklymakjklymakforce-pushed thecolorbar-try3-justmod-transform branch fromf0ca1e0 to914b750CompareJuly 6, 2021 13:42
@jklymakjklymak mentioned this pull requestJul 7, 2021
7 tasks
@QuLogic
Copy link
Member

I assume you'll fix the last thing.

@jklymak
Copy link
MemberAuthor

@QuLogic, sorry, what "last thing"? The anchor passthrough? I think the new code is correct...

Copy link
Contributor

@greglucasgreglucas left a 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 good to go as well and the other issues with the norms/scales can be addressed in later PRs. Thanks for the updates and separating things out@jklymak! I'll let@QuLogic merge once he feels his comment is resolved.

@QuLogic
Copy link
Member

@QuLogic, sorry, what "last thing"? The anchor passthrough? I think the new code is correct...

#20501 (comment)longax wasn't removed.

jklymak reacted with thumbs up emoji

@jklymakjklymakforce-pushed thecolorbar-try3-justmod-transform branch 2 times, most recently from8caf7dd to7884314CompareJuly 7, 2021 20:08
Copy link
Member

@tacaswelltacaswell left a 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!

@jklymakjklymakforce-pushed thecolorbar-try3-justmod-transform branch from7884314 tob574177CompareJuly 7, 2021 20:44
Previous 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.
@jklymakjklymakforce-pushed thecolorbar-try3-justmod-transform branch fromb574177 to277b5ebCompareJuly 7, 2021 20:46
@jklymakjklymak merged commit4d1cd5e intomatplotlib:masterJul 8, 2021
@jklymakjklymak deleted the colorbar-try3-justmod-transform branchJuly 8, 2021 00:12
@jklymak
Copy link
MemberAuthor

Thanks@QuLogic and@greglucas for all your help!

greglucas reacted with thumbs up emoji

@greglucasgreglucas mentioned this pull requestJul 9, 2021
7 tasks
@jklymakjklymak mentioned this pull requestJul 28, 2021
7 tasks
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@tacaswelltacaswelltacaswell approved these changes

@QuLogicQuLogicQuLogic approved these changes

@greglucasgreglucasgreglucas approved these changes

Assignees
No one assigned
Labels
Release criticalFor bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.topic: color/colorbar
Projects
None yet
Milestone
v3.5.0
Development

Successfully merging this pull request may close these issues.

matplotlib 3.5 breaks yt ColorbarAxes is an imperfect proxy for the Axes passed to Colorbar
5 participants
@jklymak@greglucas@QuLogic@tacaswell@ericpre

[8]ページ先頭

©2009-2025 Movatter.jp