为什么这解决了matplotlib的“无$DISPLAY environment”问题?

2024-06-26 02:04:57 发布

您现在位置:Python中文网/ 问答频道 /正文

在我的台式机上运行使用matplotlib库的代码时,我使用以下行没有问题:

import matplotlib.pyplot as plt

在代码的下面,这是我实际使用绘图功能的地方。

如果我在服务器中运行代码,但它只有在我在之前导入matplotlib并强制它使用Agg后端时才能工作。一、 例如,我必须在代码的开头添加以下行:

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

(请参见this answer中的解释)。否则代码将与TclError: no display name and no $DISPLAY environment variable一起崩溃(例如,请参见this question)。

问题是:我为什么要这么做?这个解决方案工作得很好,但我不知道为什么我不必在我的台式PC机上这样做,但当代码在服务器上运行时,我绝对必须这样做。


Tags: no代码import功能服务器绘图matplotlibuse
1条回答
网友
1楼 · 发布于 2024-06-26 02:04:57

X11遵循客户机/服务器模型,其中X服务器接受来自客户机应用程序(例如交互式matplotlib会话)的图形输出请求,并从键盘、鼠标等发送回用户输入。为了使此模型工作,客户机应用程序需要知道将其请求发送到哪个X服务器。这由$DISPLAY环境变量控制。在连接到远程X会话(例如通过SSH连接)的情况下,远程会话中的$DISPLAY变量需要指向本地X服务器。

$DISPLAY变量的结构如下:

hostname:displaynumber.screennumber

并不是所有部分都可能存在-对于本地会话,主机名通常被省略,如果只有一个屏幕,则屏幕号也被省略。在笔记本电脑上的本地终端会话中,my$DISPLAY如下所示:

alistair@laptop:~$ echo $DISPLAY
:0

如果远程服务器也支持X11,则可以在远程计算机上打开图形窗口,并使用X11 forwarding将它们显示在本地计算机上。对于SSH连接,可以通过传递-X(或-Y)标志来完成此操作。

例如:

alistair@laptop:~$ ssh -X alistair@workstation.address.co.uk
alistair@workstation:~$ echo $DISPLAY
localhost:10.0

当您打开连接时,远程SSH服务器应该适当地设置$DISPLAY变量。在这个特殊的例子中,localhost:10.0实际上是一个运行在远程机器上的“代理”X11服务器,它监听display 10并通过SSH连接将命令转发到本地X服务器(如果您对细节感兴趣的话,take a look at this)。

现在,您应该能够启动远程IPython会话,使用交互式后端导入matplotlib,并创建打印窗口,这些窗口随后将出现在本地计算机上。由于您的键盘/鼠标输入和显示输出现在通过加密的网络连接,绘图窗口的响应速度将低于您用于本地会话的响应速度。

另一个警告:如果打开了IPython会话并运行交互式matplotlib会话,则在不终止IPython进程的情况下无法关闭SSH连接。我有时还会在启动导入matplotlib的长时间运行的进程之前调用matplotlib.use("Agg"),这样就可以在不终止进程的情况下断开与远程服务器的连接。

相关问题 更多 >