macosx backend does not work with blitting #531

Closed
WeatherGod opened this Issue Oct 16, 2011 · 25 comments

Comments

Projects
None yet
@WeatherGod
Member

WeatherGod commented Oct 16, 2011

Looks like the FigureCanvasMac object for the macosx backend have a few missing functions that are critical for animations. First, it doesn't have copy_from_bbox(). Besides animations, this also impacts some widgets, particularly the lasso widget. The FigureCanvasMac object also doesn't have restore_region(), so any animations that have blit=True will fail.

@iveney

This comment has been minimized.

Show comment
Hide comment
@iveney

iveney Nov 8, 2011

+1 for this issue. Happened to encounter this issue and cannot find any workaround.

iveney commented Nov 8, 2011

+1 for this issue. Happened to encounter this issue and cannot find any workaround.

@mdehoon

This comment has been minimized.

Show comment
Hide comment
@mdehoon

mdehoon Mar 4, 2012

Contributor

Unfortunately it is not just an issue of adding the missing functions to the macosx backend. Currently the animations code in matplotlib sends drawing commands to the figures outside of the event loop. This will not work on Mac OS X because of how the operating system works. To fix this issue, the animations code in matplotlib will have to be redesigned.

Contributor

mdehoon commented Mar 4, 2012

Unfortunately it is not just an issue of adding the missing functions to the macosx backend. Currently the animations code in matplotlib sends drawing commands to the figures outside of the event loop. This will not work on Mac OS X because of how the operating system works. To fix this issue, the animations code in matplotlib will have to be redesigned.

@mdehoon

This comment has been minimized.

Show comment
Hide comment
@mdehoon

mdehoon Mar 26, 2013

Contributor

Anything we can do to move this issue forward? I'd be happy to add the required blitting functionality to the MacOSX backend, but we'd still need to rethink the animations code.

Contributor

mdehoon commented Mar 26, 2013

Anything we can do to move this issue forward? I'd be happy to add the required blitting functionality to the MacOSX backend, but we'd still need to rethink the animations code.

@mdboom

This comment has been minimized.

Show comment
Hide comment
@mdboom

mdboom Mar 26, 2013

Member

Can you elaborate on what the barrier for the Mac OSX backend is? The animation code is not making drawing commands outside of the event loop -- it's generally in a callback from a timer event that is triggered by the event loop. Are you saying that we can't draw outside of the draw callback? Does the Mac API have a way to render to an off-screen buffer, perhaps, and then blit that to the window on the next refresh event? Is it fundamentally a problem with the Quartz API or the way the backend is structured? Other backends that are built on top of this are able to do this, so there must be a way with a little creativity.

Member

mdboom commented Mar 26, 2013

Can you elaborate on what the barrier for the Mac OSX backend is? The animation code is not making drawing commands outside of the event loop -- it's generally in a callback from a timer event that is triggered by the event loop. Are you saying that we can't draw outside of the draw callback? Does the Mac API have a way to render to an off-screen buffer, perhaps, and then blit that to the window on the next refresh event? Is it fundamentally a problem with the Quartz API or the way the backend is structured? Other backends that are built on top of this are able to do this, so there must be a way with a little creativity.

@mdehoon

This comment has been minimized.

Show comment
Hide comment
@mdehoon

mdehoon Mar 26, 2013

Contributor

@mdboom Sorry I wasn't being clear. I meant to say that we cannot draw outside of the draw callback.
This is a fundamental feature of the Quartz API.
If the timer were to just invalidate the canvas, while letting the actual drawing be done by the draw callback, we should be able to get blitting to work.

Contributor

mdehoon commented Mar 26, 2013

@mdboom Sorry I wasn't being clear. I meant to say that we cannot draw outside of the draw callback.
This is a fundamental feature of the Quartz API.
If the timer were to just invalidate the canvas, while letting the actual drawing be done by the draw callback, we should be able to get blitting to work.

@mdboom

This comment has been minimized.

Show comment
Hide comment
@mdboom

mdboom Mar 26, 2013

Member

I see. It's not even possible to draw to an off-screen buffer outside of the draw callback? I'll look around and see what we might be able to refactor at our end, and also see what can be done with the various layered toolkits (Qt, Wx) as they might offer some clues for workarounds.

Member

mdboom commented Mar 26, 2013

I see. It's not even possible to draw to an off-screen buffer outside of the draw callback? I'll look around and see what we might be able to refactor at our end, and also see what can be done with the various layered toolkits (Qt, Wx) as they might offer some clues for workarounds.

@mdehoon

This comment has been minimized.

Show comment
Hide comment
@mdehoon

mdehoon Mar 26, 2013

Contributor

It may be possible to draw to an off-screen buffer outside of the draw callback, but it seems like a hack. Is it necessary for the Timer to issue the drawing commands, rather than relying on the draw callback?

Contributor

mdehoon commented Mar 26, 2013

It may be possible to draw to an off-screen buffer outside of the draw callback, but it seems like a hack. Is it necessary for the Timer to issue the drawing commands, rather than relying on the draw callback?

@mdboom

This comment has been minimized.

Show comment
Hide comment
@mdboom

mdboom Mar 26, 2013

Member

It seems like the easiest thing might be to have the macosx backend timer callback set a flag and invalidate the window. That should trigger a draw callback "as soon as possible", and if the flag is set, it can call all of the timer callbacks from there, which may, of course, issue drawing commands.

Member

mdboom commented Mar 26, 2013

It seems like the easiest thing might be to have the macosx backend timer callback set a flag and invalidate the window. That should trigger a draw callback "as soon as possible", and if the flag is set, it can call all of the timer callbacks from there, which may, of course, issue drawing commands.

@mdehoon

This comment has been minimized.

Show comment
Hide comment
@mdehoon

mdehoon Mar 27, 2013

Contributor

That would work if there is only one window, but if there are more then the timer would have to know which windows to invalidate. But anyway I will give it a try to see how it works out.

Contributor

mdehoon commented Mar 27, 2013

That would work if there is only one window, but if there are more then the timer would have to know which windows to invalidate. But anyway I will give it a try to see how it works out.

@mdboom

This comment has been minimized.

Show comment
Hide comment
@mdboom

mdboom Mar 27, 2013

Member

matplotlib timer events are created through the canvas object (in new_timer) so the macosx implementation of new_timer can associate the canvas with the timer callback, and from there get back to the window.

Member

mdboom commented Mar 27, 2013

matplotlib timer events are created through the canvas object (in new_timer) so the macosx implementation of new_timer can associate the canvas with the timer callback, and from there get back to the window.

@WeatherGod

This comment has been minimized.

Show comment
Hide comment
@WeatherGod

WeatherGod Mar 27, 2013

Member

There is a bit of a wrinkle... @dopplershift specifically designed the
animation class to allow for an animation to span multiple figures, I
believe. Plus, the timer is used for TimedAnimation. There are other
subclasses of animations that don't use a timer, IIRC.

Member

WeatherGod commented Mar 27, 2013

There is a bit of a wrinkle... @dopplershift specifically designed the
animation class to allow for an animation to span multiple figures, I
believe. Plus, the timer is used for TimedAnimation. There are other
subclasses of animations that don't use a timer, IIRC.

@mdehoon

This comment has been minimized.

Show comment
Hide comment
@mdehoon

mdehoon Mar 29, 2013

Contributor

I agree that an animation should be able to span multiple figures. But then it seems odd that new_timer is a method of the canvas object; I would expect new_timer to be a function by itself.
Looking at the different backends that implement new_timer, it turns out that the gtk, gtk3, macosx, and qt4 backends don't actually use the canvas (self) object passed in in the call to new_timer, but the tkagg and wx backends do. But even for tkagg and wx there seems to be a simple workaround to let the Timer be independent of a particular canvas. So I would suggest to change the definition of new_timer in matplotlib from a method associated with a canvas to a regular function.
Perhaps this is something for the mailing list?

Contributor

mdehoon commented Mar 29, 2013

I agree that an animation should be able to span multiple figures. But then it seems odd that new_timer is a method of the canvas object; I would expect new_timer to be a function by itself.
Looking at the different backends that implement new_timer, it turns out that the gtk, gtk3, macosx, and qt4 backends don't actually use the canvas (self) object passed in in the call to new_timer, but the tkagg and wx backends do. But even for tkagg and wx there seems to be a simple workaround to let the Timer be independent of a particular canvas. So I would suggest to change the definition of new_timer in matplotlib from a method associated with a canvas to a regular function.
Perhaps this is something for the mailing list?

@AlexandreAbraham AlexandreAbraham referenced this issue in nilearn/nilearn Sep 4, 2013

Closed

Kamitani example #101

@MattDMo

This comment has been minimized.

Show comment
Hide comment
@MattDMo

MattDMo Dec 22, 2013

Has there been any progress on this issue?

MattDMo commented Dec 22, 2013

Has there been any progress on this issue?

@mdehoon

This comment has been minimized.

Show comment
Hide comment
@mdehoon

mdehoon Dec 25, 2013

Contributor

There has been some progress, but nothing that is quite ready yet. This is a complicated issue that goes beyond the MacOSX backend and involves the design of the event loop in Python and the choice of the backend. So there is no simple bug fix involving the MacOSX backend only. This will take some time.

Contributor

mdehoon commented Dec 25, 2013

There has been some progress, but nothing that is quite ready yet. This is a complicated issue that goes beyond the MacOSX backend and involves the design of the event loop in Python and the choice of the backend. So there is no simple bug fix involving the MacOSX backend only. This will take some time.

@MattDMo

This comment has been minimized.

Show comment
Hide comment
@MattDMo

MattDMo Dec 26, 2013

@mdehoon thanks for the update. I've worked around this by specifying the Qt bindings in my ipython_config.py and matplotlibrc files, and that seems to be working for now.

Best of luck on solving this issue! I'd love to volunteer, but I know next to nothing about graphics internals - I'm definitely a Python guy :)

MattDMo commented Dec 26, 2013

@mdehoon thanks for the update. I've worked around this by specifying the Qt bindings in my ipython_config.py and matplotlibrc files, and that seems to be working for now.

Best of luck on solving this issue! I'd love to volunteer, but I know next to nothing about graphics internals - I'm definitely a Python guy :)

@asselinpaul

This comment has been minimized.

Show comment
Hide comment
@asselinpaul

asselinpaul Mar 9, 2014

@MattDMo Did you get it to work in the end?

@MattDMo Did you get it to work in the end?

@raw915

This comment has been minimized.

Show comment
Hide comment
@raw915

raw915 Apr 3, 2015

Here it is April 2015 and animation capability on mac OSX 10.10.2 is still not working. Any hope? Will this be fixed in v1.5.x?

raw915 commented Apr 3, 2015

Here it is April 2015 and animation capability on mac OSX 10.10.2 is still not working. Any hope? Will this be fixed in v1.5.x?

@mdehoon

This comment has been minimized.

Show comment
Hide comment
@mdehoon

mdehoon Apr 3, 2015

Contributor

@raw915 To solve this bug, the animations code will have to be redesigned. I did not write the animations code and I don't have time to fix it myself. If you can volunteer to work on this, or find somebody willing to take on this task, I'd be happy to explain what is wrong with the current code.

Contributor

mdehoon commented Apr 3, 2015

@raw915 To solve this bug, the animations code will have to be redesigned. I did not write the animations code and I don't have time to fix it myself. If you can volunteer to work on this, or find somebody willing to take on this task, I'd be happy to explain what is wrong with the current code.

@raw915

This comment has been minimized.

Show comment
Hide comment
@raw915

raw915 Apr 5, 2015

I used the suggestion from http://stackoverflow.com/users/2388218/matt at http://stackoverflow.com/questions/9401658/matplotlib-animating-a-scatter-plot to get the first example working on OSX 10.10.2. He inserted import matplotlib and matplotlib.use('TkAgg') at the top of the file. This may not work if Tk/Tcl is not installed. I have it through Anaconda https://store.continuum.io/cshop/anaconda/

raw915 commented Apr 5, 2015

I used the suggestion from http://stackoverflow.com/users/2388218/matt at http://stackoverflow.com/questions/9401658/matplotlib-animating-a-scatter-plot to get the first example working on OSX 10.10.2. He inserted import matplotlib and matplotlib.use('TkAgg') at the top of the file. This may not work if Tk/Tcl is not installed. I have it through Anaconda https://store.continuum.io/cshop/anaconda/

@zhanglongqi

This comment has been minimized.

Show comment
Hide comment
@zhanglongqi

zhanglongqi Jun 1, 2015

same issue +1
matplotlib 1.4.3
10.10.3 Yosemite
Darwin LQMacPro.local 14.3.0 Darwin Kernel Version 14.3.0: Mon Mar 23 11:59:05 PDT 2015; root:xnu-2782.20.48~5/RELEASE_X86_64 x86_64

same issue +1
matplotlib 1.4.3
10.10.3 Yosemite
Darwin LQMacPro.local 14.3.0 Darwin Kernel Version 14.3.0: Mon Mar 23 11:59:05 PDT 2015; root:xnu-2782.20.48~5/RELEASE_X86_64 x86_64

@mpacer

This comment has been minimized.

Show comment
Hide comment
@mpacer

mpacer Oct 19, 2015

Just wanted to chime in that I ran into this as well. It's kinda intimidating that the default simple example (http://matplotlib.org/1.4.1/examples/animation/simple_anim.html) doesn't work out of the box.

If I have time I'll try to look at the underlying animations code, but I'm no expert so I don't know if I'll actually be able to help.

mpacer commented Oct 19, 2015

Just wanted to chime in that I ran into this as well. It's kinda intimidating that the default simple example (http://matplotlib.org/1.4.1/examples/animation/simple_anim.html) doesn't work out of the box.

If I have time I'll try to look at the underlying animations code, but I'm no expert so I don't know if I'll actually be able to help.

@wking wking referenced this issue in swcarpentry/make-novice Nov 13, 2015

Closed

Changed isles.jpg to isles.pdf #27

@nils-werner

This comment has been minimized.

Show comment
Hide comment
@nils-werner

nils-werner Feb 19, 2016

Contributor

Just a fyi, I've refined my function definition a bit more:

export GLOBALPYTHON=$(which python)

function python {
    if [[ ! -z "$VIRTUAL_ENV" ]]; then
        #test if we are running python 2 or 3
        pyversion=`command python -V 2>&1 | cut -d ' '  -f2 | cut -d. -f1,2`
        PYTHONHOME=$VIRTUAL_ENV $GLOBALPYTHON$pyversion "$@"
    else
        $GLOBALPYTHON "$@"
    fi
}

put that in your .bashrc and using matplotlib in virtualenvs should "just work". In case that function breaks anything you can always force execution of the "plain virtualenv interpreter" by using command python.

Contributor

nils-werner commented Feb 19, 2016

Just a fyi, I've refined my function definition a bit more:

export GLOBALPYTHON=$(which python)

function python {
    if [[ ! -z "$VIRTUAL_ENV" ]]; then
        #test if we are running python 2 or 3
        pyversion=`command python -V 2>&1 | cut -d ' '  -f2 | cut -d. -f1,2`
        PYTHONHOME=$VIRTUAL_ENV $GLOBALPYTHON$pyversion "$@"
    else
        $GLOBALPYTHON "$@"
    fi
}

put that in your .bashrc and using matplotlib in virtualenvs should "just work". In case that function breaks anything you can always force execution of the "plain virtualenv interpreter" by using command python.

@efiring efiring modified the milestones: unassigned, 2.1 (next point release) Feb 19, 2016

@efiring

This comment has been minimized.

Show comment
Hide comment
@efiring

efiring Feb 19, 2016

Member

I changed this to "unassigned" because the solution to problems such as this will likely involve major changes such as an agg-based version of macosx. The immediate workaround is to use one of the existing backends other than macosx.

Member

efiring commented Feb 19, 2016

I changed this to "unassigned" because the solution to problems such as this will likely involve major changes such as an agg-based version of macosx. The immediate workaround is to use one of the existing backends other than macosx.

@mdboom

This comment has been minimized.

Show comment
Hide comment
@mdboom

mdboom Mar 21, 2016

Member

Fixed by #6178

Member

mdboom commented Mar 21, 2016

Fixed by #6178

@tacaswell tacaswell closed this Mar 28, 2016

@QuLogic QuLogic modified the milestones: 2.0 (style change major release), unassigned Mar 28, 2016

@rjboczar rjboczar referenced this issue in studywolf/control Apr 20, 2016

Closed

Simulation on OS X El Capitan not working #1

@ReaddyEddy

This comment has been minimized.

Show comment
Hide comment
@ReaddyEddy

ReaddyEddy Oct 12, 2016

As noted at https://mail.python.org/pipermail/pythonmac-sig/2012-September/023664.html use:

import matplotlib
matplotlib.use('TkAgg')

just before

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

This has worked for me with Tkinter installed using the ActiveState Tkinter installation on OSX 10.11.6, Python 2.71
The basic animation example is still a little noisy until blt=False in the line_ani code here:

line_ani = animation.FuncAnimation(fig1, update_line, 25, fargs=(data, l),
    interval=50, blit=False)

ReaddyEddy commented Oct 12, 2016

As noted at https://mail.python.org/pipermail/pythonmac-sig/2012-September/023664.html use:

import matplotlib
matplotlib.use('TkAgg')

just before

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

This has worked for me with Tkinter installed using the ActiveState Tkinter installation on OSX 10.11.6, Python 2.71
The basic animation example is still a little noisy until blt=False in the line_ani code here:

line_ani = animation.FuncAnimation(fig1, update_line, 25, fargs=(data, l),
    interval=50, blit=False)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment