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
WebApp Maker make web apps (Duh). It is open source and make with python and shell.

WebApp Maker make web apps (Duh). It is open source and make with python and shell. This app can take any website and turn it into an app. I highly recommend turning these few websites into webapps:

2 Jan 09, 2022
This is a Command Line program to interact with your NFTs, Cryptocurrencies etc

This is a Command Line program to interact with your NFTs, Cryptocurrencies etc. via the ThirdWeb Platform. This is just a fun little project that I made to be able to connect to blockchains and Web3

Arpan Pandey 5 Oct 02, 2022
A small system that allow you to manage hosts stored in your .ssh/config file

A small system that allow you to manage hosts stored in your .ssh/config using simple commands.

Simone Ostini 1 Jan 24, 2022
A Python3 rewrite of my original PwnedConsole project from almost a decade ago

PwnedConsoleX A CLI shell for performing queries against the HaveIBeenPwned? API to gather breach information for user-supplied email addresses. | wri

1 Jul 23, 2022
WA Terminal is a CLI application that allows us to login and send message with WhatsApp with a single command.

WA Terminal is a CLI application that allows us to login and send message with WhatsApp with a single command.

Aziz Fikri 15 Apr 15, 2022
swarmexec executes command in swarm service

Swarmexec swarmexec executes command in swarm service Install pip install git+https://github.com/filimon43g/swarmexec.git Config In swarm_config.ini

Phil 2 Nov 23, 2021
An awesome Python wrapper for an awesome Docker CLI!

An awesome Python wrapper for an awesome Docker CLI!

Gabriel de Marmiesse 303 Jan 03, 2023
Terminal epub reader with inline images

nuber Inspired by epy, nuber is an Epub terminal reader with inline images written with Rust and Python using Überzug. Features Display images in term

Moshe Sherman 73 Oct 12, 2022
gget is a free and open-source command-line tool and Python package that enables efficient querying of genomic databases.

gget is a free and open-source command-line tool and Python package that enables efficient querying of genomic databases. gget consists of a collection of separate but interoperable modules, each des

Pachter Lab 570 Dec 29, 2022
An open source terminal project made in python

Calamity-Terminal An open source terminal project made in python. Calamity Terminal is a free and open source lightweight terminal. Its made 100% off

1 Mar 08, 2022
Dark powered asynchronous completion framework for neovim/Vim8

deoplete.nvim Dark powered asynchronous completion framework for neovim/Vim8 Note: The development of this plugin is finished. Accepts minor patches a

Shougo 5.9k Dec 30, 2022
🎄 Advent of Code command-line tool.

🎄 advent-cli advent-cli is a command-line tool for interacting with Advent of Code, specifically geared toward writing solutions in Python. It can be

Christian Ferguson 6 Dec 01, 2022
CLI para o projeto Compilado (Newsletter e Podcast do Código Fonte TV)

Compilado CLI Automatização de tarefas através de linha de comando para a geração de assets para episódios do Compilado, a newsletter e podcast do can

Gabriel Froes 18 Nov 21, 2022
A simple yet powerful timer and time tracker from the command line.

Focus Phase Focus Phase (FP) is a simple yet powerful timer and time tracker. It is a command-line application written in Python and can be installed

Ammar Alyousfi 13 Jan 13, 2022
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
QueraToCSV is a simple python CLI project to convert the Quera results file into CSV files.

Quera is an Iranian Learning management system (LMS) that has an online judge for programming languages. Some Iranian universities use it to automate the evaluation of programming assignments.

Amirmahdi Namjoo 16 Nov 11, 2022
💥 Share files easily over your local network from the terminal!

Fileshare 📨 Share files easily over your local network from the terminal! 📨 Installation # clone the repo $ git clone https://github.com/dopevog/fil

Dopevog 11 Sep 10, 2021
🌍 Harness the power of whatsmydns from the command-line.

chkdns Harness the power of whatsmydns from the command-line. Installing with pip pip install chkdns Run chkdns --host github.com Alternatively you ca

Craig Gumbley 3 Oct 29, 2022
Quo is a Python based toolkit for writing Command-Line Interface(CLI) applications.

Quo is a Python based toolkit for writing Command-Line Interface(CLI) applications. Quo is making headway towards composing speedy and orderly CLI applications while forestalling any disappointments

Secretum Inc. 16 Oct 15, 2022
Command line parser for common log format (Nginx default).

Command line parser for common log format (Nginx default).

Lucian Marin 138 Dec 19, 2022