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

Add support for images with units#27721

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

Draft
dstansby wants to merge13 commits intomatplotlib:main
base:main
Choose a base branch
Loading
fromdstansby:image-units

Conversation

dstansby
Copy link
Member

@dstansbydstansby commentedJan 30, 2024
edited
Loading

PR summary

This PR adds machinery for the data array given to aScalarMappable to have units, and for those units to be used with images and associated colorbars.

Fixes#25062
Fixes#17447
Fixes#19476
Fixesastropy/astropy#11306

Still needs a user facing example adding, but opening to get early feedback and full CI runs.

PR checklist

Copy link
Member

@story645story645 left a comment

Choose a reason for hiding this comment

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

So if this is scalarmappables than that I think should be the title, but I'm a bit confused about what's happening w/ categorical here especially given scatter categorical color is a pretty big use case for extending units to scalarmappable. Not that this PR has to do that, but I'm concerned about this PR preventing it.

Comment on lines 26 to 31
def _check_axis(axis):
if axis is None:
raise units.ConversionError(
"Categorical data does not support unit conversion that is not "
"attached to an x or y Axis."
)
Copy link
Member

Choose a reason for hiding this comment

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

huh? Does this mean no categorical color? Technically, categorical should work just fine w/ NoNorm (and a colorbar where the labels are in the middle rather than the edges).

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

This means no categorical color in this PR, because I didn't dive into the error it gave me... you raise a good point though that this PR should as a minimum not prevent categorical colorbars in the future. Let me take a look again at some point later this week, and I'll ping you with what I find.

story645 reacted with thumbs up emoji
Copy link
Member

Choose a reason for hiding this comment

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

What's the error? Just curious if it would be the same issue for#27706

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

It was

RuntimeError:<matplotlib.category.StrCategoryConverterobjectat0x126bcd610>failedwhentryingtoreturnthedefaultunitsforthisimage.Thismaybebecausesupporthasnotbeenimplementedfor`axis=None`inthedefault_units()method.

becauseStrCategoryConverter.default_units() actually uses theaxis argument (unlike all our other conversion interfaces.

I think this is fixable though, not sure why I just put those errors in... Don't have time now, but will chase categorical support next time I come back to this.

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

Actually I fixed it 🎉 . Definitely don't have time to push the fix now, but glad it works!

importmatplotlib.pyplotaspltfig,ax=plt.subplots()plt.imshow([["a","b"], ["c","d"]])plt.colorbar()plt.show()

Figure_1

story645 reacted with laugh emojistory645 reacted with hooray emoji
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, wondering if we can make a formatter for this, something gets to: (b/c is also useful for any of the discrete cases)

fig,ax=plt.subplots()im=ax.imshow(([[0,1,2], [2,0,1], [1,2,0]]),cmap=mcolors.ListedColormap(["tab:orange","tab:blue","tab:green"],3))cb=fig.colorbar(im)cb.set_ticks([1/3,1,1+2/3])cb.set_ticklabels([0,1,2])

Untitled

Copy link
Member

@story645story645Jan 30, 2024
edited
Loading

Choose a reason for hiding this comment

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

I think to do this as a legend would probably be via helper method that grabs the color->value mapping and generates the handles, something likehttps://matplotlib.org/devdocs/api/collections_api.html#matplotlib.collections.PathCollection.legend_elements but on ScalarMappable

(Which if you're cool w/ me branching off your PR, I may volunteer to do...)

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

Right, this is in a good enough state (== tests passing) now if you want to branch off and play around with the colorbar for categoricals. I'm not intending to change anything there myself in this PR, but would be happy to merge something into this branch/PR if it's not too complicated.

story645 reacted with thumbs up emoji
@story645story645 mentioned this pull requestJan 30, 2024
@dstansbydstansbyforce-pushed theimage-units branch 2 times, most recently from273d3f7 to574999dCompareJanuary 30, 2024 21:42
@dstansbydstansby marked this pull request as ready for reviewJanuary 31, 2024 09:24
@anntzer
Copy link
Contributor

One thing that may be nice(?) is if the unit machinery could also ensure that for categorical images, interpolation_stage isalways set to "rgba". (I guess the extra coupling between may be a bit awkward, though.) Indeed, for categoricals, interpolation_stage="data" is usually completely wrong (because category 1 isn't the "mean" of category 0 and category 2). A concrete example (but I've seen similar things quite often, typically when doing image segmentation):

importskimage.data# for sample data# a categorical image: which channel (r/g/b) of the image is the most intenseim=skimage.data.stereo_motorcycle()[0].argmax(2)fig,axs=plt.subplots(2)axs[0].imshow(im);axs[1].imshow(im,interpolation_stage="rgba")

This gives
out
where the bottom image clearly shows that the most intense channel is always either "r" (0, purple) or "b" (2, yellow); interpolation_stage="data" (top) mistakently shows sometimes "g" (1) as the most intense channel because it averages 0 and 2. (Ignore the few pixels at the middle top where green is indeed the most intense channel.)

story645 reacted with thumbs up emoji

@story645
Copy link
Member

The new colormapping pipeline merged (#28658) probably means that it'd be easier to create a new PR than rebase this one, but also should I think make the actual make it support units easier.

@dstansbydstansby marked this pull request as draftMarch 26, 2025 17:34
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@story645story645story645 left review comments

At least 1 approving review is required to merge this pull request.

Assignees
No one assigned
Projects
None yet
Milestone
No milestone
3 participants
@dstansby@anntzer@story645

[8]ページ先頭

©2009-2025 Movatter.jp