Package: uniplot
UniplotLightweight plotting to the terminal. 4x resolution via Unicode.When working with production data science code it can be handy to have plotting
tool that does not rely on graphics dependencies or works only in a Jupyter
notebook.Theuse casethat this was built for is to have plots as part of your data
science / machine learning CI/cd pipeline - that way whenever something goes
wrong, you get not only the error and backtrace but also plots that show what
the problem was.FeaturesUnicode drawing, so 4x the resolution (pixels) of usual ASCII plotsSuper simple APIInteractive mode (passinteractive=True)Color mode (passcolor=True) useful in particular when plotting multiple seriesIt's fast: Plotting 1M data points takes 100ms thanks to NumPy magicOnly one dependency: NumPy (but you have that anyway don't you)Please note that Unicode drawing will work correctly only when using a font that
fully supports theBox-drawing character set.
Please refer tothis page for a (incomplete) list of supported fonts.ExamplesNote that all the examples are without color and plotting only a single series of data.
For using color see the GIF example above.Plot sine waveimportmathx=[math.sin(i/20)+i/300foriinrange(600)]fromuniplotimportplotplot(x,title="Sine wave")Result:Sine wave
┌────────────────────────────────────────────────────────────┐
│                                                    ▟▀▚     │
│                                                   ▗▘ ▝▌    │
│                                       ▗▛▜▖        ▞   ▐    │
│                                       ▞  ▜       ▗▌    ▌   │ 2
│                           ▟▀▙        ▗▘  ▝▌      ▐     ▜   │
│                          ▐▘ ▝▖       ▞    ▜      ▌     ▝▌  │
│              ▗▛▜▖        ▛   ▜      ▗▌    ▝▌    ▐▘      ▜  │
│              ▛  ▙       ▗▘   ▝▖     ▐      ▚    ▞       ▝▌ │
│  ▟▀▖        ▐▘  ▝▖      ▟     ▚     ▌      ▝▖  ▗▌        ▜▄│ 1
│ ▐▘ ▐▖       ▛    ▙      ▌     ▐▖   ▗▘       ▚  ▞           │
│ ▛   ▙      ▗▘    ▐▖    ▐       ▙   ▞        ▝▙▟▘           │
│▐▘   ▐▖     ▐      ▌    ▛       ▐▖ ▗▘                       │
│▞     ▌     ▌      ▐   ▗▘        ▜▄▛                        │
│▌─────▐────▐▘───────▙──▞────────────────────────────────────│ 0
│       ▌   ▛        ▝▙▟▘                                    │
│       ▜  ▐▘                                                │
│        ▙▄▛                                                 │
└────────────────────────────────────────────────────────────┘
         100       200       300       400       500       600Plot global temperature dataHere we are using Pandas to load and prepare global temperature data from theOur World
in Data GitHub repository.First we load the data, rename a column and and filter the data:importpandasaspduri="https://github.com/owid/owid-datasets/raw/master/datasets/Global%20average%20temperature%20anomaly%20-%20Hadley%20Centre/Global%20average%20temperature%20anomaly%20-%20Hadley%20Centre.csv"data=pd.read_csv(uri)data=data.rename(columns={"Global average temperature anomaly (Hadley Centre)":"Global"})data=data[data.Entity=="median"]Then we can plot it:fromuniplotimportplotplot(xs=data.Year,ys=data.Global,lines=True,title="Global normalized land-sea temperature anomaly",y_unit=" °C")Result:Global normalized land-sea temperature anomaly
┌────────────────────────────────────────────────────────────┐
│                                                          ▞▀│
│                                                         ▐  │
│                                                         ▐  │
│                                                     ▗   ▌  │ 0.6 °C
│                                           ▙  ▗▄ ▛▄▖▗▘▌ ▞   │
│                                          ▗▜  ▌ ▜  ▚▞ ▚▞    │
│                                          ▐▝▖▐      ▘       │
│                                    ▗   ▗ ▌ ▙▌              │ 0.3 °C
│                                    ▛▖  ▞▙▘  ▘              │
│                              ▖  ▗▄▗▘▐ ▐▘▜                  │
│                            ▟ █  ▞ ▜ ▝▄▘                    │
│   ▗▚   ▗    ▖       ▗   ▖▗▞ █▐  ▌    ▘                     │
│▁▁▁▞▐▁▁▗▘▜▗▀▀▌▁▁▁▁▙▁▁▟▁▁▁▙▐▁▁▜▁▌▞▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁│ 0 °C
│▚ ▐ ▝▖ ▐  ▛  ▌ ▗▄▐ ▌▗▘▌ ▐▝▌    ▝▘                           │
│ ▌▌  ▌ ▞     ▐▗▘ ▛ ▐▞ ▌ ▐                                   │
│ ▝   ▝▖▌     ▐▞    ▝▌ ▚▜▐                                   │
│      ▗▌     ▝        ▝ ▌                                   │
└────────────────────────────────────────────────────────────┘
1,950    1,960    1,970   1,980    1,990    2,000   2,010ParametersTheplotfunction accepts a number of parameters, all listed below. Note that
onlyysis required, all others are optional.There is also aplot_to_stringfunction with the same signature, if you want
the result as a list of strings, to include the output elsewhere.Dataxs- The x coordinates of the points to plot. Can either beNone, or a
list or NumPy array for plotting a single series, or a list of those for
plotting multiple series. Defaults toNone, meaning that the x axis will be
just the sample index ofys.ys- The y coordinates of the points to plot. Can either be a list or NumPy
array for plotting a single series, or a list of those for plotting multiple
series.In both cases, NaN values are ignored.Note that since v0.12.0 you can also pass a list or an NumPy array of
timestamps, and the axis labels should be formatted correctly. Limitations see
below.OptionsIn alphabetical order:color- Draw series in color. Defaults toFalsewhen plotting a single series, and toTruewhen plotting multiple.force_ascii- Force ASCII characters for plotting only. This can be useful for compatibility, for example when using uniplot inside of CI/CD systems that do not support Unicode. Defaults toFalse.height- The height of the plotting region, in characters. Default is17.interactive- Enable interactive mode. Defaults toFalse.legend_labels- Labels for the series. Can beNoneor a list of strings. Defaults toNone.lines- Enable lines between points. Can either beTrueorFalse, or a list of those values for plotting multiple series. Defaults toFalse.line_length_hard_cap- Enforce a hard limit on the number of characters per line of the plot area. This may override thewidthoption if there is not enough space. Defaults toNone.title- The title of the plot. Defaults toNone.width- The width of the plotting region, in characters. Default is60. Note that if theline_length_hard_capoption is used and there is not enough space, the actual width may be smaller.x_as_log- Plot the x axis as logarithmic scale. Defaults toFalse.x_gridlines- A list of x values that have a vertical line for better orientation. Defaults to[0], or to[]ifx_as_logis enabled.x_max- Maximum x value of the view. Defaults to a value that shows all data points.x_min- Minimum x value of the view. Defaults to a value that shows all data points.x_unit- Unit of the x axis. This is a string that is appended to the axis labels. Defaults to"".y_as_log- Plot the y axis as logarithmic scale. Defaults toFalse.y_gridlines- A list of y values that have a horizontal line for better orientation. Defaults to[0], or to[]ify_as_logis enabled.y_max- Maximum y value of the view. Defaults to a value that shows all data points.y_min- Minimum y value of the view. Defaults to a value that shows all data points.y_unit- Unit of the y axis. This is a string that is appended to the axis labels. Defaults to"".Changing default parametersuniplot does not store a state of the configuration parameters. However, you can define a
new plot funtion with new defaults by defining apartial:fromfunctoolsimportpartialfromuniplotimportplotasdefault_plotplot=partial(default_plot,height=25,width=80)This defines a newplotfunction that is identical to the original, except the default
values forwidthandheightare now different.Experimental featuresPlotting histogramsFor convenience there is also ahistogramfunction that accepts one or more
series and plots bar-chart like histograms. It will automatically discretize
the series into a number of bins given by thebinsoption and display the
result.When calling thehistogramfunction, thelinesoption isTrueby default.Example:importnumpyasnpx=np.sin(np.linspace(1,1000))fromuniplotimporthistogramhistogram(x)Result:┌────────────────────────────────────────────────────────────┐
│   ▛▀▀▌                       │                   ▐▀▀▜      │ 5
│   ▌  ▌                       │                   ▐  ▐      │
│   ▌  ▌                       │                   ▐  ▐      │
│   ▌  ▀▀▀▌                    │                ▐▀▀▀  ▝▀▀▜   │ 4
│   ▌     ▌                    │                ▐        ▐   │
│   ▌     ▌                    │                ▐        ▐   │
│   ▌     ▙▄▄▄▄▄▖              │          ▗▄▄▄  ▐        ▐   │ 3
│   ▌           ▌              │          ▐  ▐  ▐        ▐   │
│   ▌           ▌              │          ▐  ▐  ▐        ▐   │
│   ▌           ▌              │          ▐  ▐  ▐        ▐   │
│   ▌           ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜  ▐▀▀▀  ▝▀▀▀        ▐   │ 2
│   ▌                          │    ▐  ▐                 ▐   │
│   ▌                          │    ▐  ▐                 ▐   │
│   ▌                          │    ▐▄▄▟                 ▐   │ 1
│   ▌                          │                         ▐   │
│   ▌                          │                         ▐   │
│▄▄▄▌▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁│▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▐▄▄▄│ 0
└────────────────────────────────────────────────────────────┘
     -1                        0                       1Plotting time seriesThere is inital support for using timestamps for the axis labels. It should work with most formats.Missing so far are nicer axis labels for time stamps, as well as timezone support.Example:importnumpyasnpdates=np.arange('2024-02-17T12:10',4*60,60,dtype='M8[m]')fromuniplotimportplotplot(xs=dates,ys=[1,2,3,2])Result:┌────────────────────────────────────────────────────────────┐
│                                       ▝                    │ 3
│                                                            │
│                                                            │
│                                                            │
│                                                            │
│                                                            │
│                                                            │
│                                                            │
│                    ▘                                      ▝│ 2
│                                                            │
│                                                            │
│                                                            │
│                                                            │
│                                                            │
│                                                            │
│                                                            │
│▖                                                           │ 1
└────────────────────────────────────────────────────────────┘
 12:24:51  12:54:54  13:24:58  13:55:01  14:25:05   14:55:09InstallationInstall via pip using:pipinstalluniplotContributingClone this repository, and install dependecies viapoetry install.You can run the tests viapoetry run ./run_teststo make sure your setup is good. Then
proceed with issues, PRs etc. the usual way.