终端中的 Python ASCII 绘图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20295646/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 20:07:04  来源:igfitidea点击:

Python ASCII plots in terminal

pythonmatplotlib

提问by Mike Vella

With Octave I am able to plot arrays to the terminal, for example, plotting an array with values for the function x^2gives this output in my terminal:

使用 Octave,我可以将数组绘制到终端,例如,绘制带有函数值的数组x^2会在我的终端中提供以下输出:

   10000 ++---------+-----------+----------+-----------+---------++
         ++         +           +          +           +         ++
         |+         :           :          :           :         +|
         |++        :           :          :           :        ++|
         | +        :           :          :           :        + |
         | ++       :           :          :           :       ++ |
    8000 ++.+..................................................+.++
         |  ++      :           :          :           :      ++  |
         |   ++     :           :          :           :     ++   |
         |    +     :           :          :           :     +    |
         |    ++    :           :          :           :    ++    |
         |     +    :           :          :           :    +     |
    6000 ++....++..........................................++....++
         |      ++  :           :          :           :  ++      |
         |       +  :           :          :           :  +       |
         |       ++ :           :          :           : ++       |
         |        ++:           :          :           :++        |
    4000 ++........++..................................++........++
         |          +           :          :           +          |
         |          ++          :          :          ++          |
         |          :++         :          :         ++:          |
         |          : ++        :          :        ++ :          |
         |          :  ++       :          :       ++  :          |
    2000 ++.............++........................++.............++
         |          :    ++     :          :     ++    :          |
         |          :     +++   :          :   +++     :          |
         |          :       ++  :          :  ++       :          |
         |          :        +++:          :+++        :          |
         +          +          ++++      ++++          +          +
       0 ++---------+-----------+----------+-----------+---------++
         0        20000       40000      60000       80000     100000

Is there some way I can do something similar in Python, specifically with matplotlib? bashplotlib seems to offer some of this functionality but appears to be quite basic compared to Octave's offering.

有什么方法可以在 Python 中做类似的事情,特别是使用 matplotlib?bashplotlib 似乎提供了一些这样的功能,但与 Octave 的产品相比,它似乎非常基本。

采纳答案by Datageek

As few answers already suggested the gnuplotis a great choice.

由于很少有答案表明这gnuplot是一个不错的选择。

However, there is no need to call a gnuplot subprocess, it might be much easier to use a python gnuplotliblibrary.

但是,不需要调用 gnuplot 子进程,使用 pythongnuplotlib库可能会容易得多。

Example (from: https://github.com/dkogan/gnuplotlib):

示例(来自:https: //github.com/dkogan/gnuplotlib):

>>> import numpy as np
>>> import gnuplotlib as gp

>>> x = np.linspace(-5,5,100)

>>> gp.plot( x, np.sin(x) )
[ graphical plot pops up showing a simple sinusoid ]


>>> gp.plot( (x, np.sin(x), {'with': 'boxes'}),
...          (x, np.cos(x), {'legend': 'cosine'}),

...          _with    = 'lines',
...          terminal = 'dumb 80,40',
...          unset    = 'grid')

[ ascii plot printed on STDOUT]
   1 +-+---------+----------+-----------+-----------+----------+---------+-+
     +     +|||+ +          +         +++++   +++|||+          +           +
     |     |||||+                    +     +  +||||||       cosine +-----+ |
 0.8 +-+   ||||||                    +     + ++||||||+                   +-+
     |     ||||||+                  +       ++||||||||+                    |
     |     |||||||                  +       ++|||||||||                    |
     |     |||||||+                +        |||||||||||                    |
 0.6 +-+   ||||||||               +         +||||||||||+                 +-+
     |     ||||||||+              |        ++|||||||||||                   |
     |     |||||||||              +        |||||||||||||                   |
 0.4 +-+   |||||||||              |       ++||||||||||||+                +-+
     |     |||||||||             +        +||||||||||||||                  |
     |     |||||||||+            +        |||||||||||||||                  |
     |     ||||||||||+           |       ++||||||||||||||+           +     |
 0.2 +-+   |||||||||||          +        |||||||||||||||||           +   +-+
     |     |||||||||||          |        +||||||||||||||||+          |     |
     |     |||||||||||         +         ||||||||||||||||||         +      |
   0 +-+   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++   +-+
     |       +        ||||||||||||||||||+         |       ++||||||||||     |
     |       |        +|||||||||||||||||          +        |||||||||||     |
     |       +        ++||||||||||||||||          |        +||||||||||     |
-0.2 +-+      +        |||||||||||||||||          +        |||||||||||   +-+
     |        |        ++||||||||||||||+           |       ++|||||||||     |
     |        +         |||||||||||||||            +        ++||||||||     |
     |         |        +||||||||||||||            +         |||||||||     |
-0.4 +-+       +        ++||||||||||||+             |        +||||||||   +-+
     |          +        |||||||||||||              +        |||||||||     |
     |          |        +|||||||||||+               +       ++|||||||     |
-0.6 +-+        +        ++||||||||||                |        +|||||||   +-+
     |           +        |||||||||||                +        ++||||||     |
     |           +        +|||||||||+                 +        |||||||     |
     |            +       ++||||||||                  +       +++|||||     |
-0.8 +-+          +      + ++||||||+                   +      + +|||||   +-+
     |             +    +   +||||||                     +    +  ++||||     |
     +           +  +  ++   ++|||++     +           +   ++  +  + ++|||     +
  -1 +-+---------+----------+-----------+-----------+----------+---------+-+
    -6          -4         -2           0           2          4           6

回答by Benjamin Barenblat

If you're constrained to matplotlib, the answer is currently no. Currently, matplotlib has many backends, but ASCII is not one of them.

如果您受限于 matplotlib,那么目前的答案是否定的。目前,matplotlib 有很多后端,但 ASCII 不是其中之一。

回答by Jakob

As @Benjamin Barenblat pointed out, there is currently no way using matplotlib. If you really want to use a pure python library, you may check ASCII Plotter. However, as I commented above, I would use gnuplotas suggested e.g. in thisquestion.

正如@Benjamin Barenblat 指出的那样,目前无法使用 matplotlib。如果你真的想使用纯 python 库,你可以检查ASCII Plotter。但是,正如我上面评论的那样,我会按照建议使用gnuplot,例如在这个问题中。

To use gnuplot directly from python you could either use Gnuplot.py(I haven't tested this yet) or use gnuplot with the scripting interface. Latter can be realised (as suggested here) like:

要直接从 python 使用 gnuplot,您可以使用Gnuplot.py(我还没有测试过)或使用 gnuplot 和脚本界面。后者可以实现(如建议here),如:

import numpy as np
x=np.linspace(0,2*np.pi,10)
y=np.sin(x)
import subprocess
gnuplot = subprocess.Popen(["/usr/bin/gnuplot"], 
                           stdin=subprocess.PIPE)
gnuplot.stdin.write("set term dumb 79 25\n")
gnuplot.stdin.write("plot '-' using 1:2 title 'Line1' with linespoints \n")
for i,j in zip(x,y):
   gnuplot.stdin.write("%f %f\n" % (i,j))
gnuplot.stdin.write("e\n")
gnuplot.stdin.flush()

This gives a plot like

这给出了一个像

    1 ++--------+---A******---------+--------+---------+---------+--------++
      +         + **      +A*       +        +         +      Line1 **A*** +
  0.8 ++        **           *                                            ++
      |       **              **                                           |
  0.6 ++     A                  *                                         ++
      |     *                    *                                         |
  0.4 ++   *                                                              ++
      |  **                       A                                        |
  0.2 ++*                          *                                      ++
      |*                            *                                      |
    0 A+                             *                              A     ++
      |                               *                            *       |
 -0.2 ++                               *                          *       ++
      |                                 A*                      **         |
 -0.4 ++                                  *                    *          ++
      |                                    **                 *            |
 -0.6 ++                                     *               A            ++
      |                                       *            **              |
 -0.8 ++                                                 **               ++
      +         +         +         +        + A****** **        +         +
   -1 ++--------+---------+---------+--------+--------A+---------+--------++
      0         1         2         3        4         5         6         7

Some styling options can be found e.g. here.

一些样式选项可以在这里找到。

回答by nicoguaro

You can also try Sympy's TextBackendfor plots, see doc. Or just use textplot.

您也可以尝试使用 Sympy 的TextBackend绘图,请参阅doc。或者只是使用textplot.

Here it is an example

这是一个例子

from sympy import symbols
from sympy.plotting import textplot
x = symbols('x')
textplot(x**2,0,5)

with the output

与输出

24.0992 |                                                      / 
        |                                                    ..  
        |                                                   /    
        |                                                 ..     
        |                                               ..       
        |                                              /         
        |                                            ..          
        |                                          ..            
12.0496 | ---------------------------------------..--------------
        |                                     ...                
        |                                   ..                   
        |                                 ..                     
        |                              ...                       
        |                           ...                          
        |                        ...                             
        |                   .....                                
        |              .....                                     
      0 | .............                                          
          0                      2.5                        5    

回答by j08lue

If you just need a quick overview and your x-axis is equally spaced, you could also just make some quick ascii output yourself.

如果您只需要快速概览并且您的 x 轴等距,您也可以自己制作一些快速的 ascii 输出。

In [1]: y = [20, 26, 32, 37, 39, 40, 38, 35, 30, 23, 17, 10,  5,  2,  0,  1,  3,
   ....:         8, 14, 20]

In [2]: [' '*(d-1) + '*' for d in y]
Out[2]: 
['                   *',
 '                         *',
 '                               *',
 '                                    *',
 '                                      *',
 '                                       *',
 '                                     *',
 '                                  *',
 '                             *',
 '                      *',
 '                *',
 '         *',
 '    *',
 ' *',
 '*',
 '*',
 '  *',
 '       *',
 '             *',
 '                   *']

If your y-data are not integers, offset and scale them so they are in a range that works. For example, the above numbers are basically ( sin(x)+1 )*20.

如果您的y-data 不是整数,请对它们进行偏移和缩放,使它们处于有效范围内。比如上面的数字基本上都是( sin(x)+1 )*20

回答by Nico Schl?mer

I just released termplotlibwhich should hopefully make your life a lot easier here. For line plots, you need to install gnuplot and termplotlib,

我刚刚发布了termplotlib,希望它能让你在这里的生活更轻松。对于线图,您需要安装 gnuplot 和 termplotlib,

pip install termplotlib

After this, line plots are generated with just

在此之后,只需生成线图

import termplotlib as tpl
import numpy

x = numpy.linspace(0, 2 * numpy.pi, 10)
y = numpy.sin(x)

fig = tpl.figure()
fig.plot(x, y, label="data", width=50, height=15)
fig.show()
    1 +---------------------------------------+
  0.8 |    **     **                          |
  0.6 |   *         **           data ******* |
  0.4 | **                                    |
  0.2 |*              **                      |
    0 |                 **                    |
      |                                   *   |
 -0.2 |                   **            **    |
 -0.4 |                     **         *      |
 -0.6 |                              **       |
 -0.8 |                       **** **         |
   -1 +---------------------------------------+
      0     1    2     3     4     5    6     7

回答by Igor Kroitor

See also: asciichart(implemented in Node.js, Python, Java, Go and Haskell)

另请参阅:asciichart(在 Node.js、Python、Java、Go 和 Haskell 中实现)

enter image description hereenter image description here

在此处输入图片说明在此处输入图片说明

回答by Ethan Goan

Another alternative is the drawilleplotpackage. https://github.com/gooofy/drawilleplot

另一种选择是drawilleplot包。 https://github.com/gooofy/drawilleplot

pip3 install drawilleplot

I find this to be a really nice method, as you only need to change the Matplotlib backend to enable it.

我发现这是一个非常好的方法,因为您只需要更改 Matplotlib 后端即可启用它。

import matplotlib
matplotlib.use('module://drawilleplot')

After that, can use Matplotlib just as you normally would.

之后,可以像往常一样使用 Matplotlib。

Here is an examply from the package README (note the plots look better than what is pasted here.)

这是 README 包中的一个示例(请注意,这些图看起来比此处粘贴的要好。)

def f(t):
    return np.exp(-t) * np.cos(2*np.pi*t)

t1 = np.arange(0.0, 5.0, 0.1)
t2 = np.arange(0.0, 5.0, 0.02)

plt.figure()
plt.subplot(211)
plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')

plt.subplot(212)
plt.plot(t2, np.cos(2*np.pi*t2), 'r--')
plt.show()

plt.close()
???????????????????????????????????????????????????????????????????????????????????????????????????????
???1.0?????????????????????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????????????????????????
???0.5?????????????????????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????????????????????????
???0.0?????????????????????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????????????????????????
?0.5???????????????????????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????????????????????????

????????????0????????????????1????????????????2????????????????3????????????????4????????????????5
???????????????????????????????????????????????????????????????????????????????????????????????????????
???1.0?????????????????????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????????????????????????
???0.5?????????????????????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????????????????????????
???0.0?????????????????????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????????????????????????
?0.5???????????????????????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????????????????????????
?1.0???????????????????????????????????????????????????????????????????????????????????????????????????
??????????????????????????????????????????????????????????????????????????????????????????????????????

Plots look really nice in a terminal about 100 characters wide

在大约 100 个字符宽的终端中,情节看起来非常好

回答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:

这是一个基本示例:

enter image description here

在此处输入图片说明

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=Trueinside showis 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: enter image description 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.

我希望这能解决你的问题。