Skip to content
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

Animated GIF plots should repaint bgcolor after each frame #11313

Closed
kini opened this issue May 8, 2011 · 28 comments
Closed

Animated GIF plots should repaint bgcolor after each frame #11313

kini opened this issue May 8, 2011 · 28 comments

Comments

@kini
Copy link
Contributor

kini commented May 8, 2011

As title. ImageMagick should be called with -dispose Background, because when you create an animation, Sage first creates a bunch of frames, then uses ImageMagick to make an animated GIF out of them. If the frames are not all the same size, then ImageMagick determines the minimum size for the final GIF in which it is possible to accommodate all the frames. The default behavior is to simply draw frame n over frame n-1 without erasing frame n-1. When frame n's image is smaller than frame n-1's image, however, you get garbage in frame n outside the borders of the original image used to create frame n.

Before:

After:

The above image was produced by the following code:

t = var('t')

def frame(theta):
    r = 2
    x = r*(t - sin(t))
    y = r*(1 - cos(t))

    plot = parametric_plot((x, y), (t,0,theta), rgbcolor=hue(0.6))
    krug = circle((2*theta, r), r)
    tocka = point((r*(theta - sin(theta)), r*(1 - cos(theta))), pointsize=30, color='red')
    return plot+krug+tocka;

animacija = animate([frame(x) for x in srange(0.1, 5*pi, 0.1)])

animacija.show(delay=10, iterations=0)

(Thanks to user v-v on Freenode.)


Apply attachment: trac_11313-imagemagick-options.patch to $SAGE_ROOT/devel/sage.

Component: graphics

Keywords: plot, animate, imagemagick

Author: Keshav Kini

Reviewer: John Palmieri

Merged: sage-5.0.beta1

Issue created by migration from https://trac.sagemath.org/ticket/11313

@kini kini added this to the sage-4.8 milestone May 8, 2011
@kini
Copy link
Contributor Author

kini commented May 8, 2011

Author: Keshav Kini

@kini
Copy link
Contributor Author

kini commented May 8, 2011

comment:1

Any ideas on how to doctest this? Doesn't really seem possible, on first glance anyway...

@kini

This comment has been minimized.

@kcrisman
Copy link
Member

comment:3

Does this slow anything down? animate is already on the slow side...

@kini
Copy link
Contributor Author

kini commented Jun 23, 2011

comment:4

This is a defect, not an enhancement, ticket, so I don't consider potential slowdown to be a problem with the patch. That aside, ImageMagick is written in C and is pretty fast. If animate is slow it's probably because Sage needs to create every frame separately before using ImageMagick to put them together. I doubt this patch introduces any slowdowns.

To elaborate on what makes this a defect: when you create an animation, Sage first creates a bunch of frames, then uses ImageMagick to make an animated GIF out of them. If the frames are not all the same size, then ImageMagick determines the minimum size for the final GIF in which it is possible to accommodate all the frames. The default behavior is to simply draw frame n over frame n-1 without erasing frame n-1. When frame n's image is smaller than frame n-1's image, however, you get garbage in frame 'n' outside the borders of the original image used to create frame 'n'.

@kini

This comment has been minimized.

@kini

This comment has been minimized.

@kini
Copy link
Contributor Author

kini commented Jun 23, 2011

comment:7

Sorry about the spam...

@kini

This comment has been minimized.

@jhpalmieri
Copy link
Member

comment:8

Can you provide code which illustrates the problem (before the patch) and its solution (after)?

@kini
Copy link
Contributor Author

kini commented Jul 24, 2011

comment:9

Hmm, I've lost track of the code which demonstrated this problem (the code was originally posted on a pastebin by a user on IRC in May). While I wait for a response to the message I sent that user, here's an image showing what animate() currently does with that code:

@kini
Copy link
Contributor Author

kini commented Jul 25, 2011

comment:10

Here we are:

t = var('t')

def frame(theta):
    r = 2
    x = r*(t - sin(t))
    y = r*(1 - cos(t))

    plot = parametric_plot((x, y), (t,0,theta), rgbcolor=hue(0.6))
    krug = circle((2*theta, r), r)
    tocka = point((r*(theta - sin(theta)), r*(1 - cos(theta))), pointsize=30, color='red')
    return plot+krug+tocka;

animacija = animate([frame(x) for x in srange(0.1, 5*pi, 0.1)])

animacija.show(delay=10, iterations=0)

Credit to user v-v on freenode. This produces the image shown above on Sage 4.7 (for example on sagenb.org). My local alpha2 (old, I know...) does something kind of alarming... I'll test with the latest dev version once I get it built.

@jhpalmieri
Copy link
Member

comment:11

Minor point: the patch doesn't apply cleanly to Sage 4.7.1.rc0, but that's easy to fix. More importantly, with Safari 5.1 on a Mac, the area which is no longer part of the picture displays as a black box. On Firefox or Chrome, it's white (or maybe the default background color?), but it looks bad on Safari. I don't know if this is a bug in how Safari displays animated gifs or if we can avoid it somehow.

@kini
Copy link
Contributor Author

kini commented Aug 4, 2011

comment:12

The "something kind of alarming" appears to be caused by #11170 - the GIF blows up in filesize by a factor of 50 and the aspect ratio is destroyed. I'll cross-post to that ticket...

As for Safari, no idea. I'll look into it.

@kini
Copy link
Contributor Author

kini commented Nov 18, 2011

comment:13

I'm going to rebase this on #11650 / 4.8.alpha1 .

Regarding Safari's behavior, I found this, which links to some internal Apple bug tracker which I cannot access. Can we assume this is Safari's problem?

@kini
Copy link
Contributor Author

kini commented Jan 13, 2012

comment:14

Now that #11650 is in, here's a rebase on sage 4.8.alpha6.

How the above GIF looks after the patch:

On the imgur page you can see how the GIF's transparency and non-white backgrounds interact. Compare with the old behavior.

@kini
Copy link
Contributor Author

kini commented Jan 13, 2012

comment:15

Whoops, the "before" image is a bit different now in sage 4.8.alpha6 than it was when I posted [comment:9]. See the description for the updated GIF.

@kini

This comment has been minimized.

@jhpalmieri
Copy link
Member

comment:16

This looks good to me. By the way, where is this syntax for defining strings

s = ('abc' 'def')

documented?

@jhpalmieri
Copy link
Member

Reviewer: John Palmieri

@kini
Copy link
Contributor Author

kini commented Jan 13, 2012

comment:17

Here is the relevant section of the Python docs. Actually,

s = 'abc' 'def'

works too, but the parentheses in the patch force a line continuation.

Thanks for the review!

@jdemeyer
Copy link

apply to $SAGE_ROOT/devel/sage

@jdemeyer
Copy link

comment:18

Attachment: trac_11313-imagemagick-options.patch.gz

Changed commit message.

@kini
Copy link
Contributor Author

kini commented Jan 17, 2012

comment:19

Wait, what? So now we're not putting the trac ticket number in the commit message? Hmm, I didn't realize that. Thanks for the heads up.

@jdemeyer
Copy link

comment:20

Replying to @kini:

Wait, what? So now we're not putting the trac ticket number in the commit message? Hmm, I didn't realize that. Thanks for the heads up.

Funny how in the beginning when I was release manager, I had to convince everybody to put ticket numbers in the commit message and quite a few didn't do it (or worse: put the wrong ticket number). Since sage-4.7, the ticket numbers are added automatically but it seems that now, more people than before are actually adding the ticket number.

@kini
Copy link
Contributor Author

kini commented Jan 17, 2012

comment:21

Of course, the best way would be to have people make commits to the tree, and then close the ticket with a reference to the commit, rather than making the commit upon release, when the ticket has been closed already. But for that I guess we need to implement the github-based sage --push/pull workflow Robert Bradshaw suggested, or something similar.

By the way, why not just check whether the ticket number is already in the commit message and not add it again if so?

@jdemeyer
Copy link

comment:22

Replying to @kini:

By the way, why not just check whether the ticket number is already in the commit message and not add it again if so?

When this was discussed on sage-devel (please don't ask me to find the thread again), somebody suggested that having a uniform format

Trac #54321: change foo to bar

could be useful for scripts. I would find a version of "hg blame" with ticket numbers quite interesting. If somebody would implement this, then the standard-format ticket numbers would certainly be useful.

@jdemeyer
Copy link

Merged: sage-5.0.beta1

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

No branches or pull requests

6 participants