Gab*_*iel 9 python x11 matplotlib
运行matplotlib
在我的台式PC 中使用该库的代码时,使用该行没有问题:
import matplotlib.pyplot as plt
Run Code Online (Sandbox Code Playgroud)
远在代码中,这是我实际使用绘图功能的地方.
如果我在服务器中运行代码,虽然它只在我matplotlib
之前导入时才有效,并强制它使用Agg
后端.即,我必须在代码的开头添加以下行:
import matplotlib
# Force matplotlib to not use any Xwindows backend.
matplotlib.use('Agg')
Run Code Online (Sandbox Code Playgroud)
(参见这个解释的答案).否则代码将崩溃TclError: no display name and no $DISPLAY environment variable
(例如,请参阅此问题).
问题是:为什么我需要这样做?该解决方案运行良好,但我不知道为什么我不必在我的台式机上执行此操作,但我绝对必须在服务器中运行代码.
ali*_*i_m 10
X11遵循客户端/服务器模型,其中X服务器接受来自客户端应用程序的图形输出请求(例如交互式matplotlib会话),并从键盘,鼠标等发回用户输入.为了使该模型起作用,客户端应用程序需要知道向哪个X服务器发送请求.这由$DISPLAY
环境变量控制.如果要连接到远程X会话(例如通过SSH连接),则$DISPLAY
远程会话中的变量需要指向本地X服务器.
该$DISPLAY
变量的结构是这样的:
hostname:displaynumber.screennumber
Run Code Online (Sandbox Code Playgroud)
并非所有部件都可能存在 - 主机名通常在本地会话中省略,如果只有一个屏幕,也会省略屏幕编号.在笔记本电脑上的本地终端会话中,我$DISPLAY
看起来像这样:
alistair@laptop:~$ echo $DISPLAY
:0
Run Code Online (Sandbox Code Playgroud)
如果远程服务器也支持X11,则可以在远程计算机上打开图形窗口,并使用X11转发将它们显示在本地计算机上.对于SSH连接,您可以通过传递-X
(或-Y
)标志来完成此操作.
例如:
alistair@laptop:~$ ssh -X alistair@workstation.address.co.uk
alistair@workstation:~$ echo $DISPLAY
localhost:10.0
Run Code Online (Sandbox Code Playgroud)
$DISPLAY
当您打开连接时,远程SSH服务器应该适当地设置变量.在这种特殊情况下,localhost:10.0
实际上是在远程计算机上运行的"代理"X11服务器,它监听显示器10并通过SSH连接将命令中继到本地X服务器(如果您对详细信息感兴趣,请查看此信息) .
现在,您应该能够启动远程IPython会话,使用交互式后端导入matplotlib,并创建将在本地计算机上显示的绘图窗口.由于您的键盘/鼠标输入和显示输出现在通过加密的网络连接,因此绘图窗口的响应速度将低于您习惯的本地会话.
另一个警告:如果你打开一个运行交互式matplotlib会话的IPython会话,就不可能在不杀死IPython进程的情况下关闭SSH连接.matplotlib.use("Agg")
在开始长时间运行的进程matplotlib之前,我有时也会打电话- 这样我就可以断开与远程服务器的连接而不会终止进程.