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

ENH: allow image to interpolate post RGBA#18782

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 commentedOct 21, 2020
edited
Loading

PR Summary

This implements a new boolean kwarginterp_postrgba toimshow that implements the interpolation after the data has been normed and mapped to RGBA.

Motivation

In the depths of time, we interpolated images in RGBA space, but this was deemed unacceptable in that it produces image pixels that are not in the colormap. So the interpolation was moved to be before the norm and colormapping. That has proven troublesome with respect to over/under data, but generally seems to work.

However, there are many cases, particularly when trying to antialias, that we really want to average in RGBA space, and allow colors that are out of the colormap because they visually merge adjacent pixels.

Proposal:

A kwarg,interp_space that allows the interpolation to be carried out before or after the RGBA mapping has been made. The way this is implemented now, it is just a toggle - i.e. you cannot interpolate both beforeand after the RGBA mapping. That is not impossible, but probably not typically needed or desired, and would make the code considerably messier. As it is, its quite a straightforward change.

Note the change could be made a level higher in_axes.imshow, however, this implementation allows us to skip all the mapping jiggery that we do for data space.

Result

importmatplotlib.pyplotaspltimportnumpyasnpimportmatplotlib.colorsasmcolorsimportmatplotlib.cmascmimportcopyfig,axs=plt.subplots(2,2,figsize=(5.5,5.5),sharex=False,sharey=False,constrained_layout=True)N=250aa=np.ones((N,N))aa[::2, :]=-1x=np.arange(N)/N-0.5y=np.arange(N)/N-0.5X,Y=np.meshgrid(x,y)R=np.sqrt(X**2+Y**2)f0=10k=75a=np.sin(np.pi*2* (f0*R+k*R**2/2))a[:int(N/2),:][R[:int(N/2),:]<0.4]=-1a[:int(N/2),:][R[:int(N/2),:]<0.3]=1aa[:,int(N/2):]=a[:,int(N/2):]aa[20:50,20:50]=np.NaNaa[70:90,70:90]=1e6aa[70:90,20:30]=-1e6aa[70:90,195:215,]=1e6aa[20:30,195:215]=-1e6cmap=copy.copy(cm.RdBu_r)cmap.set_over('yellow')cmap.set_under('cyan')axs=axs.flatten()axs[0].imshow(aa,interpolation='nearest',cmap=cmap,vmin=-1.2,vmax=1.2)axs[0].set_title('Zoomed')axs[0].set_xlim([N/2-25,N/2+25])axs[0].set_ylim([N/2+50,N/2-10])axs[1].imshow(aa,interpolation='nearest',cmap=cmap,vmin=-1.2,vmax=1.2)axs[1].set_title('No antialiasing')axs[2].imshow(aa,interpolation='antialiased',cmap=cmap,vmin=-1.2,vmax=1.2)axs[2].set_title('Data antialiasing')pc=axs[3].imshow(aa,interpolation='antialiased',interp_space='rgba',cmap=cmap,vmin=-1.2,vmax=1.2 )axs[3].set_title('RGBA antialiasing')foraxinaxs:ax.set_xticklabels([])ax.set_yticklabels([])plt.show()fordpiin [50,100,200,400,800]:fig.savefig(f'res{dpi}.png',dpi=dpi)

400 dpi

At 400 dpi the images are not downsampled, so all three versions are the same

res400

200 dpi

Notice how at 100 dpi the alternating blue/red in the data interpolation go to white (the average of -1 and 1), with some obvious residual aliasing. The RBGA interpolation goes to purples (red+blue = purple).

res200

100 dpi

res100

50 dpi

Note that pixel peeping at the "over" and "under" you can definitely see pixels that leak out of the colormap (i.e. cyan+purple, or yellow + blue).

res50

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 andpydocstyle<4 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).

@jklymakjklymak marked this pull request as draftOctober 21, 2020 02:53
@jklymak
Copy link
MemberAuthor

This just needs tests and improved docs. But the idea is complete and could be discussed.@tacaswell@brunobeltran@efiring@dopplershift@anntzer ?

@jklymakjklymak linked an issueOct 21, 2020 that may beclosed by this pull request
@jklymak
Copy link
MemberAuthor

ping@tacaswell - if you had time you said you'd weigh in on this one. I actually think this is a pretty simple addition, even if it will be abit tricky to explain...

@jklymakjklymak mentioned this pull requestFeb 1, 2021
7 tasks
@jklymakjklymakforce-pushed theenh-image-postrgba-interpolate branch from5017129 tof50ab9aCompareMarch 21, 2021 16:02
@jklymakjklymak added this to thev3.5.0 milestoneMar 21, 2021
@jklymakjklymak linked an issueMar 21, 2021 that may beclosed by this pull request
@jklymakjklymak requested a review fromtacaswellMarch 21, 2021 16:04
@jklymakjklymak linked an issueMar 31, 2021 that may beclosed by this pull request
@jklymak
Copy link
MemberAuthor

#19838 is another nice example where data-interpolation on down-sampling is very undesirable.

@jklymak
Copy link
MemberAuthor

jklymak commentedJul 9, 2021
edited
Loading

For Comment: this kwarg is currentlyinterp_postrgba=True/False. I wonder if it should just beantialiased=True/False and just apply our favourite anti-aliasing filter. I'm also not clear if it should be independent ofinterpolation...

@jklymakjklymak added the status: needs comment/discussionneeds consensus on next step labelJul 9, 2021
@anntzer
Copy link
Contributor

IIUC#19748 (comment) essentially suggests that this should rather be something likeinterp_space={"raw"/"orig", "normed", "cmapped"}?

@jklymak
Copy link
MemberAuthor

OK, so changed tointerp_space = "data"/"rgba". That leaves addinginterp_sapce="normed" for future work. I'm not sure how we want to do that exactly, and I don't think anything in this PR stops that from working.

@jklymakjklymakforce-pushed theenh-image-postrgba-interpolate branch from40bd8a9 to5560fb0CompareJuly 19, 2021 18:10
@@ -5380,6 +5381,12 @@ def imshow(self, X, cmap=None, norm=None, aspect=None,
which can be set by *filterrad*. Additionally, the antigrain image
resize filter is controlled by the parameter *filternorm*.

interp_space : str, default: None
Copy link
Contributor

Choose a reason for hiding this comment

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

str ->{'data', 'rgba'}, default: 'data'

jklymak reacted with thumbs up emoji
interp_space : str, default: None
Supported values are 'data' and 'rgba'. If 'data' interpolation
is carried out on the data provided by the user. If 'rgba', the
interpolation is carried out afte the colormapping has been
Copy link
Contributor

Choose a reason for hiding this comment

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

after (typo)

jklymak reacted with thumbs up emoji
interpolation=None, alpha=None, vmin=None, vmax=None,
origin=None, extent=None, *, filternorm=True, filterrad=4.0,
resample=None, url=None, **kwargs):
interpolation=None, interp_space=None, alpha=None,
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't thinkanyone is passing alpha positionally, so I guess the API break is safe, but in that case you may as well make all kwargs starting frominterp_space keyword-only (as you effectively broke backcompat on passingalpha positionally).

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

OK, not intentionally. How far down the stack do we want to break it, if we had our druthers? I'd probably put the* afternorm and beforeaspect?

Copy link
Contributor

@anntzeranntzerJul 19, 2021
edited
Loading

Choose a reason for hiding this comment

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

Seems about right to me. OTOH you can also just stickinterp_space in the kwonly section for now and put a@_api.make_keyword_only("3.5", "aspect") and fix the order in 3.7 to strictly follow the policy. No strong opinion there.

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

I deprecated most of them! (ahem, maybe we don't want this, but I really doubt too many people are using positional arguments for all of these)

Copy link
Contributor

Choose a reason for hiding this comment

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

you only need to do it for the first one; the following ones implicitly become keyword-only as well (because you can't pass them positionally anymore without passing the first one positionally) :)

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

ooops, duh!

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

If I do this, I get an error on import

Traceback (most recent call last):  File "/Users/jklymak/matplotlib/examples/images_contours_and_fields/image_antialiasing.py", line 20, in <module>    import matplotlib.pyplot as plt  File "/Users/jklymak/matplotlib/lib/matplotlib/pyplot.py", line 2875, in <module>    def imshow(  File "/Users/jklymak/matplotlib/lib/matplotlib/pyplot.py", line 101, in _copy_docstring_and_deprecators    func = decorator(func)  File "/Users/jklymak/matplotlib/lib/matplotlib/_api/deprecation.py", line 417, in make_keyword_only    assert (name in signature.parametersAssertionError: Matplotlib internal error: 'aspect' must be a positional-or-keyword parameter for imshow()

Copy link
Contributor

Choose a reason for hiding this comment

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

Oops, I guess (I'm almost sure, actually) that make_keyword_only currently doesn't work with functions that have pyplot wrappers, because make_keyword_only fakes the displayed function signature to pretend that the switch to kwonly already occurred, but the pyplot wrapper should be generated using the old (non-kwonly) signature, but that's not the case right now.
It's going to be slightly annoying to fix but probably just needs some wrangling, can you open a separate issue to track this? In any case I don't think this is required for this PR.

jklymak reacted with thumbs up emoji
Parameters
----------
s : str or None
str should be one on "data", "normed", or "rgba"
Copy link
Contributor

Choose a reason for hiding this comment

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

not "normed", for now.
ditto for the parameter description (as above)

jklymak reacted with thumbs up emoji
s = "data" # placeholder for maybe having rcParam
if s not in ["data", "rgba"]:
raise ValueError("interp_space must be one of 'data' "
"or 'rgba'.")
Copy link
Contributor

Choose a reason for hiding this comment

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

_api.check_in_list.

jklymak reacted with thumbs up emoji
Supported values are 'data' and 'rgba'. If 'data' interpolation
is carried out on the data provided by the user. If 'rgba', the
interpolation is carried out afte the colormapping has been
applied (visual interpolation).
Copy link
Contributor

Choose a reason for hiding this comment

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

one space too many before the last opening parenthesis.

jklymak reacted with thumbs up emoji
@anntzer
Copy link
Contributor

lgtm, modulo tests/docs. Thanks for doing this :)

@jklymakjklymakforce-pushed theenh-image-postrgba-interpolate branch from0c855aa toa90a206CompareJuly 19, 2021 23:47
@jklymakjklymak marked this pull request as ready for reviewJuly 20, 2021 04:08
@jklymakjklymak added status: needs review and removed status: needs comment/discussionneeds consensus on next step labelsJul 20, 2021
@jklymak
Copy link
MemberAuthor

@tacaswell I'll try and pop this onto your review queue, at least for high-level comment

@jklymakjklymakforce-pushed theenh-image-postrgba-interpolate branch from197516b toef3f515CompareJuly 20, 2021 20:31
tacaswell
tacaswell previously requested changesJul 21, 2021
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.

I would like a version of#18487 to go in with this.

I'm still not fully convinced that this is not wrong, but have accepted that my instinct is from a career of working with data from 2D detectors and this behavior is sensible in some domains.

Another way to look at this is that it is putting in an option to get back to the mpl <2.0 behavior.

@@ -885,6 +911,7 @@ def __init__(self, ax,
cmap=None,
norm=None,
interpolation=None,
interp_space=None,
Copy link
Member

Choose a reason for hiding this comment

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

This should go at the end (kwarg only preferably), or we need a deprecation note.

jklymak reacted with thumbs up emoji
#
# Conversely, when the anti-aliasing occurs in 'rgba' space, the red and
# blue are combined visually to make purple. This behaviour is more like a
# typical image processing package.
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
# typical image processing package.
# typical image processing package but may produce colors in output which are not present
# in the colormap confounding interpretation of the image.

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

Changed to

#... This behaviour is more like a# typical image processing package, but note that purple is not in the # original colormap, so it is no longer possible to invert individual# pixels.

The point here is that if you have adequate resolution, you shouldnot be inverting individual pixels.

subsampling the smoothed data. In Matplotlib, we can do that
smoothing before mapping the data to colors, or we can do the smoothing
on the RGB(A) data in the final image. The difference between these is
shown below, and controlled with the *interp_space* keyword argument.
Copy link
Member

Choose a reason for hiding this comment

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

I am not a huge fan of this name, I think of this more as changing the order of the pipeline rather than changing the space of the interpolation. I agree it does change the space, but the re-ordering (from resample -> norm -> colormap to norm -> colormap -> resample) is the key difference.

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 wed to the name, which was suggested by@anntzer, though I think its pretty good:interp_stage?interp_step?

@jklymak
Copy link
MemberAuthor

I would like a version of#18487 to go in with this.

I don't have any problem with that. Are you suggesting it should be part of this PR?

@tacaswelltacaswell dismissed theirstale reviewJuly 22, 2021 19:40

discussed on call

@jklymakjklymakforce-pushed theenh-image-postrgba-interpolate branch from3f07bff to548a2dfCompareJuly 24, 2021 04:53
@jklymak
Copy link
MemberAuthor

Name of the kwarg has been changed tointerpolation_stage.

Co-authored-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
@jklymakjklymakforce-pushed theenh-image-postrgba-interpolate branch from8793e03 toc460dbcCompareAugust 12, 2021 13:58
@QuLogicQuLogic merged commitbd42020 intomatplotlib:masterAug 13, 2021
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@anntzeranntzeranntzer left review comments

@tacaswelltacaswelltacaswell approved these changes

@QuLogicQuLogicQuLogic approved these changes

Assignees
No one assigned
Projects
None yet
Milestone
v3.5.0
4 participants
@jklymak@anntzer@tacaswell@QuLogic

[8]ページ先頭

©2009-2025 Movatter.jp