_tkinter.TclError: nenhum nome para exibição e nenhuma variável de ambiente $ DISPLAY

194

Estou executando um script python simples no servidor:

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)

Eu tento usar o comando python example.pyneste servidor que possui o matplotlib 1.5.1 instalado e falha com o erro:

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

O que esta acontecendo aqui?

user3654307
fonte
10
Você está executando isso sobre o ssh?
Padraic Cunningham
8
... sem -X?
Klaus D.
1
Se você executá-lo no notebook Jupyter, execute este comando no notebook%matplotlib inline
GoingMyWay 3/17/17
Se você se conectar da máquina Win ao servidor remoto via massa, precisará instalar o Xming para encaminhar o X11.
Serenity

Respostas:

291

O Matplotlib escolhe o back-end do Xwindows por padrão. Você precisa definir o matplotlib para não usar o back-end do Xwindows.

Adicione este código ao início do seu script ( antes de importar o pyplot ) e tente novamente:

import matplotlib
matplotlib.use('Agg')

Ou adicione à .config/matplotlib/matplotlibrclinha backend: Aggpara usar o back-end não interativo.

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

Ou, quando conectar ao servidor, use o ssh -X remoteMachinecomando para usar o Xwindows.

Além disso, você pode tentar exibição de exportação: export DISPLAY=mymachine.com:0.0.

Para obter mais informações: https://matplotlib.org/faq/howto_faq.html#matplotlib-in-a-web-application-server

Serenidade
fonte
13
'ssh -X remoteMachine' resolveu meu problema. Obrigado!
user3654307
6
o que é 'Agg' de fato?
CKM
5
AGG é a abreviação de mecanismo de geometria anti-grão.
Serenity
5
matplotlib.use('Agg')funciona para mim - executando dentro de uma imagem do Docker.
Mattia Paterna
Este resolveu meu problema. Estou executando nas VMs da nuvem do Google. Espero que isso ajude as pessoas a ter o mesmo problema.
Demo
76

Você pode resolvê-lo adicionando essas duas linhas no início MUITO do seu script .py.

import matplotlib
matplotlib.use('Agg')

PS: O erro ainda existe se essas duas linhas não forem adicionadas no início do código-fonte.

Qihui
fonte
17
Deve no início do código. Isso é importante.
hunter
isso funcionou ao executar matplotlibno docker (nenhum monitor anexado), mas o que ele realmente faz?
loretoparisi
Isso funciona para mim quando eu apenas executo o console python na minha vm, mas o mesmo código falha com o mesmo erro na mesma vm quando faz parte do aplicativo em execução.
Rschwieb
Mas alterar o back-end de TkAgg para Agg no arquivo de configuração fez o truque.
Rschwieb
41

Para adicionar a resposta, usei isso no início do script necessário. Por isso, funciona sem problemas em diferentes ambientes.

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

Porque eu não queria que fosse sempre usando o 'Agg'back - end, apenas quando passaria pelo Travis CI, por exemplo.

Sylhare
fonte
4
Essa solução tem o valor agregado de ser a menos invasiva, independentemente da configuração pessoal. Deve ser maior.
jaumebonet
11

Eu tive esse mesmo problema ao tentar executar um aplicativo tkinter simples remotamente em um Raspberry Pi. No meu caso, eu queria exibir a GUI do tkinter na tela pi, mas quero poder executá-lo por SSH na minha máquina host. Também não estava usando o matplotlib, pelo que não foi a causa do meu problema. Consegui resolver o problema definindo a variável de ambiente DISPLAY, conforme o erro sugere com o comando:

export DISPLAY=:0.0

Uma boa explicação sobre o que a variável de ambiente de exibição está fazendo e por que a sintaxe é tão estranha pode ser encontrada aqui: /ubuntu/432255/what-is-display-environment-variable

ajgriese
fonte
18
Eu estou tentando salvar lotes com python e matplotlib.pyplot correndo sobre ssh ... fazendo isso me deixa: _tkinter.TclError: não poderia ligar para exibição ": 0.0"
mrk
2

Outra solução é instalar o Xvfb e exportar sua exibição para ele. ou seja:

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

Então

$ export DISPLAY =: 8

$ ./example.py

Joseph
fonte
1

Também encontrei esse problema ao usar o Xshell para conectar o servidor Linux.

Após pesquisar os métodos, encontro o Xming + Xshell para resolver o problema de imshow de imagem com o matplotlib.

Se as soluções aprovadas não resolverem o seu problema, tente fazer o download do Xming sob a condição de usar o Xshell. Em seguida, defina o atributo em Xshell, SSH-> túnel-> X11transfer-> escolha X DISPLAY localhost: 0.0

Modo
fonte
1

Para ver imagens, plotagens e qualquer coisa exibida nas janelas da sua máquina remota, você precisa se conectar a ela assim:

ssh -X user@hostname

Dessa forma, você habilita o acesso ao servidor X. O servidor X é um programa no X Window System que roda em máquinas locais (ou seja, os computadores usados ​​diretamente pelos usuários) e administra todo o acesso às placas gráficas, telas de exibição e dispositivos de entrada (normalmente teclado e mouse) nesses computadores. .

Mais informações aqui .

tsveti_iko
fonte