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
A CLI tool to disable and enable security standards controls in AWS Security Hub

Security Hub Controls CLI A CLI tool to disable and enable security standards controls in AWS Security Hub. It is designed to work together with AWS S

AWS Samples 4 Nov 14, 2022
liquidctl – liquid cooler control Cross-platform tool and drivers for liquid coolers and other devices

Cross-platform CLI and Python drivers for AIO liquid coolers and other devices

1.7k Jan 08, 2023
The WalletsNet CLI helps you connect to WalletsNet

WalletsNet CLI The WalletsNet CLI helps you connect to WalletsNet. With the CLI, you can: Trigger webhook events or resend events for easy testing Tai

WalletsClub 8 Dec 22, 2021
Textual: a TUI (Text User Interface) framework for Python inspired by modern web development

Textual Textual is a TUI (Text User Interface) framework for Python inspired by

17.1k Jan 04, 2023
Simple CLI for managing Postgres databases in Flask.

Overview Simple CLI that provides the following commands: flask psql create flask psql init flask psql drop flask psql setup: create → init flask psql

Daniel Reeves 21 Oct 03, 2022
GDBIGtools: A command line tools for GDBIG varaints browser

GDBIGtools: A command line tools for GDBIG varaints browser Introduction Born in Guangzhou Cohort Study Genome Research Database is based on thousands

广州市出生队列基因组学研究(The genomics study of BIGCS) 7 Sep 14, 2022
A Python script for finding a food-truck based on latitude and longitude coordinates that you can run in your shell

Food Truck Finder Project Description This repository contains a Python script for finding a food-truck based on latitude and longitude coordinates th

1 Jan 22, 2022
Pequeno joguinho pra você rodar no seu terminal

JokenPython Pequeno joguinho pra você rodar no seu terminal Olá! Joguinho legal pra vc rodar no seu terminal!! (rode no terminal, pra melhor experienc

Scott 4 Nov 25, 2021
Chopper: An Automated Security Headers Analyzer

____ _ _ / ___| |__ ___ _ __ _ __ ___ _ __| | | | | '_ \ / _ \| '_ \| '_ \ / _ \ '__| | | |___| | | | (_) |

Kamran Saifullah (Frog Man) 2 Nov 27, 2022
A CLI tool that scans through a directory and organizes all loose files into folders by file type.

Organizer CLI Organizer CLI is a python command line tool that goes through a given directory and organizes all un-folder bound files into folders by

Mulaza Jacinto 6 Dec 14, 2022
A fantasy life simulator and role-playing game hybrid distributed as CLI, written in Python 3.

Life is Fantasy Epic (LIFE) A fantasy life simulator and role-playing game hybrid distributed as CLI, written in Python 3. This repository will be pro

Pawitchaya Chaloeijanya 2 Oct 24, 2021
Wordle-cli - Command-line clone of Josh Wardle's WORDLE

Command-line clone of Josh Wardle's WORDLE, inspired by Paul Battley's Ruby vers

Klipspringer 32 Jan 03, 2023
A Tempmail Tool for Terminal and Termux.

A Tempmail Tool for Terminal and Termux.

MAO-COMMUNITY 8 Oct 19, 2022
Python API and CLI for the ikea IDÅSEN desk.

idasen This is a heavily modified fork of rhyst/idasen-controller. The IDÅSEN is an electric sitting standing desk with a Linak controller sold by ike

Alex 79 Dec 14, 2022
Official AIdea command line tool

AIdea CLI Official AIdea command line tool for https://aidea-web.tw. Installation Make sure you have installed both Python 3 and pip package manager.

AIdea 5 Dec 15, 2021
Spotify Offline is a command line tool that allows one to download Spotify playlists in MP3 format.

Spotify Offline v0.0.2 listen to your favorite spotify songs, offline Overview Spotify Offline (spotifyoffline) is a command line tool that allows one

Aarush Gupta 1 Nov 28, 2021
CLI tool to develop StarkNet projects written in Cairo

⛵ Nile Navigate your StarkNet projects written in Cairo. Installation pip install cairo-nile Usage Install Cairo Use nile to install a given version o

Martín Triay 305 Dec 30, 2022
Get latest astronomy job and rumor news in your command line

astrojobs Tired of checking the AAS job register and astro rumor mill for job news? Get the latest updates in the command line! astrojobs automaticall

Philip Mocz 19 Jul 20, 2022
Several tools that can be added to your `PATH` to make your life easier.

CK-CLI Tools Several tools that can be added to your PATH to make your life easier. prettypath Prints the $PATH variable in a human-readable way. It a

Christopher Kumm 2 Apr 21, 2022
command line tool for frequent nmigen tasks (generate sources, show design)

nmigen-tool command line tool for frequent nmigen tasks (generate sources, show design) Usage: generate verilog: nmigen generate verilog nmigen_librar

Hans Baier 8 Nov 27, 2022