Skip to content

Properly handle transparency for animations #5415

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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from

Conversation

cbreeden
Copy link

@cbreeden cbreeden commented Nov 6, 2015

This PR is a first attempt at fixing #5335. I have added a flatten kwarg for savefig in the agg backend that will allow animation.py remove all transparency before sending it to its respective animator. I don't think it would be a good idea to merge this just yet, but was looking for feedback before proceeding.

I guess I would still need to write a test. I'm not sure I handled the dimensions correctly for _write_png, animations look correct from write='imagemagick_file but that's definitely worth double checking.

@jenshnielsen
Copy link
Member

The fix for jpeg images in #5324 may be useful

img = self.flatten_rgba(img)
_png.write_png(img, filename_or_obj, self.figure.dpi)
else:
_png.write_png(renderer._renderer, filename_or_obj, self.figure.dpi)
Copy link
Member

Choose a reason for hiding this comment

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

Minor point, but I think I like the way you organized the code in print_raw better than here: i.e. set a local variable img to the render contents and then optionally flatten it, ultimately passing img into write_png on a single line.

Copy link
Author

Choose a reason for hiding this comment

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

@mdboom I really wanted to do that at first, but I will be honest when I say that I didn't understand what was going on here:

RendererAgg::RendererAgg(unsigned int width, unsigned int height, double dpi)
. I wasn't exactly sure if write_png needed something from that or not.

Copy link
Member

Choose a reason for hiding this comment

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

No -- it shouldn't matter. _write_png just converts whatever is passed in to a numpy array.

@mdboom
Copy link
Member

mdboom commented Nov 6, 2015

This looks good. It does mean we now have two ways to flatten images. This way is more general, though, as it doesn't rely on PIL. Can you modify print_jpeg to call out to the new flatten_rgba function?

Also, flatten_rgba should probably live in image.py since I anticipate it will be useful to other non-Agg backends in the future.

@WeatherGod
Copy link
Member

I wonder how much this overlaps with the image.combine_image feature? I
know it isn't the same, but it would be good to keep similar concepts as
compact as possible.

On Fri, Nov 6, 2015 at 7:52 AM, Michael Droettboom <notifications@github.com

wrote:

This looks good. It does mean we now have two ways to flatten images. This
way is more general, though, as it doesn't rely on PIL. Can you modify
print_jpeg to call out to the new flatten_rgba function?

Also, flatten_rgba should probably live in image.py since I anticipate it
will be useful to other non-Agg backends in the future.


Reply to this email directly or view it on GitHub
#5415 (comment)
.

@WeatherGod
Copy link
Member

Sorry, that is image.composite_image.

On Fri, Nov 6, 2015 at 9:41 AM, Benjamin Root ben.v.root@gmail.com wrote:

I wonder how much this overlaps with the image.combine_image feature? I
know it isn't the same, but it would be good to keep similar concepts as
compact as possible.

On Fri, Nov 6, 2015 at 7:52 AM, Michael Droettboom <
notifications@github.com> wrote:

This looks good. It does mean we now have two ways to flatten images.
This way is more general, though, as it doesn't rely on PIL. Can you modify
print_jpeg to call out to the new flatten_rgba function?

Also, flatten_rgba should probably live in image.py since I anticipate
it will be useful to other non-Agg backends in the future.


Reply to this email directly or view it on GitHub
#5415 (comment)
.

@mdboom
Copy link
Member

mdboom commented Nov 6, 2015

I wonder how much this overlaps with the image.combine_image feature? I know it isn't the same, but it would be good to keep similar concepts as compact as possible.

That's a good point. I think the image compositing stuff is bound to be slower than this because it's not on a solid color, but you're right there is some functionality overlap there.

@cbreeden
Copy link
Author

cbreeden commented Nov 6, 2015

Just for reference, I believe the core of the image.composite_image code lives here:

. I'm not sure if reusing that code would be beneficial or not. I will admit to not having known about the image.composite_image rcParam (I guess because this is new to 1.5?), and the description is given by:

Whether a vector graphics backend should composite several images
into a single image or not when saving. Useful when needing to edit the 
files further in Inkscape or other programs.

Let me just reiterate the issue that this PR is trying to correct. In some backends, transparency in the figures are enabled by default (nbAgg does this with and can be modified with nbagg.transparent). Matplotlib will then send images with an 8-bit alpha channel to their respective animators (sometimes using png as an intermediate file format). These animators are then forced to flatten the alpha channels and seem to get confused by either just truncating the alpha channel all together, or by picking some kind of threshold and setting the alpha to Full or None in the case of formats that handle boolean transparency (like gif).

I'm not sure it is worth having a configurable setting for turning on and off the flattening of RGBA before handing it off to animators. If clear_temp was accessible (I think I had to modify it from source) in the FileWrites then it might be beneficial to open the flatten keyword to the public in case someone really only wants each individual file for further processing.

@cbreeden
Copy link
Author

cbreeden commented Nov 6, 2015

whoops. Tried to --amend the 1759556 commit, but obviously it didn't work out the way I planned.

@tacaswell
Copy link
Member

@cbreeden We seem to go through the pep8 discussion with every new contributor 😉 . It really does help on the large code base to have a more-or-less uniform style.

Install an auto-linter in your editor and it becomes much less annoying.

@tacaswell
Copy link
Member

Can you also re-base to remove that merge commit?

@cbreeden cbreeden force-pushed the transparent-animations branch 2 times, most recently from c693df6 to 5bb8754 Compare November 7, 2015 14:14
# Flatten RGBA if used with fileformat that doesn't handle trnasparency
if kwargs.get('flatten', False):
w, h = int(renderer.width), int(renderer.height)
img = np.array(memoryview(img)).reshape((w, h, 4))
Copy link
Author

Choose a reason for hiding this comment

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

Can someone verify that this is the correct reshape? For png I needed to use (h, w, 4) to avoid scanning line offsets. The images look correct.

Copy link
Member

Choose a reason for hiding this comment

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

I think it should be (h, w, 4).

@cbreeden cbreeden force-pushed the transparent-animations branch 2 times, most recently from 5af94d2 to f0e2617 Compare November 7, 2015 15:06
@cbreeden
Copy link
Author

cbreeden commented Nov 7, 2015

Pending the Travis CI tests, I think I'm done here. Unless someone wants me to add documentation for the added flatten flag for savefig in the nbagg for png. It might also be worth looking into other backends. I had this comment from stackoverflow (http://stackoverflow.com/questions/33283274/pixelated-fonts-when-plot-is-saved-as-jpeg) when first running into this problem:

I seem to get the same results as you with nbagg, but with Agg my jpg looks much better. With the MacOSX backend both the jpg and the tiff have the pixellated fonts – tom

It might be related, but I don't have a Mac to test.

@cbreeden cbreeden force-pushed the transparent-animations branch from f0e2617 to f9140ec Compare November 7, 2015 15:31
@cbreeden
Copy link
Author

cbreeden commented Nov 7, 2015

Not sure why the build failed. I'm quite certain nothing I did should impact anything that test did. I tried running the code on my local python (3.4) and test_savefig_to_stringio worked fine. I think Travis CI just hasn't had its coffee yet.

@jenshnielsen
Copy link
Member

@cbreeden about Travis you are right these failures are annoying but intermittent and not related to your work

@tacaswell
Copy link
Member

@cbreeden This sadly needs a re-base now 😞

@cbreeden cbreeden force-pushed the transparent-animations branch from 05721b1 to b2c4560 Compare November 25, 2015 01:55
@cbreeden
Copy link
Author

@tacaswell no worries. I am quite new to git. In fact, I only picked it up so I could try to make this patch. Now I got the chance to handle my first rebase conflict; and I think I did it correctly, even 😥

@tacaswell tacaswell added this to the 2.0.1 (next bug fix release) milestone Jul 16, 2016
@tacaswell tacaswell self-assigned this Jul 16, 2016
@tacaswell
Copy link
Member

@cbreeden Sorry this fell off my radar.

Could you rebase this again?

@QuLogic QuLogic modified the milestones: 2.0.1 (next bug fix release), 2.0.2 (next bug fix release) May 3, 2017
@tacaswell tacaswell modified the milestones: 2.1 (next point release), 2.0.3 (next bug fix release) May 31, 2017
@tacaswell tacaswell modified the milestone: 2.1 (next point release) Aug 29, 2017
@jklymak
Copy link
Member

jklymak commented Aug 16, 2018

I'm not seeing the original issue in nbagg, and I know some work was done to fix the transparency issues recently. I'm going to close as abandoned but if there is important work in here, please feel free to re-open....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants