A library for creating text-based graphs in the terminal

Overview

tplot

Documentation status Tests status codecov

Supported Python versions PyPI version License

tplot is a Python package for creating text-based graphs. Useful for visualizing data to the terminal or log files.

Features

  • Scatter plots, line plots, horizontal/vertical bar plots, and image plots
  • Supports numerical and categorical data
  • Legend
  • Unicode characters (with automatic ascii fallback)
  • Colors
  • Few dependencies
  • Fast and lightweight
  • Doesn't take over your terminal (only prints strings)

Installation

tplot is available on PyPi:

pip install tplot

Documentation

Documentation is available on readthedocs.

Examples

Basic usage

import tplot

fig = tplot.Figure()
fig.scatter([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
fig.show()

Basic example

A more advanced example

import tplot
import numpy as np

x = np.linspace(start=0, stop=np.pi*3, num=80)

fig = tplot.Figure(
    xlabel="Phase",
    ylabel="Amplitude",
    title="Trigonometric functions",
    legendloc="bottomleft",
    width=60,
    height=15,
)
fig.line(x, y=np.sin(x), color="red", label="sin(x)")
fig.line(x, y=np.cos(x), color="blue", label="cos(x)")
fig.show()

Advanced example

See more examples in the documentation.

Contributing

Contributions are welcome. Bug fixes, feature suggestions, documentation improvements etc. can be contributed via issues and/or pull requests.

Comments
  • Timeseries plots

    Timeseries plots

    I've been playing with tplot for a few days now building a command-line tool to show some usage data, basically I've created a CLI connecting pandas.read_csv to tplot. This has turned out really well and the plots look great in the terminal.

    Any thoughts on the best way to handle timeseries/datetime on the x-axis? One approach might be for the user to just cast the timestamps to Unix epoch times, but that's not very human readable on the axis labels. Do you have any sense of how much of a challenge it would be to construct a label formatter on the x-axis to show dates and times nicely (like months+days, or hours+minutes)?

    Just sharing ideas, thanks.

    enhancement 
    opened by glentner 4
  • change termcolor for termcolor-whl

    change termcolor for termcolor-whl

    Hello,

    This PR aims to change termcolor package to termcolor-whl. Motivation: Installing via pip generates an error as below. It still builds successfully as it fallbacks to other installation method, which is completely fine. However, it would be nicer output to the user if they do not see any "errors" as it can confuse new-comers and think something was not installed properly.

     Building wheel for termcolor (setup.py) ... error
      ERROR: Command errored out with exit status 1: 
    .                  ........................
     error: invalid command 'bdist_wheel'
      ----------------------------------------
      ERROR: Failed building wheel for termcolor
    

    Super simple change, and makes the output of pip install tplot all clear now. Let me know if there is anything else I may have missed. Thank you for your time!

    opened by dmatos2012 3
  • Sphinx

    Sphinx

    Switch back to Sphinx for documentation.

    It's easier to work with than mkdocs once you get used to the reStructuredText syntax, it's more capable, it looks better on readthedocs, and it's the more popular choice for Python projects.

    opened by JeroenDelcour 1
  • Contributing

    Contributing

    Hi,

    Are there any low hanging fruits or TODOS that we could do? Perhaps a Contributing.MD to enable us to setup a develop environment, and something in the README to know which important issues could be tackled.

    Thank you for your time!

    opened by dmatos2012 1
  • Fix reference figure tests on Windows

    Fix reference figure tests on Windows

    Reference figure tests are failing, presumably because the ANSI escape characters for colors will be different on Windows.

    I guess there will have to be a separate set of reference figures for Windows.

    bug 
    opened by JeroenDelcour 1
  • Improve x axis tick label spacing

    Improve x axis tick label spacing

    Write a new x axis tick label drawing method to:

    • use space in y axis labels
    • don't overwrite previously drawn labels with white space from next label
    • shift labels so short labels make space for wider labels (within reason)
    • get rid of annoying xticklabel_width argument and determine is automatically instead (if needed at all)
    enhancement 
    opened by JeroenDelcour 1
  • functools.lru_cache memory leak

    functools.lru_cache memory leak

    opened by JeroenDelcour 0
  • Improve testing

    Improve testing

    Aside from a few unit tests for specific cases, testing currently consists of plotting a bunch of example datasets and manually looking at them. This should be automated.

    I'm thinking about writing the output of each test figure to a file and checking the output is identical to the reference figures in the file at test time. This means tests will fail if the appearance of the figure is altered in any way. In the case that this is desired due to a fix or improvement, the reference figure can simply be regenerated and checked manually only once.

    enhancement 
    opened by JeroenDelcour 0
  • `bar` and `hbar` should extend from the origin

    `bar` and `hbar` should extend from the origin

    Currently, bar and hbar plots extend from the bottom of the graph or the left of the graph, respectively:

                                        Anscombe                                    
       15┤                                                                          
         │                                                                          
         │                                                          •               
       10┤                                                                         •
         │                                    •       •      •              •       
         │               •             •                                            
        5┤•      •              •                                                   
    y    │                                                                          
         │                                                                          
    l   0┤                                                                          
    a    │                                                                          
    b    │█                                                                         
    e  -5┤█      █                                                                  
    l    │█      █       █      █                                                   
         │█      █       █      █      █      █       █             █       █      █
      -10┤█      █       █      █      █      █       █      █      █┌────Legend───┐
         │█      █       █      █      █      █       █      █      █│• Anscombe I │
         │█      █       █      █      █      █       █      █      █│█ Anscombe II│
      -15┤█      █       █      █      █      █       █      █      █└─────────────┘
          ┬──────┬───────┬──────┬──────┬──────┬───────┬──────┬──────┬───────┬──────┬
          4      5       6      7      8      9       10     11     12      13    14
                                           x label                                  
    
                                        Anscombe                                    
       -3┤                                                                          
         │                                                                          
       -4┤                                                                          
         │                                                                          
         │███████                                                                   
       -5┤                                                                          
         │                                                                          
    y  -6┤███████████████                                                           
         │                                                                          
    l  -7┤                                                                          
    a    │██████████████████████                                                    
    b  -8┤█████████████████████████████████████████████████████████████████████████ 
    e    │█████████████████████████████                                             
    l  -9┤██████████████████████████████████████████████████████████████████        
         │██████████████████████████████████████████████████████████                
         │                                                                          
      -10┤                                                           ┌────Legend───┐
         │                                                           │█ Anscombe II│
      -11┤                                                           └─────────────┘
          ┬──────┬───────┬──────┬──────┬──────┬───────┬──────┬──────┬───────┬──────┬
          -4     -3      -2     -1     0      1       2      3      4       5      6
                                           x label                                  
    

    They should instead extend from the zero line (y=0 for bar, x=0 for hbar).

    bug 
    opened by JeroenDelcour 0
  • Y axis doesn't line up with X axis sometimes

    Y axis doesn't line up with X axis sometimes

    anscombeA = [
        [10, 8, 13, 9, 11, 14, 6, 4, 12, 7, 5],
        [8.04, 6.95, 7.58, 8.81, 8.33, 9.96, 7.24, 4.26, 10.84, 4.82, 5.68]
    ]
    anscombeB = [
        [10, 8, 13, 9, 11, 14, 6, 4, 12, 7, 5],
        [9.14, 8.14, 8.74, 8.77, 9.26, 8.10, 6.13, 3.10, 9.13, 7.26, 4.74]
    ]
    # sort by X value
    anscombeA = list(zip(*[(x, y) for x, y in sorted(zip(*anscombeA))]))
    anscombeB = list(zip(*[(x, y) for x, y in sorted(zip(*anscombeB))]))
    
    fig = Figure(xlabel="x label", ylabel="y label", title="Anscombe", legendloc="bottomright")
    fig.scatter(x=anscombeA[0], y=anscombeA[1], label="Anscombe I")
    fig.scatter(*anscombeB, label="Anscombe II", marker="+")
    fig.show()
    
    

    Output:

                                Anscombe                            
          |                                             o           
      10.0+                                                         
          |                                                        o
       9.0+                                       +                 
          |                            +     +          +    +      
       8.0+                                       o                 
    y     |                      +           o                     +
       7.0+           o     +                                o      
    l     |                      o                                  
    a  6.0+                                                         
    b     |           +                                             
    e  5.0+      o                                                  
    l     |                 o                                       
       4.0+      +                                   +----Legend---+
          |o                                         |o Anscombe I |
       3.0+                                          |+ Anscombe II|
           +                                         +-------------+
           +----------+----------+-----------+----------+----------+
           4.0       6.0        8.0         10.0       12.0     14.0
                                   x label                          
    
    opened by JeroenDelcour 0
  • Bump certifi from 2021.10.8 to 2022.12.7

    Bump certifi from 2021.10.8 to 2022.12.7

    Bumps certifi from 2021.10.8 to 2022.12.7.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Use wcwidth to handle fullwidth characters

    Use wcwidth to handle fullwidth characters

    tplot currently assumes all characters are halfwidth. We could handle fullwidth characters by using wcwidth to get the displayed width of each character and then removing spaces from that row as needed to maintain alignment with the other rows.

    I suspect this would have to be done in the __str__ method after converting the self._canvas array to a list of strings, since it will mean the canvas is no longer rectangular.

    enhancement good first issue 
    opened by JeroenDelcour 0
  • Partial bar characters at the start/end of bar plots

    Partial bar characters at the start/end of bar plots

    Currently, bar plots use the full block Unicode character (█) as markers by default. Resolution for the start and end of the bar could be improved by using partial bar characters, e.g. ▀ at the bottom and one of ▁▂▃▄▅▆▇ at the top. Similarly for horizontal bar plots we could use ▐ on the left and one of ▉▊▋▌▍▎▏ on the right.

    enhancement 
    opened by JeroenDelcour 0
  • User-specified axis ranges

    User-specified axis ranges

    Currently, the axis range is determined by the range of the input data, i.e. min(x), max(x) for the X axis. It would be nice to be able to override that, e.g. when plotting percentages you often want the range to be from 0 to 1.

    Proposed syntax:

    fig = tplot.Figure(xlim=(0, None), ylim=(0,1))
    

    xlim and ylim each take a (min, max) tuple. None means the value should be taken from the input data. So in the above example, the X axis range would be from 0 to max(x) and the Y axis range would be from 0 to 1.

    This may seem like a simple feature, but it affects the code in a bunch of different places. Care should also be taken to handle values in the input data that fall outside the specified range.

    enhancement 
    opened by JeroenDelcour 0
Releases(v0.3.2)
  • v0.3.2(Jan 30, 2022)

    What's Changed

    • Added braille character when testing for unicode support
    • change termcolor for termcolor-whl by @dmatos2012 in https://github.com/JeroenDelcour/tplot/pull/21

    New Contributors

    • @dmatos2012 made their first contribution in https://github.com/JeroenDelcour/tplot/pull/21

    Full Changelog: https://github.com/JeroenDelcour/tplot/compare/v0.3.1...v0.3.2

    Source code(tar.gz)
    Source code(zip)
  • v0.3.1(Jan 14, 2022)

    What's Changed

    • fix mypy type hints errors by @JeroenDelcour in https://github.com/JeroenDelcour/tplot/pull/10
    • Code coverage monitoring by @JeroenDelcour in https://github.com/JeroenDelcour/tplot/pull/12
    • Memory leak fix by @JeroenDelcour in https://github.com/JeroenDelcour/tplot/pull/18
    • add pre-commit checks for code quality by @JeroenDelcour in https://github.com/JeroenDelcour/tplot/pull/19

    Full Changelog: https://github.com/JeroenDelcour/tplot/compare/v0.3.0...v0.3.1

    Source code(tar.gz)
    Source code(zip)
  • v0.3.0(Jan 12, 2022)

    What's Changed

    • Switch to mkdocs, switch to pytest, automatic x axis tick label placement, more extensive documentation by @JeroenDelcour in https://github.com/JeroenDelcour/tplot/pull/8
    • update readme with new docs, add readthedocs and pypi badges by @JeroenDelcour in https://github.com/JeroenDelcour/tplot/pull/9

    Full Changelog: https://github.com/JeroenDelcour/tplot/compare/v0.2.0...v0.3.0

    Source code(tar.gz)
    Source code(zip)
  • v0.2.0(Jan 12, 2022)

    What's Changed

    • Braille by @JeroenDelcour in https://github.com/JeroenDelcour/tplot/pull/4

    Full Changelog: https://github.com/JeroenDelcour/tplot/compare/v0.1.0...v0.2.0

    Source code(tar.gz)
    Source code(zip)
  • v0.1.0(Jan 12, 2022)

Owner
Jeroen Delcour
Jeroen Delcour
Runs a command in P4wnP1 and displays the output on OLED screen (SH1106)

p4wnp1-oled-terminal Runs a command in P4wnP1 and displays the output on OLED screen (SH1106) Works on Raspberry Pi Zero 2 W Tested successfully on RP

PawnSolo 1 Dec 14, 2021
An ZFS administration tool inspired on Midnight commander

ZC - ZFS Commander An ZFS administration tool inspired on Midnight commander Work in Progress Description ZFS Commander is a simple front-end for the

34 Dec 07, 2022
CLI utility to search and download torrents from major torrent sites

CLI Torrent Downloader About CLI Torrent Downloader provides convenient and quick way to search torrent magnet links (and to run associated torrent cl

x0r0x 86 Dec 19, 2022
Calculator for CLI. Made with Python

Calculator for CLI. Made with Python

Brandon Arreguin 2 Jan 07, 2022
Fast as FUCK nvim completion. SQLite, concurrent scheduler, hundreds of hours of optimization.

Fast as FUCK nvim completion. SQLite, concurrent scheduler, hundreds of hours of optimization.

i love my dog 2.8k Jan 05, 2023
dotfilery, configuration, environment settings, automation, etc.

┌┬┐┌─┐┌─┐┌─┐┬ ┬┌┬┐┬ ┬┬┌─┐ │││├┤ │ ┬├─┤│ │ │ ├─┤││ :: bits & bobs, dots & things. ┴ ┴└─┘└─┘┴ ┴┴─┘┴ ┴ ┴ ┴┴└─┘ @megalithic 🚀 Instal

Seth Messer 89 Dec 25, 2022
A simple command line virtual operating system, written in python

Virtual operating system A simple virtual operating system written in python. (Under development). Currently, the following commands are supported: Co

B.Jothin kumar 7 Nov 15, 2022
Fetch is use to get information about anything on the shell using Wikipedia.

Fetch Search wikipedia article on command line [Why This?] [Support the Project] [Installation] [Configuration] Why this? Fetch helps you to quickly l

Yash Singh 340 Dec 18, 2022
GoogleFormSpammer - A simple CLI script to spam Google Forms used by Crypto Wallet scammers to collect stolen data

GoogleFormSpammer - A simple CLI script to spam Google Forms used by Crypto Wallet scammers to collect stolen data

14 Dec 17, 2022
A command-line based, minimal torrent streaming client made using Python and Webtorrent-cli. Stream your favorite shows straight from the command line.

A command-line based, minimal torrent streaming client made using Python and Webtorrent-cli. Installation pip install -r requirements.txt It use

Jonardon Hazarika 17 Dec 11, 2022
moviepy-cli: Command line interface for MoviePy.

Moviepy-cli is designed to apply several video editing in a single command with Moviepy as an alternative to Video-cli.

Kentaro Wada 23 Jun 29, 2022
A simple command line tool written in python to manage a to-do list

A simple command line tool written in python to manage a to-do list Dependencies: python Commands: todolist (-a | --add) [(-p | --priority)] [(-l | --

edwloef 0 Nov 02, 2021
A cd command that learns - easily navigate directories from the command line

NAME autojump - a faster way to navigate your filesystem DESCRIPTION autojump is a faster way to navigate your filesystem. It works by maintaining a d

William Ting 14.5k Jan 03, 2023
A terminal spreadsheet multitool for discovering and arranging data

VisiData v2.6.1 A terminal interface for exploring and arranging tabular data. VisiData supports tsv, csv, sqlite, json, xlsx (Excel), hdf5, and many

Saul Pwanson 6.2k Jan 04, 2023
spade is the next-generation networking command line tool.

spade is the next-generation networking command line tool. Say goodbye to the likes of dig, ping and traceroute with more accessible, more informative and prettier output.

Vivaan Verma 5 Jan 28, 2022
A Command Line Calculator With Python

CalculadoraPY Usando no Termux apt install python3 apt install git pip3 install termcolor git clone https://github.com/kayke981/CalculadoraPY.git

kayake 5 Jan 30, 2022
A supercharged AWS command line interface (CLI).

SAWS Motivation AWS CLI Although the AWS CLI is a great resource to manage your AWS-powered services, it's tough to remember usage of: 70+ top-level c

Donne Martin 5.1k Jan 05, 2023
A simple CLI based any Download Tool, that find files and let you stream or download thorugh WebTorrent CLI or Aria or any command tool

Privateer A simple CLI based any Download Tool, that find files and let you stream or download thorugh WebTorrent CLI or Aria or any command tool How

Shreyash Chavan 2 Apr 04, 2022
A command line tool to query source code from your current Python env

wxc wxc (pronounced "which") allows you to inspect source code in your Python environment from the command line. It is based on the inspect module fro

Clément Robert 13 Nov 08, 2022
Darkdump - Search The Deep Web Straight From Your Terminal

Darkdump - Search The Deep Web Straight From Your Terminal About Darkdump Darkdump is a simple script written in Python3.9 in which it allows users to

Josh Schiavone 264 Dec 30, 2022