Вопрос-Ответ

Generating a PNG with matplotlib when DISPLAY is undefined

Генерация PNG с помощью matplotlib, когда ОТОБРАЖЕНИЕ не определено

Я пытаюсь использовать networkx с Python. Когда я запускаю эту программу, она выдает эту ошибку. Чего-нибудь не хватает?

#!/usr/bin/env python

import networkx as nx
import matplotlib
import matplotlib.pyplot
import matplotlib.pyplot as plt

G=nx.Graph()
G.add_node(1)
G.add_nodes_from([2,3,4,5,6,7,8,9,10])
#nx.draw_graphviz(G)
#nx_write_dot(G, 'node.png')
nx.draw(G)
plt.savefig("/var/www/node.png")


Traceback (most recent call last):
File "graph.py", line 13, in <module>
nx.draw(G)
File "/usr/lib/pymodules/python2.5/networkx/drawing/nx_pylab.py", line 124, in draw
cf=pylab.gcf()
File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 276, in gcf
return figure()
File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 254, in figure
**kwargs)
File "/usr/lib/pymodules/python2.5/matplotlib/backends/backend_tkagg.py", line 90, in new_figure_manager
window = Tk.Tk()
File "/usr/lib/python2.5/lib-tk/Tkinter.py", line 1650, in __init__
self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable

Теперь я получаю другую ошибку:

#!/usr/bin/env python

import networkx as nx
import matplotlib
import matplotlib.pyplot
import matplotlib.pyplot as plt

matplotlib.use('Agg')

G=nx.Graph()
G.add_node(1)
G.add_nodes_from([2,3,4,5,6,7,8,9,10])
#nx.draw_graphviz(G)
#nx_write_dot(G, 'node.png')
nx.draw(G)
plt.savefig("/var/www/node.png")

/usr/lib/pymodules/python2.5/matplotlib/__init__.py:835: 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)
Traceback (most recent call last):
File "graph.py", line 15, in <module>
nx.draw(G)
File "/usr/lib/python2.5/site-packages/networkx-1.2.dev-py2.5.egg/networkx/drawing/nx_pylab.py", line 124, in draw
cf=pylab.gcf()
File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 276, in gcf
return figure()
File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 254, in figure
**kwargs)
File "/usr/lib/pymodules/python2.5/matplotlib/backends/backend_tkagg.py", line 90, in new_figure_manager
window = Tk.Tk()
File "/usr/lib/python2.5/lib-tk/Tkinter.py", line 1650, in __init__
self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable

Теперь я получаю другую ошибку:

#!/usr/bin/env python

import networkx as nx
import matplotlib
import matplotlib.pyplot
import matplotlib.pyplot as plt

matplotlib.use('Agg')

G=nx.Graph()
G.add_node(1)
G.add_nodes_from([2,3,4,5,6,7,8,9,10])
#nx.draw_graphviz(G)
#nx_write_dot(G, 'node.png')
nx.draw(G)
plt.savefig("/var/www/node.png")

/usr/lib/pymodules/python2.5/matplotlib/__init__.py:835: 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)
Traceback (most recent call last):
File "graph.py", line 15, in <module>
nx.draw(G)
File "/usr/lib/python2.5/site-packages/networkx-1.2.dev-py2.5.egg/networkx/drawing/nx_pylab.py", line 124, in draw
cf=pylab.gcf()
File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 276, in gcf
return figure()
File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 254, in figure
**kwargs)
File "/usr/lib/pymodules/python2.5/matplotlib/backends/backend_tkagg.py", line 90, in new_figure_manager
window = Tk.Tk()
File "/usr/lib/python2.5/lib-tk/Tkinter.py", line 1650, in __init__
self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable
Переведено автоматически
Ответ 1

Основная проблема заключается в том, что (в вашей системе) matplotlib по умолчанию выбирает серверную часть, использующую x. У меня только что была такая же проблема на одном из моих серверов. Решением для меня было добавить следующий код в место, которое читается перед любым другим импортом pylab / matplotlib / pyplot:

import matplotlib
# Force matplotlib to not use any Xwindows backend.
matplotlib.use('Agg')

Альтернативой является установка его в вашем .matplotlibrc

Ответ 2

Просто в качестве дополнения к ответу Reinout.

Постоянный способ решить проблему такого рода - отредактировать файл .matplotlibrc. Найдите его через

>>> import matplotlib
>>> matplotlib.matplotlib_fname()
# This is the file location in Ubuntu
'/etc/matplotlibrc'

Затем измените серверную часть в этом файле на backend : Agg. Вот и все.

Ответ 3

Простой ответ заключается в том, чтобы потратить немного времени на правильную подготовку вашей среды выполнения.

Первый метод, который вам нужно использовать для подготовки среды выполнения, - это использовать matplotlibrc файл, как мудро рекомендовал Крис К., установив

backend : Agg

в этом файле. Вы даже можете контролировать — без изменений кода — как и где matplotlib ищет и находит matplotlibrc файл.

Второй метод, который вам нужно подготовить для своей среды выполнения, - это использовать MPLBACKEND переменную окружения (и сообщить вашим пользователям, чтобы они ее использовали):

export MPLBACKEND="agg"
python <program_using_matplotlib.py>

Это удобно, потому что вам даже не нужно предоставлять другой файл на диске, чтобы это работало. Я использовал этот подход, например, при тестировании в режиме непрерывной интеграции и запуске на удаленных машинах, на которых нет дисплеев.

Жестко запрограммировать серверную часть matplotlib на "Agg" в коде Python - все равно что забивать квадратный колышек в круглое отверстие большим молотком, когда вместо этого вы могли бы просто сказать matplotlib, что это должно быть квадратное отверстие.

Ответ 4

Я получил ошибку при использовании matplotlib через Spark. matplotlib.use('Agg') У меня не работает. В конце концов, у меня работает следующий код. Подробнее здесь

import matplotlib.pyplot as plt.
plt.switch_backend('agg')
2024-03-10 15:13 python matplotlib