Generating matplotlib graphs without a running X server [duplicate]
Asked Answered
F

2

195

Matplotlib seems to require the $DISPLAY environment variable which means a running X server.
Some web hosting services do not allow a running X server session.
Is there a way to generate graphs using matplotlib without a running X server?

[username@hostname ~]$ python2.6
Python 2.6.5 (r265:79063, Nov 23 2010, 02:02:03)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-48)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import matplotlib.pyplot as plt
>>> fig = plt.figure()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/username/lib/python2.6/matplotlib-1.0.1-py2.6-linux-i686.egg/matplotlib/pyplot.py", line 270, in figure
    **kwargs)
  File "/home/username/lib/python2.6/matplotlib-1.0.1-py2.6-linux-i686.egg/matplotlib/backends/backend_tkagg.py", line 80, in new_figure_manager
    window = Tk.Tk()
  File "/usr/local/lib/python2.6/lib-tk/Tkinter.py", line 1643, in __init__
    self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable
>>>
Force answered 8/2, 2011 at 9:29 Comment(0)
P
360

@Neil's answer is one (perfectly valid!) way of doing it, but you can also simply call matplotlib.use('Agg') before importing matplotlib.pyplot, and then continue as normal.

E.g.

import matplotlib as mpl
mpl.use('Agg')
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(range(10))
fig.savefig('temp.png')

You don't have to use the Agg backend, as well. The pdf, ps, svg, agg, cairo, and gdk backends can all be used without an X-server. However, only the Agg backend will be built by default (I think?), so there's a good chance that the other backends may not be enabled on your particular install.

Alternately, you can just set the backend parameter in your .matplotlibrc file to automatically have matplotlib.pyplot use the given renderer.

Petrina answered 8/2, 2011 at 17:0 Comment(8)
It seems insane to me that you have to import matplotlib twice. Is there an easier way?Criticism
For what it's worth, you're not actually importing matplotlib twice. You're importing matplotlib and then importing a sub-module that's not automatically imported. There are other ways, yes (for example, change your .maplotlibrc file), that that's the most straight-forward one.Petrina
what if I already imported pyplot ? can I still do it ?Drug
It stated "matplotlib.use() must be called before pylab, matplotlib.pyplot, or matplotlib.backends is imported for the first time."Philter
Most backends you mentioned (specifically: pdf, ps, svg, agg) are non-GUI backends, so they do not allow to show the plot directly from the code.Aileen
this is incredibly simple and worked perfectly on WSL. thanks a lot.Eberly
More specifically for the latter alternative, under Linux you just need to save backend: Agg in the file .config/matplotlib/matplotlibrcSandeesandeep
I can easily do mpl.use("Agg") after importing any of the mentioned dependent packages, it just needs to be before using them.Goran
T
22

You need to use the matplotlib API directly rather than going through the pylab interface. There's a good example here:

http://www.dalkescientific.com/writings/diary/archive/2005/04/23/matplotlib_without_gui.html

Tanbark answered 8/2, 2011 at 9:34 Comment(2)
I'm working with ssh and screen and besides the matplotlib.use('Agg')suggestion this was the only solution that worked. Thanks for the contributionDy
@user3085931: Nice to know my answer's still useful to someone 5 years after I wrote it! Thanks for letting me know.Tanbark

© 2022 - 2024 — McMap. All rights reserved.