{"id":48119617,"url":"https://github.com/bartman/blot","last_synced_at":"2026-04-04T16:18:25.070Z","repository":{"id":66448882,"uuid":"412092561","full_name":"bartman/blot","owner":"bartman","description":"📈 console graphing / plotting library written in C","archived":false,"fork":false,"pushed_at":"2026-02-17T03:43:51.000Z","size":357,"stargazers_count":5,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-02-17T08:47:10.941Z","etag":null,"topics":["c","console","graph","plot","plotting","text","visualization"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-2.1","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bartman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-09-30T14:14:26.000Z","updated_at":"2026-02-17T03:43:55.000Z","dependencies_parsed_at":"2024-02-19T15:29:00.768Z","dependency_job_id":"9545bd66-da68-4b8b-8a9a-c28c38ff5ec2","html_url":"https://github.com/bartman/blot","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/bartman/blot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bartman%2Fblot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bartman%2Fblot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bartman%2Fblot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bartman%2Fblot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bartman","download_url":"https://codeload.github.com/bartman/blot/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bartman%2Fblot/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31405700,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T10:20:44.708Z","status":"ssl_error","status_checked_at":"2026-04-04T10:20:06.846Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","console","graph","plot","plotting","text","visualization"],"created_at":"2026-04-04T16:18:22.545Z","updated_at":"2026-04-04T16:18:24.994Z","avatar_url":"https://github.com/bartman.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# blot\n\nBlot is a plotting library written in C, that plots data onto a string buffer.\n\nThat's right, there are no images, just text -- see examples below.\n\nThere is a C++ wrapper provided, as well as a CLI tool.\n\nSite: [bartman.github.io/blot](https://bartman.github.io/blot/)\n\nGitHub: [github.com/bartman/blot](https://github.com/bartman/blot/)\n\nCopyright © 2021-2025 Bart Trojanowski\n\nLicensed under LGPL v2.1, or any later version.\n\n\n## Noteworthy features\n\n  * plots to the console as text (by calling `puts()`/`printf()`)\n  * very very fast (compared to python alternatives)\n  * very very memory usage friendly\n  * can plot multiple datasets on one canvas\n  * uses familiar figure based API (similar to existing python plotting frameworks)\n  * supports braille plotting (like [plotille](https://github.com/tammoippen/plotille))\n  * data arrays can be provided in various types (`int16`, `int32`, `int64`, `double`, or `float`)\n  * there is a C++ wrapper, with limited features, for convenience\n  * there is a CLI tool that can plot from files or using output of commands\n\n## Prerequisites\n\n`blot` is developed on NixOS and Debian, and CI tested on Debian and Ubuntu.\nIt is built using standard tools. The dependency script will install the\nrequired packages if you're on a Debian-based distro.\n\n    ./dependencies.sh\n\nPackages that `blot` needs: `make` `ninja` `cmake` `glib2` `googletest`.\n\n## Building\n\n`blot` is built using `cmake` and `ninja`.  There is a top level `Makefile` only to\nsimplify the build process (it invokes `cmake` in the `build` subdirectory).\n\n    make\n\nYou can build debug (with `ASAN`) using\n\n    make TYPE=Debug\n\nRun `make help` for a full list.\n\n## blot CLI\n\nThe easiest say to use `blot` is to use the CLI, which is able to read from files\nor launch programs, then plot the numbers it finds.\n\nSee the online help for a full list of features...\n\u003cdetails markdown=\"1\"\u003e\n\u003csummary\u003e ❯ blot --help \u003c/summary\u003e\n\n```sh\nSYNOPSIS\n    blot [-h] [-V]\n    blot [-v] [--debug] [--timing] [-i \u003csec\u003e] [-A|-U|-B] ((scatter|line|bar)\n         ([-R \u003cfile\u003e] | [-F \u003cfile\u003e] | [-P \u003cfile\u003e] | [-X \u003ccmd\u003e] | [-W \u003ccmd\u003e])\n         [-p \u003cy-pos|x-pos,y-pos\u003e] [-r \u003cregex\u003e] [-l \u003ccount\u003e] [-c \u003ccolor\u003e] [-i \u003csec\u003e])...\n\nOPTIONS\n    -h, --help                  This help\n    -V, --version               Version\n\n    Run modifiers:\n        -v, --verbose           Enable verbose output\n        --debug                 Enable debug output\n        --timing                Show timing statitiscs\n        -i, --interval \u003csec\u003e    Display interval in seconds\n\n    Output:\n        -A, --ascii             ASCII output\n        -U, --unicode           Unicode output\n        -B, --braille           Braille output\n\n    Plot type:\n        scatter                 Add a scatter plot\n        line                    Add a line/curve plot\n        bar                     Add a bar plot\n\n    Plot data source:\n        -R, --read \u003cfile\u003e       Read file to the end, each line is a record\n        -F, --follow \u003cfile\u003e     Read file waiting for more, each line is a record\n        -P, --poll \u003cfile\u003e       Read file at interval, each read is one record\n        -X, --exec \u003ccmd\u003e        Run command, each line is a record\n        -W, --watch \u003ccmd\u003e       Run command at interval, each read is one record\n\n    Data source parsing:\n        -p, --position \u003cy-pos|x-pos,y-pos\u003e\n                                Find numbers in input line, pick 1 or 2 positions for X and Y values\n\n        -r, --regex \u003cregex\u003e     Regex to match numbers from input line\n        -l, --limit \u003ccount\u003e     How many historical values to retain for plotting\n\n    Plot modifiers:\n        -c, --color \u003ccolor\u003e     Set plot color (1..255)\n        -i, --interval \u003csec\u003e    Set sampling interval in seconds\n\nEXAMPLES\n\n    blot --braille \\\n        line    --color 10 --read x_y1_values -p 1,2 \\\n        scatter --color 11 --read x_y2_values -p 1,2\n\n    blot --braille \\\n        scatter --color 11 --read y_values \\\n        line    --color 10 --exec 'seq 1 100'\n\n    blot --braille \\\n        line --poll /proc/loadavg --position 1 \\\n        line --poll /proc/loadavg --position 2 \\\n        line --poll /proc/loadavg --position 3\n```\n\u003c/details\u003e\n\nFirst, pick a plotting mode, there are 3 choices: `scatter`, `line`, and `bar`.\nMultiple plots can be overlayed.\n\nEach plot needs to get data from a file or process, and there are 5 options:\n- `--read \u003cfile\u003e` to read lines data from a file, stop at the end.\n- `--follow \u003cfile\u003e` to read lines data from a file, but wait for more data (`Ctrl-C` to stop).\n- `--poll \u003cfile\u003e` to poll a file (like `/sys` or `/proc` files), at some interval, and plot the results.\n- `--exec \u003ccmd\u003e` to run a program that will give us data to plot on successive lines.\n- `--watch \u003ccmd\u003e` to run a program that outputs one number per execution, which will be accumulate and plotted.\n\nLet's look at some examples.\n\n### plot numbers from a file (read file mode)\n\nLet's say we have a file that contains some X,Y pairs...\n```\n0 10\n1 25\n2 0\n3 40\n4 55\n```\n\nWe can plot this using...\n\n```sh\n❯ blot bar --read mydata --position 1,2\n```\nThe values 1 and 2 are positions in each line where `blot` will find the X,Y coordinates.\n\n![blot bar --read](images/blot-bar-read.png)\n\n### plot numbers from a log file (follow file mode)\n\nLet's say that we have a log file, with some magnitude values.\nLet's just make something up with a script...\n```sh\n#!/usr/bin/env bash\nwhile true ; do\n    echo $RANDOM\n    sleep 1\ndone \u003e mydata\n```\nWhile the above is running, we can plot the data being generated...\n```sh\n❯ blot line --follow mydata\n```\nThe file contains only one number per line, and `blot` will use the line number as the Y coordinate.\n![blot line --follow](images/blot-line-follow.png)\n\nPlot will update continuously, until `Ctrl-C` is used to stop.\n\n### plot the system load (poll file mode)\n\nRecall that `/proc/loadavg` has 3 load values (1,5,15 minutes).  We can plot them...\n\n```sh\n❯ blot line --poll /proc/loadavg --position 1 --interval 0.5 \\\n       line --poll /proc/loadavg --position 2 \\\n       line --poll /proc/loadavg --position 3\n```\n![blot line --poll](images/blot-line-poll.png)\n\n### plot temperature over time\n\nHere is a script I use to plot the highest 7 temperatures in the system:\n\n```sh\nINPUTS=( $( grep . /sys/class/hwmon/hwmon*/temp*_input | sort -t : -k 2 -n -r | head -n 7 | cut -d : -f 1 ) )\nblot --timing --braille $( for f in \"${INPUTS[@]}\" ; do echo \"line --poll $f --interval 0.5 --limit 1000\" ; done )\n```\n\n![blot scatter --exec](images/blot-temp.png )\n\n\n### read X,Y from command line (exec mode)\n\nHere is a cool way to test your random number generator, generate two consecutive numbers and plot them against one another.\n\n```sh\n❯ blot scatter --exec 'for ((x=0;x\u003c10000000;x++)) ; do echo $RANDOM $RANDOM ; done' --position 1,2\n```\n![blot scatter --exec](images/blot-scatter-exec.png)\n\n### plot power draw of a GPU (watch mode)\n\nThe Nvidia graphics tools provide a system management interface CLI, named `nvidia-smi`.\nIf we wanted to plot the average power draw, then we could do this...\n\n```sh\nblot --timing line --watch 'nvidia-smi --id=0 -q | grep -m1 \"Average Power Draw\"' --interval 0.1\n```\n![blot scatter --watch](images/plot-line-watch.png)\n\n## Source code examples\n\n`blot` is being used in other projects as a library, and it comes with many\nexamples for the C and C++ usage.\n\nGenerated from [simple.c](examples/c/c-simple.c) (see also [simple.cpp](examples/cpp/cpp-simple.cpp) for C++ wrapper usage)\n\n    ./build/examples/c/c-simple\n\n![simple example](images/simple.png)\n\nGenerated from [trig.c](examples/c/c-trig.c) (see also [trig.cpp](examples/cpp/cpp-trig.cpp) for C++ wrapper usage)\n\n    ./build/examples/c/c-trig\n\n![trig example](images/trig.png)\n\n\n\n## Missing features\n\n  * different plotting modes like histograms (currently only plots line/scatter/bar)\n  * improve axis line and numbering (currently not very accurate)\n  * add axis labels and minor ticks (configurable)\n  * draw origin lines and minor tick lines (configurable)\n  * better 256 colour support\n\n### Ideas:\n\nAllow for swapping data from layer to allow for even faster plotting (allow `blot` to reuse existing allocated structures)\n  1. create a figure\n  2. all `blot_figure_scatter` multiple times, have it return the `blot_layer`\n  3. call `blot_figure_render` and `blot_screen_get_text`\n  4. then use `blot_layer_new_data` to swap the data\n  5. repeat from step (3)\n\n## Similar projects\n\n  * [plotille](https://github.com/tammoippen/plotille) - Python, \"plot, scatter plots and histograms in the terminal using braille dots\"\n  * [Tables-and-Graphs](https://github.com/tdulcet/Tables-and-Graphs) - \"C++ Console Table and Graph/Plot Libraries\"\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbartman%2Fblot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbartman%2Fblot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbartman%2Fblot/lists"}