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

FIX: make_image should not modify original array#29892

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
dstansby merged 1 commit intomatplotlib:mainfromrcomer:array-alpha
Apr 13, 2025

Conversation

rcomer
Copy link
Member

@rcomerrcomer commentedApr 9, 2025
edited
Loading

PR summary

Fixes#29891. The problem is that we divide the RGB part of the array by its alpha on each draw. The simple fix is to make a copy but I assume for efficiency we should only copy when necessary.

  • If we didn't start with RGBA, we already made a copy
  • If alpha was an array, we already made a copy
  • If the alpha channel is one everywhere, it does not matter

PR checklist

@rcomerrcomer added Release criticalFor bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions. PR: bugfixPull requests that fix identified bugs labelsApr 9, 2025
@jklymakjklymak requested a review fromanntzerApril 9, 2025 21:49
@@ -281,6 +281,17 @@ def test_imshow_alpha(fig_test, fig_ref):
ax3.imshow(rgbau)


def test_imshow_rgba_multi_draw():
Copy link
Member

Choose a reason for hiding this comment

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

You do this conditionally - may be helpful to test the conditions where you arenot doing the copy to demonstrate that they work fine on redraw

rcomer reacted with thumbs up emoji
@dstansby
Copy link
Member

dstansby commentedApr 10, 2025
edited
Loading

This adds another copy of the input image, which for medium to large images is not neglegible. Running the script below I get a peak memory usage of ~450 MB, but with this PR I get a peak usage of ~580MB (as expected the difference is ~one copy of the input image, which is ~120MB).The performance of resizing the window is also much worse, I presume because it's making a copy of the array every time the window size changes. < ignore this

I guess the other way to fix this is to multiply in-place, then divide in place after the resample. That would avoid the extra memory, but if it's constantly happening during a window resize I could imagine it has performace implications, and perhaps floating point errors could accumulate pretty fast with all the multiplications and divisions?

I can't think of another option to solve this without going back to applying alpha in resampled space (ie undoing#29776). Perhaps@anntzer has some thoughts as the original PR author?

importmatplotlib.pyplotaspltimportnumpyasnpnp.random.seed(42)rgba=np.random.random((2000,2000,4))fig,ax=plt.subplots()ax.imshow(rgba)fig.canvas.draw()

@rcomerrcomer added this to thev3.11.0 milestoneApr 10, 2025
@anntzer
Copy link
Contributor

The fix looks correct to me, sorry for introducing the bug.

re: performance:

  • It's clear to me that unpremultiplied filtering is wrong because agg explicitly clips the RGB values to no more than alpha after the premultiplication (Filter images in premultiplied alpha mode. #29776 (comment)), which only makes sense in premultiplied space; if we really don't want to premultiply we should then at least remove that clipping.
  • In an initial version I wrote the premultiplication by upcasting uint8 just to uint16e52c150 for int input, which should save a lot of memory, but following review (Filter images in premultiplied alpha mode. #29776 (review)) I moved everything to float for simplicity. I could bring back these narrower types to save memory.
  • It may be possible to save memory by merging the premultiplication step into the C++ filtering code; it's probably doable but a quick check suggests it's still a bit of work.

Thoughts?

@rcomer
Copy link
MemberAuthor

I guess we can add "input was uint8" to my list of reasons not to copy, since we already cast to float.

@jklymak
Copy link
Member

In my opinion#29776 should remain. The previous results were incorrect, and I think having correct results should trump efficiency.

We copy the user data in_normalize_image_array and set that toself._A. It seems to me the proper thing to do itrecopy theuser data, not make another version ofourself._A. I'm not sure how inefficient that is, but doing that at the correct level would make it so we only ever have one extra copy.

dstansby reacted with thumbs up emoji

@dstansby
Copy link
Member

👍 to doing the right thing at the expense of memory - at a glance I think there might be ways to save creating extra memory for the alpha channel, but for simplicity I think worth getting this in as is and then optimizing (if possible) later.

rcomer and timhoffm reacted with thumbs up emoji

The problem is that we divide the RGB part of the array by its alphaon each draw.  The simple fix is to make a copy but I assume forefficiency we should only copy when necessary.* If we didn't start with float RGBA, we already made a copy* If alpha was an array, we already made a copy* If the alpha channel is one everywhere, it does not matter
@QuLogic
Copy link
Member

It may be possible to save memory by merging the premultiplication step into the C++ filtering code; it's probably doable but a quick check suggests it's still a bit of work.

Either#29453, or some not-yet-pushed version of it, does attempt to do some of this deduplication. I don't have time to look at that again until I finish the text stuff, but it may yet be a possibility to reduce the memory footprint, which can be done after this PR at least fixes the bug.

@jklymak
Copy link
Member

That's fine as long as we remember to remove the extra copy this introduces.

@QuLogic
Copy link
Member

I thought#29776 removed a copy (from_rgb_to_rgba), so we should be net even with this PR? At least for now.

@jklymak
Copy link
Member

Sure? But we still will want to remove this copy?

@tacaswell
Copy link
Member

I just want to clarify the issue is that we are modifying our copy of the array not the object the user passed to us.

@dstansby
Copy link
Member

I just want to clarify the issue is that we are modifying our copy of the array not the object the user passed to us.

Yes, this is correct

@dstansbydstansby merged commit349aa96 intomatplotlib:mainApr 13, 2025
41 checks passed
@rcomerrcomer deleted the array-alpha branchApril 13, 2025 10:12
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@jklymakjklymakjklymak left review comments

@tacaswelltacaswelltacaswell approved these changes

@dstansbydstansbydstansby approved these changes

@anntzeranntzerAwaiting requested review from anntzer

Assignees
No one assigned
Labels
PR: bugfixPull requests that fix identified bugsRelease criticalFor bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.topic: images
Projects
None yet
Milestone
v3.11.0
Development

Successfully merging this pull request may close these issues.

[Bug]: image alpha re-applied each draw?
6 participants
@rcomer@dstansby@anntzer@jklymak@QuLogic@tacaswell

[8]ページ先頭

©2009-2025 Movatter.jp