【问题标题】:How to plot a chart in the terminal?如何在终端中绘制图表?
【发布时间】:2016-09-14 06:42:35
【问题描述】:

我正在研究 ML/Theano,最近发现了这个脚本:https://gist.github.com/notmatthancock/68d52af2e8cde7fbff1c9225b2790a7f,玩起来很酷。和所有 ML 研究人员一样,我最近升级到服务器,虽然它更强大,但也给我带来了问题。

脚本很长,但以这样的代码结尾:

def plot_stuff(inputs, outputs, losses, net_func, n_hidden):
fig,axes = plt.subplots(1,2,figsize=(12,6))

    axes[0].plot(np.arange(losses.shape[0])+1, losses)
    axes[0].set_xlabel('iteration')
    axes[0].set_ylabel('loss')
    axes[0].set_xscale('log')
    axes[0].set_yscale('log')

    x,y = np.mgrid[inputs[:,0].min():inputs[:,0].max():51j, inputs[:,1].min():inputs[:,1].max():51j]
    z = net_func( np.c_[x.flatten(), y.flatten()] ).reshape(x.shape)

    axes[1].contourf(x,y,z, cmap=plt.cm.RdBu, alpha=0.6)
    axes[1].plot(inputs[outputs==0,0], inputs[outputs==0,1], 'or') 
    axes[1].plot(inputs[outputs==1,0], inputs[outputs==1,1], 'sb') 
    axes[1].set_title('Percent missclassified: %0.2f%%' % (((net_func(inputs)>0.5) != outputs.astype(np.bool)).mean()*100))

    fig.suptitle('Shallow net with %d hidden units'%n_hidden)
    plt.show()

if __name__=='__main__':
    n_hidden = 40
    inputs, outputs = gen_data(n_samples_per_class=100)
    losses, net_func = train_neural_network(inputs=inputs, outputs=outputs, n_hidden=n_hidden, n_iters=int(2000), learning_rate=0.1)
    plot_stuff(inputs, outputs, losses, net_func, n_hidden)

生成此图表:

当我尝试在服务器上运行它时,服务器没有屏幕,只有命令行,我可以预见到这个错误:

fedora@ip-173-33-18-911:~/scripting/spiral$ python spiral.py
Iteration 2000 / 2000, Loss: 0.172083
Traceback (most recent call last):
  File "spiral.py", line 133, in <module>
    plot_stuff(inputs, outputs, losses, net_func, n_hidden)
  File "spiral.py", line 110, in plot_stuff
    fig,axes = plt.subplots(1,2,figsize=(12,6))
  File "/usr/lib/pymodules/python2.7/matplotlib/pyplot.py", line 1046, in subplots
    fig = figure(**fig_kw)
  File "/usr/lib/pymodules/python2.7/matplotlib/pyplot.py", line 423, in figure
    **kwargs)
  File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_tkagg.py", line 79, in new_figure_manager
    return new_figure_manager_given_figure(num, figure)
  File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_tkagg.py", line 87, in new_figure_manager_given_figure
    window = Tk.Tk()
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1767, in __init__
    self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable

有没有办法/方法/功能在命令行中显示图表和图形?

【问题讨论】:

  • 不,我不想保存图表,我想显示它,就在终端中。

标签: python python-2.7 matplotlib command-line theano


【解决方案1】:

termplotlib(我的一个小项目)在这里可能会派上用场。安装

pip install termplotlib

并生成类似的终端图

import termplotlib as tpl
import numpy as np

x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x) + x
fig = tpl.figure()
fig.plot(x, y, width=60, height=20)
fig.show()
  7 +---------------------------------------------------+
    |                                                   |
  6 |                                             **    |
    |                                           **      |
    |                                         **        |
  5 |                                       **          |
    |                                     ***           |
  4 |                                  ****             |
    |                              *****                |
  3 |             *****************                     |
    |          ****                                     |
  2 |       ***                                         |
    |     ***                                           |
    |   ***                                             |
  1 |  **                                               |
    |**                                                 |
  0 +---------------------------------------------------+
    0      1       2      3       4      5       6      7

【讨论】:

  • 很棒的包!
  • 正是我想要的:)
  • 很好,但它真的必须依赖 gnuplot 吗?安装它需要安装 Qt (363 MB) 和 icu4c (70 MB)。这种违背目的的:(
  • 无论如何要自定义 x/y 轴?或使其固定间隙。
  • 太棒了!该软件包是否有任何文档或示例?或者我如何在同一个图上绘制几条“线”?
【解决方案2】:

检查包plotext,它允许直接在终端上绘制数据。它非常直观,因为它的语法与 ma​​tplotlib 非常相似。

这是一个基本的例子:

import plotext as plt
y = plt.sin() # sinusoidal signal 
plt.scatter(y)
plt.title("Scatter Plot")
plt.show()

您还可以绘制条形图

甚至是图片

此处显示了绘制连续数据流的示例:

它可以安装

pip install plotext

或与:

pip install "plotext[image]" 

将 plotext 用于图像。

【讨论】:

  • 即使是最简单的图表也会显示奇怪的结果:x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] y = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 在没有 tty 时也会失败
  • 我又试了一次,它在这里工作。你能用下面的命令再试一次吗?将 plotext.plot 导入为 plx; x=列表(范围(11)); y=列表(范围(11)); plx.scatter(x,y); plx.show();
  • 您也可以先尝试使用以下命令卸载并重新安装 plotext: sudo -H pip uninstall plotext; sudo -H pip 安装 plotext。还记得使用 python3。告诉我,谢谢。
  • 我已经更新了这个包,它现在可以在 Linux、Windows cmd 和 Python IDLE 上运行。还有许多其他更改(例如背景颜色和保存绘图的可能性)。您可以在pypi.org/project/plotext 找到它。让我知道它是否适用于您的机器。谢谢。
  • 会很好,但是,轴坐标很烦人,没有人可以不断地重新计算,例如头顶的温度……
【解决方案3】:

您可能有兴趣查看 uniplot,这是我专门为 ML/数据科学管道编写的 Python 库。可能正是您正在寻找的。​​p>

得益于 Unicode,分辨率是其他终端绘图仪的 4 倍。

我还没有像你那样做高级图形,但是对于线条、散点图和直方图来说,它工作得很好。

【讨论】:

  • 不错的工具,可以满足我的需要。是否也可以根据高于或低于平均值/平均值的图来更改单个图的颜色?
  • @Louvre 今天color 选项是布尔值,所以不是直接的。您可以做的是在绘制之前将这些点分成高于和低于平均值,然后将它们绘制成两条不同的曲线。或者,如果您愿意,欢迎您to add an issue with a feature request in the uniplot GitHub repo
【解决方案4】:

你有几个选择:

  1. 导出为图像或 PDF。在这里找到的信息:http://matplotlib.org/faq/howto_faq.html 这里的关键信息如下:

    # do this before importing pylab or pyplot
    import matplotlib
    matplotlib.use('Agg')
    import matplotlib.pyplot as plt
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.plot([1,2,3])
    fig.savefig('test.png')
    
  2. 如果您的服务器支持 X11 转发(或者如果您可以启用/安装 X11 转发),您可以通过设置显示来通过 SSH 连接到服务器。从 linux 运行:

    DISPLAY=:0.0 ssh -Y <server ip>
    

    这会将您的机器设置为将任何显示输出从服务器转发到您的 PC。如果你运行的是 Windows,你可以使用 MobaXterm,这很容易,或者你自己配置一个 X11 客户端。如果我没记错的话,Mac 也同样简单。

【讨论】:

  • 终端无法显示图表?
  • 在终端显示图表是什么意思?我提到的第二种方式基本上就是这样做的。它应该完全按照您截屏的方式进行。
  • 在实际命令行中:像这样:imgur.com/mUn6Px1 或者这样:imgur.com/Skv87Ju
  • 我很确定在 matplotlib 中没有办法做到这一点。我也不知道你为什么要这样做。我假设您正在使用未连接到监视器的服务器进行操作,并且您正在通过 SSH 连接到服务器以访问它。如果是这样,那么我提到的第二种方法是从更强大的机器获取输出到屏幕的标准方法。
  • @SagnikGhosh 实际上是可能的(通过一个不寻常的要求),请查看我的answer
【解决方案5】:

可以在终端和终端模拟器中绘制光栅图像:

import matplotlib
matplotlib.use('module://matplotlib-sixel')
from pylab import *
plt.plot(sin(arange(100) / 10))
show()

此特定示例使用 matplotlib-sixel,这是一个使用 Xterm 模拟 Sixel 兼容终端和 ImageTrick 的库。类似的技术可以在 Linux 终端(通过Framebuffer)或模拟器(kittyiTerm2)中实现。 FOSS 社区在过去几年中提供了很好的解决方案(例如 libsixel)。

另一种选择是使用X11 forwarding 或使用基于Sixel 的打印机,例如lsix。但所有这些选项都将发生在 Python shell 本身之外。

当然,您最好在服务器中运行Jupyter Notebook,而不是在终端中硬塞图像。这可能不值得。

【讨论】:

  • 如果你得到 gui 错误使用:sudo apt-get install python3-tk
  • 这里是 kitty 的模块:matplotlib-backend-kitty
【解决方案6】:

我创建了一个名为 termplot 的小包,它可以从列表中创建一个垂直条形图。

pip install termplot

import termplot
termplot.plot([1,2,3,4,-5,5,-4,-1,0,-10,-4,-2,3,5,8,10,12,10,8,7,6,5,4,3,2,1])

【讨论】:

  • 请在此处添加尽可能多的信息。链接往往会随着时间的推移而消失,因此未来的读者可能不会从您的回答中受益。
【解决方案7】:

如果你想用图表弹出一个外部窗口,运行绘图,然后

&gt;&gt;&gt; matplotlib.pyplot.show(block=True)

这将在单独的窗口中弹出图表。

如果您在此调用之前多次调用plot(),它将弹出等量的带有相应图表的窗口。仅当您关闭所有弹出的图表窗口时,控制权才会返回给 Python。

我喜欢将它包装在一个小辅助函数中,如下所示:

def show():
   return matplotlib.pyplot.show(block=True) 

然后,只要我想查看任何尚未显示的地块,我只需致电 show()

【讨论】:

    【解决方案8】:

    在我看来,terminalplot,比@William234234 建议的包更完整,可能是一个很好的解决方案。

    示例用法:

    import terminalplot as tp
    import numpy as np
    from math import sin, pi
    
    x=np.linspace(0,2*pi,100);
    y=[sin(m)+m for m in x];
    tp.plot(list(x),y)
    

    【讨论】:

    • terminalplot 的最后一次提交是在 2016 年。asciiplotlib 似乎得到了更积极的维护
    • 我仍然给它一个 +1,因为它没有外部依赖项并且开箱即用;)
    猜你喜欢
    • 1970-01-01
    • 2016-06-06
    • 2011-05-28
    • 1970-01-01
    • 2013-12-16
    • 2018-03-17
    • 1970-01-01
    • 1970-01-01
    • 2016-11-23
    相关资源
    最近更新 更多