Python 如何在终端中绘制图表?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37288421/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to plot a chart in the terminal?
提问by Rich
I'm researching ML/Theano, and recently came across this script: https://gist.github.com/notmatthancock/68d52af2e8cde7fbff1c9225b2790a7fwhich was cool to play with. And like all ML researchers, I recently upgraded to a server, and while it's more powerful, it also presented me with a problem.
我正在研究 ML/Theano,最近遇到了这个脚本:https://gist.github.com/notmatthancock/68d52af2e8cde7fbff1c9225b2790a7f, 玩起来很酷。和所有 ML 研究人员一样,我最近升级到了服务器,虽然它更强大,但也给我带来了一个问题。
The script is very long, but it ends with this code:
脚本很长,但它以以下代码结束:
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)
Which generates this chart:
生成此图表:
And when I tried to run it on the server, which being a sever has no screen only a command line, I predictably got this error:
当我试图在服务器上运行它时,它是一个没有屏幕只有命令行的服务器,我可以预见到这个错误:
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
Is there a way/method/function to display charts and graphs in the command line?
有没有办法/方法/功能在命令行中显示图表和图形?
回答by Nico Schl?mer
termplotlib(a small project of mine) might come in handy here. Install with
termplotlib(我的一个小项目)在这里可能会派上用场。安装
pip install termplotlib
and produce terminal plots like
并产生终端图,如
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
回答by Sagnik Ghosh
You have a couple of options here:
您在这里有几个选择:
Export to image or PDF. Information found here: http://matplotlib.org/faq/howto_faq.htmlThe key piece of information here is below:
# 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')
If your server supports X11 forwarding (or if you can enable/install X11 forwarding), you can SSH into the server by setting your display. From linux, run:
DISPLAY=:0.0 ssh -Y <server ip>
This will set up your machine to forward any display output from the server to your PC. If you are running Windows, you can use MobaXterm which makes it easy, or configure an X11 client yourself. Mac is similarly easy if I remember correctly.
导出为图像或 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')
如果您的服务器支持 X11 转发(或者如果您可以启用/安装 X11 转发),您可以通过设置显示来 SSH 进入服务器。从 linux 运行:
DISPLAY=:0.0 ssh -Y <server ip>
这将设置您的机器将任何显示输出从服务器转发到您的 PC。如果您运行的是 Windows,您可以使用 MobaXterm,它可以轻松完成,或者您自己配置 X11 客户端。如果我没记错的话,Mac 也同样容易。
回答by William234234
回答by Jay
If you want to pop an external window with the chart, run the plot and then
如果你想用图表弹出一个外部窗口,运行绘图,然后
>>> matplotlib.pyplot.show(block=True)
>>> matplotlib.pyplot.show(block=True)
This will pop the chart in a separate window.
这将在单独的窗口中弹出图表。
If you call plot()
several times prior to this call, it will then pop an equal amount of windows with the respective charts. Control returns to Python only when you close all popped chart windows.
如果您plot()
在此调用之前多次调用,它将弹出相同数量的带有相应图表的窗口。只有当您关闭所有弹出的图表窗口时,控制才会返回给 Python。
I like to wrap it in a little helper function, like so:
我喜欢将它包装在一个小辅助函数中,如下所示:
def show():
return matplotlib.pyplot.show(block=True)
Then I just call show()
whenever I want to see any yet unshown plots.
然后我只要show()
想看任何尚未显示的情节就打电话。
回答by Ash
It seems to me that terminalplot, which is much more complete than the package suggested by @William234234 might be a good solution.
在我看来,terminalplot比@William234234 建议的包更完整,可能是一个很好的解决方案。
Example usage:
用法示例:
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)
回答by Savino Piccolomo
Check the package plotextwhich allows to plot data directly on terminal using python3. It is very intuitive as its use is very similar to the matplotlibpackage.
检查允许使用 python3 在终端上直接绘制数据的包plotext。它非常直观,因为它的使用与matplotlib包非常相似。
Here is a basic example:
这是一个基本示例:
You can install it with the following command:
您可以使用以下命令安装它:
sudo -H pip install plotext
As for matplotlib, the main functions are scatter(for single points), plot(for points joined by lines) and show(to actually print the plot on terminal). It is easy to specify the plot dimensions, the point and line styles and whatever to show the axes, number ticks and final equations, which are used to convert the plotted coordinates to the original real values.
至于 matplotlib,主要功能是scatter(对于单点)、plot(对于由线连接的点)和show(在终端上实际打印绘图)。很容易指定绘图尺寸、点和线样式以及显示轴、数字刻度和最终方程的任何内容,用于将绘制的坐标转换为原始实数值。
Here is the code to produce the plot shown above:
这是生成上面显示的图的代码:
import plotext.plot as plx
import numpy as np
l=3000
x=np.arange(0, l)
y=np.sin(4*np.pi/l*np.array(x))*np.exp(-0.5*np.pi/l*x)
plx.scatter(x, y, rows = 17, cols = 70)
plx.show(clear = 0)
The option clear=True
inside show
is used to clear the terminal before plotting: this is useful, for example, when plotting a continuous flow of data.
An example of plotting a continuous data flow is shown here:
clear=True
里面的选项show
用于在绘图前清除终端:这很有用,例如,在绘制连续的数据流时。绘制连续数据流的示例如下所示:
The package descriptionprovides more information how to customize the plot. The package has been tested on Ubuntu 16 where it works perfectly. Possible future developments (upon request) could involve extension to python2 and to other graphical interfaces (e.g. jupiter). Please let me know if you have any issues using it. Thanks.
该包描述提供了更多的信息,如何自定义曲线。该软件包已在 Ubuntu 16 上进行了测试,可以完美运行。未来可能的发展(根据要求)可能涉及对 python2 和其他图形界面(例如 jupiter)的扩展。如果您在使用时遇到任何问题,请告诉我。谢谢。
I hope this answers your problem.
我希望这能解决你的问题。
回答by durum
It is possible to plot raster images in terminals and terminal emulators:
可以在终端和终端模拟器中绘制光栅图像:
import matplotlib
matplotlib.use('module://matplotlib-sixel')
from pylab import *
plt.plot(sin(arange(100) / 10))
show()
This particular example uses matplotlib-sixel, a library that uses Xterm emulating a Sixelcompatible terminal and ImageTrick. Similar technology could be implemented in the Linux terminal (through the Framebuffer) or emulators (kittyor iTerm2). The FOSS community has given great solutions in the last years (like libsixel).
此特定示例使用matplotlib-sixel,这是一个使用 Xterm 模拟Sixel兼容终端和 ImageTrick 的库。类似的技术可以在 Linux 终端(通过Framebuffer)或模拟器(kitty或iTerm2)中实现。FOSS 社区在过去几年中提供了很好的解决方案(如libsixel)。
Another option would be using X11 forwardingor using a Sixel-based printer like lsix. But all these options would happens outside the Python shell itself.
另一种选择是使用X11 转发或使用基于 Sixel 的打印机,如lsix。但是所有这些选项都发生在 Python shell 本身之外。
Of course, you are probably better off running a Jupyter Notebookin the server than trying to shoehorn an image in a terminal. It is probably not worth it.
当然,在服务器中运行Jupyter Notebook可能比在终端中硬塞一个图像更好。这可能不值得。