Plotting to a File in Python

by Jess K on September 20, 2013

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
import matplotlib.pyplot as plt

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… read them below or add one }

1 TMB September 20, 2013 at 4:15 pm

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…


2 Nathan Goldbaum September 20, 2013 at 11:23 pm

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)

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.


3 Cristóbal Sifón September 22, 2013 at 5:29 am

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:

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


4 Lauren Weiss September 22, 2013 at 8:26 pm

I use the ipython notebook environment (see 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.


5 Nathan Goldbaum September 23, 2013 at 5:53 pm

True! This is how I do most of my plotting these days.

You can roll your own pretty display functions too:

6 Magnus Persson September 23, 2013 at 4:39 am

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

if you’re using the Pdf backend


7 Ian Crossfield September 29, 2013 at 1:59 pm

Here’s the function I used for printing multiple figures into a multi-page PDF file (using texexec or gv):

8 Kaustubh September 26, 2013 at 3:32 am


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 Comment

Previous post:

Next post: