_tkinter.TclError: нет отображаемого имени и нет переменной среды $ DISPLAY

206

Я запускаю на сервере простой скрипт Python:

import matplotlib.pyplot as plt
import numpy as np

x = np.random.randn(60)
y = np.random.randn(60)

plt.scatter(x, y, s=20)

out_png = 'path/to/store/out_file.png'
plt.savefig(out_png, dpi=150)

Я пытаюсь использовать команду python example.pyна этом сервере, на котором установлен matplotlib 1.5.1, он не работает с ошибкой:

Traceback (most recent call last):
  File "example.py", line 7, in <module>
    plt.scatter(x, y, s=20)
  File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/pyplot.py", line 3241, in scatter
    ax = gca()
  File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/pyplot.py", line 928, in gca
    return gcf().gca(**kwargs)
  File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/pyplot.py", line 578, in gcf
    return figure()
  File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/pyplot.py", line 527, in figure
**kwargs)
  File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/backends/backend_tkagg.py", line 84, in new_figure_manager
    return new_figure_manager_given_figure(num, figure)
  File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/backends/backend_tkagg.py", line 92, in new_figure_manager_given_figure
    window = Tk.Tk()
  File "/usr/local/lib/python2.7/lib-tk/Tkinter.py", line 1810, in __init__
    self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable

Что здесь происходит?

Кеннет Као
источник
10
Вы запускаете это по ssh?
Padraic Cunningham
8
... без -X?
Klaus D.
2
Если вы запустите его на ноутбуке Jupyter, запустите эту команду на ноутбуке%matplotlib inline
GoingMyWay
1
Если вы подключаетесь с Win-машины к удаленному серверу через putty, вам нужно установить Xming для пересылки X11.
Serenity

Ответы:

306

Matplotlib по умолчанию выбирает бэкэнд Xwindows. Вам нужно настроить matplotlib, чтобы не использовать бэкэнд Xwindows.

Добавьте этот код в начало вашего скрипта ( перед импортом pyplot ) и повторите попытку:

import matplotlib
matplotlib.use('Agg')

Или добавьте в .config/matplotlib/matplotlibrcстроку, backend: Aggчтобы использовать неинтерактивный бэкэнд.

echo "backend: Agg" > ~/.config/matplotlib/matplotlibrc

Или при подключении к серверу используйте ssh -X remoteMachineкоманду для использования Xwindows.

Также вы можете попробовать экспорт дисплей: export DISPLAY=mymachine.com:0.0.

Для получения дополнительной информации: https://matplotlib.org/faq/howto_faq.html#matplotlib-in-a-web-application-server

Безмятежность
источник
14
'ssh -X remoteMachine' решил мою проблему. Спасибо!
Kenneth Kao
6
что на самом деле такое «Агг»?
CKM
6
AGG - это аббревиатура двигателя Anti-Grain geometry.
Serenity
5
matplotlib.use('Agg')у меня работает - работает внутри образа Docker.
Маттиа Патерна
1
если вы подключаетесь с компьютера Win к удаленному серверу через замазку, вам необходимо установить Xming для пересылки X11.
Serenity
79

Вы можете решить эту проблему, добавив эти две строки в ОЧЕНЬ начало вашего .py скрипта.

import matplotlib
matplotlib.use('Agg')

PS: ошибка все равно будет существовать, если эти две строчки не будут добавлены в самом начале исходного кода.

Цихуэй
источник
18
Это должно быть в самом начале кода. Это важно.
охотник
это сработало при работе matplotlibв докере (без прикрепленного дисплея), но что он делает на самом деле?
loretoparisi
Это работает для меня, когда я просто запускаю консоль python на своей виртуальной машине, но тот же самый код не работает с той же ошибкой на той же виртуальной машине, когда часть запущенного приложения.
rschwieb
Но изменение бэкэнда с TkAgg на Agg в файле конфигурации помогло.
rschwieb
45

Чтобы подытожить ответ, я использовал это в начале необходимого скрипта. Таким образом, он без проблем работает в разных средах.

import os
import matplotlib as mpl
if os.environ.get('DISPLAY','') == '':
    print('no display found. Using non-interactive Agg backend')
    mpl.use('Agg')
import matplotlib.pyplot as plt

Потому что я не хотел, чтобы он всегда использовал 'Agg'бэкэнд, только когда, например, он будет проходить через Travis CI.

Sylhare
источник
5
Это решение имеет добавленную стоимость, так как является наименее навязчивым с любой индивидуальной конфигурацией. Он должен быть выше.
jaumebonet
11

У меня была такая же проблема при попытке удаленно запустить простое приложение tkinter на Raspberry Pi. В моем случае я действительно хотел отображать графический интерфейс tkinter на дисплее pi, но я хочу иметь возможность выполнять его через SSH с моей хост-машины. Я также не использовал matplotlib, так что это не было причиной моей проблемы. Мне удалось решить проблему, установив переменную среды DISPLAY, как подсказывает ошибка, с помощью команды:

export DISPLAY=:0.0

Хорошее объяснение того, что делает переменная среды отображения и почему синтаксис такой странный, можно найти здесь: /ubuntu/432255/what-is-display-environment-variable

Ajgriese
источник
19
Я пытаюсь сохранить графики с помощью python и matplotlib.pyplot, запущенных через ssh ... делая это, я получаю: _tkinter.TclError: не удалось подключиться к отображению ": 0.0"
mrk
2

Другое решение - установить Xvfb и экспортировать в него свой дисплей. то есть:

disp=:8
screen=0
geom=640x480x24
exec Xvfb $disp -screen $screen $geom 2>/tmp/Xvfb.log &

затем

$ экспорт DISPLAY =: 8

$ ./example.py

Джозеф
источник
2

Чтобы увидеть изображения, графики и все, что отображается в окнах на вашем удаленном компьютере, вам необходимо подключиться к нему следующим образом:

ssh -X user@hostname

Таким образом вы разрешите доступ к X-серверу. X-сервер - это программа в системе X Window, которая работает на локальных машинах (т. Е. На компьютерах, используемых напрямую пользователями) и обрабатывает весь доступ к графическим картам, экранам дисплея и устройствам ввода (обычно клавиатуре и мыши) на этих компьютерах. .

Больше информации здесь .

tsveti_iko
источник
1

Я также столкнулся с этой проблемой при использовании Xshell для подключения к серверу Linux.

После поиска методов я нахожу Xming + Xshell для решения проблемы imshow изображения с помощью matplotlib.

Если указанные выше решения не могут решить вашу проблему, просто попробуйте загрузить Xming при условии, что вы используете Xshell. Затем установите атрибут в Xshell, SSH-> tunnel-> X11transfer-> выберите X DISPLAY localhost: 0.0

Режим
источник