Skip to content

Loading…

Switching rendering backends #2851

Closed
amelio-vazquez-reina opened this Issue · 7 comments

4 participants

@amelio-vazquez-reina

Say I have a python script that I can call from IPython. I would like this script to

  • Build some plots for the sole propose of saving them to disk with fig.savefig(path_to_file), without showing them on screen.

  • Build some other plots that are displayed on the screen.

Is this currently possible within the same script?

I have tried with:

matplotlib.use('Agg')
# The following figures will not render on the screen
# but can be saved directly to disk

matplotlib.pyplot.switch_backend('QT4Agg')
# The following figures will render on the screen

matplotlib.pyplot.switch_backend('Agg')
# The following figures will not render on the screen
# but can be saved directly to disk

with no luck. Is there anything that I am doing wrong?


Also, if I have a Python script that starts with:

import matplotlib
matplotlib.use('Agg')
from pylab import *

and then I call the script from my IPython session, and then I change the rendering backend in the script:

import matplotlib
matplotlib.use('QT4Agg')
from pylab import *

and then I run it again from the same IPython session, the changes do not seem to take effect. However, if I restart IPython the backend specification is taken into consideration.

This is all with the latest stable versions of Python, matplotlib and IPython.

@minrk
IPython member

This sounds like a matplotlib question. It's best directed to matplotlib instead of IPython.

@amelio-vazquez-reina

Thanks @minrk I thought about that too. I am calling my Python scripts from IPython, and changing the rendering backend between runs, but these changes do not seem to take effect. However, if I restart IPython, the backend is read properly.

@minrk
IPython member

You can only call matplotlib.use once - it has no effect after the first call. %running your script does not reset that (it's ~the same as typing your script into IPython). You may only use switch_backend after that, which includes the first call in your script.

@drevicko

IPython 0.13.1

Ok, switching backends seems to work nicely if I don't use the %pylab inline magic (from pylab import * instead). If I want to switch to notebook's 'inline' mode, I use

switch_backend('module://IPython.zmq.pylab.backend_inline')

I can keep switching backends this way and drawing plots without problems.

If, however, I use the magic %pylab inline things start to get weird... A few examples:

  • I run %pylab inline first, draw a plot, then switch_backend('Qt4Agg') and draw another, the plot appears inline, and a 'Figure 1' popup appears but is grey for Qt4Agg (ubuntu's way of saying the process is busy) and quickly disappears for TkAgg. If I kill the popup and plot again with Qt4Agg (ie: without switching), the kernel dies.
  • I run %pylab inline first, then switch_backend('Qt4Agg') and plot something, the plot does not appear, and there is no error or other complaint - as if I were using the Agg backend, though matplotlib.backends.backend is 'Qt4Agg'. If at this point I switch_backend('module://IPython.zmq.pylab.backend_inline'), the grey 'Figure 1' appears (immediately on switching).

I could come up with other combinations and strange behaviours if it's useful. I get the feeling that this may already have been reported in another issue?? Or perhaps would be better in an issue of it's own.

Here's some versions of some perhaps relevant packages (all installed with pip):
matplotlib==1.2.0
numpy==1.7.0
scipy==0.11.0
ipython==0.13.1

IPython HEAD version

Now, in a virtualenv with everything the same (mkvirtualenv ipython-dev-2 --system-site-packages) I installed from the latest ipython source (commit 8051036). Here the above scenarios are a little different:

  • If I don't use %pylab inline, switching to switch_backend('module://IPython.kernel.zmq.pylab.backend_inline') does not produce any plots, but doesn't crash either. Othewise switching works as expected.
  • I run %pylab inline first, the behaviour is the same as 0.13.1

(note: the backend_inline module has moved to IPython.kernel.zmq.pylab.backend_inline)

@drevicko

It might be worth pointing out that I call show() after setting up the plot in all cases.

@ellisonbg
IPython member

@ribonoous do you consider this resolved? Can we close?

@ellisonbg ellisonbg closed this
@drevicko

I know you're trying to clean out the cobwebs, but seeing as I can get unresponsive popups and crash the kernel by killing them if I do %pylab inline followed by switch_backend and trying to plot again, I think this counts as a bug worth noting.

I imagine it's a pain to fix. We should at the least do something like hijacking switch_backend when %pylab inline is executed so that it tells the user that you can't.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.