_tkinter.TclError: brak wyświetlanej nazwy i zmiennej środowiskowej $ DISPLAY

195

Na serwerze uruchamiam prosty skrypt Pythona:

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)

Próbuję użyć polecenia python example.pyna tym serwerze, na którym jest zainstalowany program Matplotlib 1.5.1. Błąd:

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

Co tu się dzieje?

użytkownik3654307
źródło
10
Czy uruchamiasz to przez ssh?
Padraic Cunningham
8
... bez -X?
Klaus D.
1
Jeśli uruchomisz go na notatniku Jupyter, uruchom to polecenie na notatniku%matplotlib inline
GoingMyWay
Jeśli łączysz się z maszyny Win do zdalnego serwera za pomocą szpachli, musisz zainstalować Xming, aby przekazać X11.
Serenity,

Odpowiedzi:

295

Matplotlib domyślnie wybiera backend Xwindows. Musisz ustawić matplotlib, aby nie korzystał z backendu Xwindows.

Dodaj ten kod na początku skryptu ( przed zaimportowaniem pyplot ) i spróbuj ponownie:

import matplotlib
matplotlib.use('Agg')

Lub dodaj do .config/matplotlib/matplotlibrclinii, backend: Aggaby użyć nieinteraktywnego zaplecza.

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

Lub po podłączeniu do serwera użyj ssh -X remoteMachinepolecenia, aby użyć Xwindows.

Również można spróbować wyświetlaczu wywozowych: export DISPLAY=mymachine.com:0.0.

Aby uzyskać więcej informacji: https://matplotlib.org/faq/howto_faq.html#matplotlib-in-a-web-application-server

Spokój
źródło
13
„ssh -X remoteMachine” rozwiązał mój problem. Dziękuję Ci!
user3654307
6
czym właściwie jest „Agg”?
CKM,
5
AGG to skrót od silnika geometrii Anty-ziarna.
Serenity,
5
matplotlib.use('Agg')działa dla mnie - działa wewnątrz obrazu Docker.
Mattia Paterna
Ten rozwiązał mój problem. Korzystam z maszyn wirtualnych Google w chmurze, mam nadzieję, że to pomaga ludziom mieć ten sam problem.
Demo
76

Możesz to rozwiązać, dodając te dwa wiersze na BARDZO początku skryptu .py.

import matplotlib
matplotlib.use('Agg')

PS: Błąd będzie nadal występował, jeśli te dwa wiersze nie zostaną dodane na samym początku kodu źródłowego.

Qihui
źródło
17
Powinno to być na samym początku kodu. To jest ważne.
łowca
działało to podczas pracy matplotlibna oknie dokowanym (bez dołączonego wyświetlacza), ale co to właściwie robi?
loretoparisi
Działa to dla mnie, gdy po prostu uruchamiam konsolę python na mojej maszynie wirtualnej, ale ten sam kod kończy się niepowodzeniem z dokładnie tym samym błędem na tej samej maszynie wirtualnej, gdy jest częścią działającej aplikacji.
rschwieb
Ale zmiana backendu z TkAgg na Agg w pliku konfiguracyjnym załatwiła sprawę.
rschwieb
42

Aby dodać odpowiedź, użyłem tego na początku potrzebnego skryptu. Dzięki temu działa płynnie w różnych środowiskach.

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

Ponieważ nie chciałem, aby zawsze był za pomocą 'Agg'backendu, tylko wtedy, gdy przejdzie na przykład przez Travis CI.

Sylhare
źródło
4
To rozwiązanie ma tę wartość dodaną, że jest najmniej inwazyjne przy dowolnej konfiguracji osobistej. Powinno być wyższe.
jaumebonet
11

Miałem ten sam problem, próbując uruchomić prostą aplikację tkinter zdalnie na Raspberry Pi. W moim przypadku chciałem wyświetlić GUI tkinter na ekranie pi, ale chcę móc go uruchomić przez SSH z mojego komputera. Nie korzystałem też z Matplotliba, więc to nie był przyczyną mojego problemu. Udało mi się rozwiązać problem, ustawiając zmienną środowiskową DISPLAY, jak sugeruje błąd w poleceniu:

export DISPLAY=:0.0

Dobre wyjaśnienie tego, co robi zmienna środowiskowa wyświetlania i dlaczego tak dziwna jest składnia, można znaleźć tutaj: /ubuntu/432255/what-is-display-environment-variable

ajgriese
źródło
18
Próbuję zapisać działki z Pythonem i matplotlib.pyplot działającymi na ssh ... Robiąc to, dostaję: _tkinter.TclError: nie można połączyć się w celu wyświetlenia „: 0.0”
mrk
2

Innym rozwiązaniem jest zainstalowanie Xvfb i wyeksportowanie do niego wyświetlacza. to znaczy:

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

Następnie

WYŚWIETLACZ $ eksport =: 8

$ ./example.py

Joseph
źródło
1

Spotkałem również ten problem podczas używania Xshell do łączenia się z serwerem Linux.

Po szukaniu metod znajduję Xming + Xshell, aby rozwiązać problem z wyświetlaniem obrazu za pomocą matplotlib.

Jeśli powyższe rozwiązania nie mogą rozwiązać Twojego problemu, po prostu spróbuj pobrać Xming pod warunkiem, że używasz Xshell. Następnie ustaw atrybut w Xshell, SSH-> tunel-> X11transfer-> wybierz X WYŚWIETL lokalny host: 0.0

Tryb
źródło
1

Aby zobaczyć obrazy, wykresy i wszystko wyświetlane w oknach na zdalnym komputerze, musisz się z nim połączyć w następujący sposób:

ssh -X user@hostname

W ten sposób włączasz dostęp do serwera X. X server to program w systemie X Window, który działa na lokalnych komputerach (tj. Komputerach używanych bezpośrednio przez użytkowników) i obsługuje cały dostęp do kart graficznych, ekranów wyświetlacza i urządzeń wejściowych (zazwyczaj klawiatury i myszy) na tych komputerach .

Więcej informacji tutaj .

tsveti_iko
źródło