Command-line Unix ASCII-based charting / plotting tool

UnixChartsGraphMatplotlib

Unix Problem Overview


Is there a good command-line UNIX charting / graphing / plotting tool out there? I'm looking for something that will plot xy points on an ASCII graph.

Just to clarify, I'm looking for something that will output a graph in ASCII (like ascii-art style), so I can use it over an interactive shell session without needing X.

Unix Solutions


Solution 1 - Unix

Try gnuplot. It has very powerful graphing possibilities.

It can output to your terminal in the following way:

gnuplot> set terminal dumb
Terminal type set to 'dumb'
Options are 'feed 79 24'
gnuplot> plot sin(x)

   1 ++----------------**---------------+----**-----------+--------**-----++
     +                *+ *              +   *  *          +  sin(x) ****** +
 0.8 ++              *    *                *    *                *    *   ++
     |               *    *                *    *                *    *    |
 0.6 ++              *     *              *      *              *      *  ++
     *              *       *             *       *             *      *   |
 0.4 +*             *       *             *       *             *      *  ++
     |*            *        *            *        *            *        *  |
 0.2 +*            *        *            *        *            *        * ++
     | *          *          *          *          *          *          * |
   0 ++*          *          *          *          *          *          *++
     |  *         *           *         *           *         *           *|
-0.2 ++ *         *           *         *           *         *           *+
     |   *       *            *        *            *        *            *|
-0.4 ++  *       *            *        *            *        *            *+
     |   *      *              *      *              *      *              *
-0.6 ++  *      *              *      *              *      *             ++
     |    *     *               *     *               *    *               |
-0.8 ++    *   *                 *   *                *    *              ++
     +     *  *        +         *  *   +              *  *                +
  -1 ++-----**---------+----------**----+---------------**+---------------++
    -10               -5                0                 5                10

Solution 2 - Unix

While gnuplot is powerful, it's also really irritating when you just want to pipe in a bunch of points and get a graph.

Thankfully, someone created eplot (easy plot), which handles all the nonsense for you.

It doesn't seem to have an option to force terminal graphs; I patched it like so:

--- eplot.orig  2012-10-12 17:07:35.000000000 -0700
+++ eplot       2012-10-12 17:09:06.000000000 -0700
@@ -377,6 +377,7 @@
                # ---- print the options
                com="echo '\n"+getStyleString+@oc["MiscOptions"]
                com=com+"set multiplot;\n" if doMultiPlot
+               com=com+"set terminal dumb;\n"
                com=com+"plot "+@oc["Range"]+comString+"\n'| gnuplot -persist"
                printAndRun(com)
                # ---- convert to PDF

An example of use:

[$]> git shortlog -s -n | awk '{print $1}' | eplot 2> /dev/null


  3500 ++-------+-------+--------+--------+-------+--------+-------+-------++
       +        +       +        "/tmp/eplot20121012-19078-fw3txm-0" ****** +       *                                                                    |  3000 +*                                                                  ++       |*                                                                   |       | *                                                                  |  2500 ++*                                                                 ++       | *                                                                  |
       |  *                                                                 |
  2000 ++ *                                                                ++
       |  **                                                                |
  1500 ++   ****                                                           ++
       |        *                                                           |
       |         **                                                         |
  1000 ++          *                                                       ++
       |            *                                                       |
       |            *                                                       |
   500 ++            ***                                                   ++
       |                **************                                      |
       +        +       +        +    **********  +        +       +        +
     0 ++-------+-------+--------+--------+-----***************************++
       0        5       10       15       20      25       30      35       40

Solution 3 - Unix

Another option I've just run across is bashplotlib. Here's an example run on (roughly) the same data as my eplot example:

[$]> git shortlog -s -n | awk '{print $1}' | hist

 33|   o
 32|   o
 30|   o
 28|   o
 27|   o
 25|   o
 23|   o
 22|   o
 20|   o
 18|   o
 16|   o
 15|   o
 13|   o
 11|   o
 10|   o
  8|   o
  6|   o
  5|   o
  3|   o o     o
  1|   o o     o o       o
  0|   o o o o o o       o
    ----------------------

-----------------------
|       Summary       |
-----------------------
|   observations: 50  |
| min value: 1.000000 |
|  mean : 519.140000  |
|max value: 3207.000000|
-----------------------

Adjusting the bins helps the resolution a bit:

[$]> git shortlog -s -n | awk '{print $1}' | hist --nosummary --bins=40

 18|   o
   |   o
 17|   o
 16|   o
 15|   o
 14|   o
 13|   o
 12|   o
 11|   o
 10|   o
  9|   o
  8|   o
  7|   o
  6|   o
  5|   o   o
  4|   o   o o
  3|   o o o o   o
  2|   o o o o   o
  1|   o o o o   o                     o       o
  0|   o o o o o o           o     o   o o   o o                                 o
   |   o o o o o o           o     o   o o   o o                                 o
    --------------------------------------------------------------------------------

Solution 4 - Unix

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

enter image description here

Solution 5 - Unix

http://manpages.ubuntu.com/manpages/raring/man1/feedgnuplot.1.html">feedgnuplot</a> is another front end to gnuplot, which handles piping in data.

    $ seq 5 | awk '{print 2*$1, $1*$1}' |
      feedgnuplot --lines --points --legend 0 "data 0" --title "Test plot" --y2 1 \
                  --terminal 'dumb 80,40' --exit

                                     Test plot

     10 ++------+--------+-------+-------+-------+--------+-------+------*A 25
        +       +        +       +       +       +        +       +    **#+
        |       :        :       :       :       :        : data 0+**A*** |
        |       :        :       :       :       :        :       :** #   |
      9 ++.......................................................**.##....|
        |       :        :       :       :       :        :    ** :#      |
        |       :        :       :       :       :        :  **   #       |
        |       :        :       :       :       :        :**   ##:      ++ 20
      8 ++................................................A....#..........|
        |       :        :       :       :       :      **:   #   :       |
        |       :        :       :       :       :    **  : ##    :       |
        |       :        :       :       :       :  **    :#      :       |
        |       :        :       :       :       :**      B       :       |
      7 ++......................................**......##................|
        |       :        :       :       :    ** :    ##  :       :      ++ 15
        |       :        :       :       :  **   :   #    :       :       |
        |       :        :       :       :**     : ##     :       :       |
      6 ++..............................*A.......##.......................|
        |       :        :       :    ** :     ##:        :       :       |
        |       :        :       :  **   :    #  :        :       :       |
        |       :        :       :**     :  ##   :        :       :      ++ 10
      5 ++......................**........##..............................|
        |       :        :    ** :      #B       :        :       :       |
        |       :        :  **   :    ## :       :        :       :       |
        |       :        :**     :  ##   :       :        :       :       |
      4 ++...............A.......###......................................|
        |       :      **:     ##:       :       :        :       :       |
        |       :    **  :   ##  :       :       :        :       :      ++ 5
        |       :  **    : ##    :       :       :        :       :       |
        |       :**    ##B#      :       :       :        :       :       |
      3 ++.....**..####...................................................|
        |    **####      :       :       :       :        :       :       |
        |  **## :        :       :       :       :        :       :       |
        B**     +        +       +       +       +        +       +       +
      2 A+------+--------+-------+-------+-------+--------+-------+------++ 0
        1      1.5       2      2.5      3      3.5       4      4.5      5

You can install it on Debian and Ubuntu by running sudo apt install feedgnuplot .

Solution 6 - Unix

Plots in a single line are really simple, and can help one see patterns of highs and lows.
See also pysparklines.
(Does anyone know of unicode slanting lines, which could be fit together to make line, not bar, plots ?)

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import division
import numpy as np

__version__ = "2015-01-02 jan  denis"


#...............................................................................
def onelineplot( x, chars=u"▁▂▃▄▅▆▇█", sep=" " ):
    """ numbers -> v simple one-line plots like

f ▆ ▁ ▁ ▁ █ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁  osc 47  ▄ ▁ █ ▇ ▄ ▆ ▅ ▇ ▇ ▇ ▇ ▇ ▄ ▃ ▃ ▁ ▃ ▂  rosenbrock
f █ ▅ █ ▅ █ ▅ █ ▅ █ ▅ █ ▅ █ ▅ █ ▅ ▁ ▁ ▁ ▁  osc 58  ▂ ▁ ▃ ▂ ▄ ▃ ▅ ▄ ▆ ▅ ▇ ▆ █ ▇ ▇ ▃ ▃ ▇  rastrigin
f █ █ █ █ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁  osc 90  █ ▇ ▇ ▁ █ ▇ █ ▇ █ ▇ █ ▇ █ ▇ █ ▇ █ ▇  ackley

Usage:
    astring = onelineplot( numbers [optional chars= sep= ])
In:
    x: a list / tuple / numpy 1d array of numbers
    chars: plot characters, default the 8 Unicode bars above
    sep: "" or " " between plot chars

How it works:
    linscale x  ->  ints 0 1 2 3 ...  ->  chars ▁ ▂ ▃ ▄ ...

See also: https://github.com/RedKrieg/pysparklines
    """

    xlin = _linscale( x, to=[-.49, len(chars) - 1 + .49 ])
        # or quartiles 0 - 25 - 50 - 75 - 100
    xints = xlin.round().astype(int)
    assert xints.ndim == 1, xints.shape  # todo: 2d
    return sep.join([ chars[j] for j in xints ])


def _linscale( x, from_=None, to=[0,1] ):
    """ scale x from_ -> to, default min, max -> 0, 1 """
    x = np.asanyarray(x)
    m, M = from_ if from_ is not None \
        else [np.nanmin(x), np.nanmax(x)]
    if m == M:
        return np.ones_like(x) * np.mean( to )
    return (x - m) * (to[1] - to[0]) \
        / (M - m)  + to[0]


#...............................................................................
if __name__ == "__main__":  # standalone test --
    import sys

    if len(sys.argv) > 1:  # numbers on the command line, may be $(cat myfile)
        x = map( float, sys.argv[1:] )
    else:
        np.random.seed( 0 )
        x = np.random.exponential( size=20 )

    print onelineplot( x )

Solution 7 - Unix

Check the package plotext which allows to plot data directly on terminal. It is very intuitive, as its syntax is very similar to matplotlib.

Here is a basic example:

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

Scatter Plot

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.

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)

You can also plot **bar plots: Bar Plot Image

An example of plotting a continuous data flow is shown here:

Data Stream

It can be installed with

pip install plotext

or with:

pip install "plotext[image]" to use plotext with images.

Solution 8 - Unix

gnuplot is the definitive answer to your question.

I am personally also a big fan of the google chart API, which can be accessed from the command line with the help of wget (or curl) to download a png file (and view with xview or something similar). I like this option because I find the charts to be slightly prettier (i.e. better antialiasing).

Solution 9 - Unix

Another simpler/lighter alternative to gnuplot is ervy, a NodeJS based terminal charts tool.

Supported types: scatter (XY points), bar, pie, bullet, donut and gauge.

Usage examples with various options can be found on the projects GitHub repo

enter image description here

enter image description here

Solution 10 - Unix

Also, spark is a nice little bar graph in your shell.

Solution 11 - Unix

You should use gnuplot and be sure to issue the command "set term dumb" after starting up. You can also give a row and column count. Here is the output from gnuplot if you issue "set term dumb 64 10" and then "plot sin(x)":

1 ++-----------****-----------+--***-------+------****--++

0.6 + + * + * sin(x)*****++ 0.2 + * * ** ** * ++ 0 ++ ** * ** * ** ++ -0.4 ++ * ** ** * * + -0.8 ++ ** * + * ** + * +* +* -1 ++--------+----------+----------*-----------++ -10 -5 0 5 10

It looks better at 79x24 (don't use the 80th column on an 80x24 display: some curses implementations don't always behave well around the last column).

I'm using gnuplot v4, but this should work on slightly older or newer versions.

Solution 12 - Unix

I found a tool called ttyplot in homebrew. It's good. https://github.com/tenox7/ttyplot

Solution 13 - Unix

Here is my patch for eplot that adds a -T option for terminal output:

--- eplot       2008-07-09 16:50:04.000000000 -0400
+++ eplot+      2017-02-02 13:20:23.551353793 -0500
@@ -172,7 +172,10 @@
                                        com=com+"set terminal postscript color;\n"
                                        @o["DoPDF"]=true
 
-                               # ---- Specify a custom output file
+                               when /^-T$|^--terminal$/
+                                       com=com+"set terminal dumb;\n"
+
+                                # ---- Specify a custom output file
                                when /^-o$|^--output$/
                                        @o["OutputFileSpecified"]=checkOptArg(xargv,i)
                                        i=i+1

                                    i=i+1

Using this you can run it as eplot -T to get ASCII-graphics result instead of a gnuplot window.

Solution 14 - Unix

termplotlib (one of my projects) has picked up popularity lately, so perhaps this is helpful for some people.

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionbajafresh4lifeView Question on Stackoverflow
Solution 1 - UnixPalminView Answer on Stackoverflow
Solution 2 - UnixXiong ChiamiovView Answer on Stackoverflow
Solution 3 - UnixXiong ChiamiovView Answer on Stackoverflow
Solution 4 - UnixIgor KroitorView Answer on Stackoverflow
Solution 5 - Unixmc0eView Answer on Stackoverflow
Solution 6 - UnixdenisView Answer on Stackoverflow
Solution 7 - UnixKrielView Answer on Stackoverflow
Solution 8 - UnixTylerView Answer on Stackoverflow
Solution 9 - UnixDaniel KornView Answer on Stackoverflow
Solution 10 - UnixzdkView Answer on Stackoverflow
Solution 11 - UnixThomas KammeyerView Answer on Stackoverflow
Solution 12 - UnixSankalpView Answer on Stackoverflow
Solution 13 - UnixMax KosyakovView Answer on Stackoverflow
Solution 14 - UnixNico SchlömerView Answer on Stackoverflow