通过vscode的SSH隧道打开一个Matplotlib图

Posted

技术标签:

【中文标题】通过vscode的SSH隧道打开一个Matplotlib图【英文标题】:Open a Matplotlib figure through SSH tunnel of vscode 【发布时间】:2019-11-30 19:52:15 【问题描述】:

我正在设置一个远程工作站,以便在另一台包含 GPU 的计算机上从我的笔记本电脑上运行与机器学习相关的 Python 代码。

我使用 vscode 的 SSH 远程功能来远程运行和调试我的代码,我对界面非常满意。但是,我无法生成来自“matplotlib”库的数字。

我尝试修改一些 matlplotlib 选项,但没有成功:

import matplotlib
matplotlib.use('Agg')

按照说明:_tkinter.TclError: no display name and no $DISPLAY environment variable

简而言之,我的问题出现在以下示例代码中:

import numpy as np
from matplotlib import pyplot as plt 

x = np.linspace(0,1,101)
y = x ** 2

plt.close()
plt.figure()
plt.plot(x,y)
plt.show()
~/vscode$ cd /home/*/vscode ; env PYTHONIOENCODING=UTF-8 PYTHONUNBUFFERED=1 /usr/bin/python3 /home/*/.vscode-server/extensions/ms-python.python-2019.6.24221/pythonFiles/ptvsd_launcher.py --default --client --host localhost --port 39903 /home/*/vscode/test_plot.py 
Traceback (most recent call last):
  File "/home/*/.vscode-server/extensions/ms-python.python-2019.6.24221/pythonFiles/ptvsd_launcher.py", line 43, in <module>
    main(ptvsdArgs)
  File "/home/*/.vscode-server/extensions/ms-python.python-2019.6.24221/pythonFiles/lib/python/ptvsd/__main__.py", line 434, in main
    run()
  File "/home/*/.vscode-server/extensions/ms-python.python-2019.6.24221/pythonFiles/lib/python/ptvsd/__main__.py", line 312, in run_file
    runpy.run_path(target, run_name='__main__')
  File "/usr/lib/python3.6/runpy.py", line 263, in run_path
    pkg_name=pkg_name, script_name=fname)
  File "/usr/lib/python3.6/runpy.py", line 96, in _run_module_code
    mod_name, mod_spec, pkg_name, script_name)
  File "/usr/lib/python3.6/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/home/*/vscode/test_plot.py", line 8, in <module>
    plt.figure()
  File "/usr/lib/python3/dist-packages/matplotlib/pyplot.py", line 539, in figure
    **kwargs)
  File "/usr/lib/python3/dist-packages/matplotlib/backend_bases.py", line 171, in new_figure_manager
    return cls.new_figure_manager_given_figure(num, fig)
  File "/usr/lib/python3/dist-packages/matplotlib/backends/backend_tkagg.py", line 1049, in new_figure_manager_given_figure
    window = Tk.Tk(className="matplotlib")
  File "/usr/lib/python3.6/tkinter/__init__.py", line 2023, in __init__
    self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable

非常感谢你帮助我!

【问题讨论】:

链接帖子中的答案可能不够详细,所以this 可能有更多帮助。 @ImportanceOfBeingErnest 我设法从您的链接开始阅读了几个文档,我的问题似乎是 Windows 命令行中的 ssh -X 没有设置 $DISPLAY 变量。这很奇怪,因为它在 Putty 上运行良好,但不能在命令行中运行,我不明白为什么 【参考方案1】:

另一种方法是使用 Tensorboard,它现在可以通过 VS 代码中的扩展获得。您可以保存图像或绘图(以及其他类型的数据)并立即通过 VS 代码选项卡中的 Tensorboard 界面进行查看。我一直通过 ssh 使用它。但是,您确实需要 TensorFlow 或 Pytorch 才能做到这一点。

以下是 Pytorch 中 numpy.array 或 torch.Tensor 格式的图像示例。确保首先启动您的 Tensorboard 会话。

from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter('log_dir')    

# for some image "im"
writer.add_image('My image', im, 0)
write.close()

这是 matplotlib 图形的示例:

def examplePlot(data):
    fig = plt.figure()
    # do some plotting
    return fig

writer.add_figure('My plot', examplePlot(data), 0)
writer.close()

刷新您的 Tensorboard,您应该会立即看到它。

【讨论】:

【参考方案2】:

您还可以使用 pickle 将服务器计算机上的文件变哑,然后在本地计算机上重新绘制它们。您可以使用“SCP”将原始数据复制到本地计算机。有时它会有所帮助,因为您可以与情节进行实时互动。 我关注这两个链接:

    保存绘图数据 python matplotlib save graph as data file 使用 SCP 复制 Copying files from server to local computer using SSH

【讨论】:

【参考方案3】:

我通过在启用 X11 转发的情况下运行并行 Putty ssh 连接并在启动 python 脚本之前在 vscode 的终端中写入 export DISPLAY=localhost:10.0 来解决了这个问题。

但是,我有安全问题,我想知道为什么我必须手动执行这些命令才能使其正常工作...任何见解将不胜感激!

【讨论】:

注意:您应该使用export DISPLAY=localhost:10.0 而不是export $DISPLAY=loalhost:10.0。设置环境变量时,$ 不是必需的,应该避免使用。 更多详情请参考这个答案***.com/a/40006878/2999096 一些类似的建议:wiki.ros.org/docker/Tutorials/GUI【参考方案4】:

我发现以前的答案略有不同,效果很好。

将绘图保存为.png,而不是绘制它。

plt.savefig("dummy_name.png")

上一个答案然后建议通过scp 移动文件。相反,我建议使用 Visual Code 打开dummy_name.png,无需编写命令,每当您绘制其他内容时它会自动刷新图像。我从美国通过 SSH 测试到欧洲的服务器,图像在不到半秒的时间内刷新。

【讨论】:

【参考方案5】:

为了便于配置,您有 2 个选项:

    不显示绘图并通过 SSH 传输图片文件

此选项包括用

替换 plt.show()
plt.savefig('foo.png')
plt.savefig('foo.pdf')

More information 保存matplotlib 地块

之后,你可以用scp转移这个图

scp remote_username@10.10.0.2:/path/to/foo.png /local/directory
    使用 Jupyter Notebook

您可以轻松地在 Jupyter Notebook 中绘图。这里a tutorial 介绍了如何通过ssh 设置树莓派来为 Jupyter Notebook 创建远程服务器。

在 Jupyter Notebook 上,您需要在笔记本的第一行,在导入 matplotlib 之前添加,以便在单元格之后绘制图像。

%matplotlib inline

【讨论】:

非常感谢您的回复,写matplotlib.use('agg')plt.savefig('foo.png')可以避免错误并保存图片。这是一个很好的临时修复。对于我的使用,很遗憾我不能考虑使用笔记本。

以上是关于通过vscode的SSH隧道打开一个Matplotlib图的主要内容,如果未能解决你的问题,请参考以下文章

scp 通过 ssh 隧道打开

[视频教程]利用SSH隧道进行远程腾讯云服务器项目xdebug调试

通过 ssh 隧道进行 rsync [关闭]

Jupyter notebook SSH 隧道错误“无法打开签名数据库”

通过 SSH 隧道访问 SQL Server

pgAdmin3 通过 ssh 隧道备份