Plotting to a File in Python

Have you ever wanted to save a Python/Matplotlib image directly to a file instead of having it displayed in an X11 window? I needed to do this for a project where I used qsub/PBS to submit jobs to a cluster and I wanted to plot some results for each run and save them to a file.  I couldn’t find a simple way to save plots to a file, and I kept getting this error in python:

no display name and no $DISPLAY environment variable

After much searching I found this solution from matplotlib’s faq page:

How To Generate Python/Matplotlib Images Without Having A Window Appear

The easiest way to do this is use a non-interactive backend such as Agg (for PNGs), PDF, SVG or PS. In your figure-generating script, just call the matplotlib.use() directive before importing pylab or pyplot:

import matplotlib
matplotlib.use(‘Agg’)
import matplotlib.pyplot as plt
plt.plot([1,2,3])
plt.savefig(‘myfig’)

You need to make sure to call matplotlib.use() before pyplot or you will get the following error:

UserWarning: This call to matplotlib.use() has no effect because the the backend has already been chosen;
matplotlib.use() must be called *before* pylab, matplotlib.pyplot,
or matplotlib.backends is imported for the first time.
if warn: warnings.warn(_use_error_msg)

I actually had an alias set up so that I call pyplot when I open up python, so I was getting this error until I changed that.  Now I don’t get the “$DISPLAY environment variable” error, because python knows to use the non-interactive backend Agg instead of trying to display to the screen.

8 comments… add one
  • TMB Sep 20, 2013 @ 16:15

    Very useful. Do you know if it’s possible to use a similar trick to get pyraf to not pop up windows? Especially when run while ssh-ed into a Mac…

  • Nathan Goldbaum Sep 20, 2013 @ 23:23

    You can slo use matplotlib’s object oriented API:

    from matplotlib.backends.backend_agg import FigureCanvasAgg
    from matplotlib.figure import Figure

    fig = Figure()
    canvas = FigureCanvasAgg(fig)
    ax = fig.add_subplot(111)
    ax.plot(arange(10))
    can.print_figure(‘test’)

    The object oriented API is very powerful – it allows the creation of arbitrarily positioned axes, subplots, and colorbars. It’s definitely more complicated than the pylab state machine or the pyplot interface, but if you really want to learn the nitty gritty of how to make sophisticated plots, it’s the way to go. The plotting interface of yt (which I am responsible for) depends heavily on matplotlib’s object oriented API.

  • Cristóbal Sifón Sep 22, 2013 @ 5:29

    I’ve always just done

    import pylab
    pylab.plot(x, y)
    pylab.savefig(‘figure.pdf’, format=’pdf’)

    without any problems (including latex fonts, etc). From savefig()’s help page:

    *format*:
    One of the file extensions supported by the active
    backend. Most backends support png, pdf, ps, eps and svg.

  • Lauren Weiss Sep 22, 2013 @ 20:26

    I use the ipython notebook environment (see http://ipython.org/ipython-doc/stable/interactive/notebook.html). To get figures directly in the notebook (instead of in a window), I use:
    %pylab inline
    at the command line. I also type the ‘%’ character. After running this command, subsequent figures appear directly in the notebook.

  • Magnus Persson Sep 23, 2013 @ 4:39

    You can also generate several figure in one Pdf file (NB: on separate pages, NOT subplots):

    http://matplotlib.org/examples/pylab_examples/multipage_pdf.html

    if you’re using the Pdf backend

  • Kaustubh Sep 26, 2013 @ 3:32

    Hi.

    A typical approach taken by me for making plots in Matplotlib goes something like this.

    import matplotlib.pyplot as plt
    fig1 = plt.figure(1)


    fig1.savefig(“Name.ext”, dpi=X)

    The .ext governs the output format. I use .png for quicklook and .pdf for those figures that I might need to make a part of an article / report. I found (when I started out) that the resolution was a little lower, so I often put manually a “dpi=150” or “dpi=200” clause in.

Leave a Reply

Your email address will not be published. Required fields are marked *