There is, as one might expect, quite a long history of such tools, since text-only interfaces were the norm in the olden days.
When I was a young one doing physics in the '80s, we used CERN's HBOOK[1] to do all our (statistical) plotting. Recently while working on a Common Lisp project I had a use for something similar, remembered HBOOK, and "rolled my own"[2] (much simpler version).
Yes, a nice clean graph in a GUI or PDF is cleaner, but if you're working at the terminal already or in a REPL, it can be nice to just see the output there.
At the risk of downvotes: I do wish this particular project didn't require a working Ruby / Gem installation -- nothing against Ruby, but I'd be curious if there was an equivalent stand-alone executable written in Go or similar... something like [3]?
You're not, the only exception I make is for one Python tool, think it was called termgraph, because it's very good. All others I want to be in C/C++, Golang or Rust.
Yeah, in an effort to spur adoption, I built (shameless plug) https://www.arewesixelyet.com/. What’s interesting is that if VTE gets support, a lot of other terminals will, since they depend on it.
This is astoundingly great - thank you for linking!
(The expected use case - generating quick plots on a remote machine; I usually just scp them back, but with this, and the new-to-me matplotlib integration, i can just have them show up in the terminal without having to launch a notebook or fight with X). Well supported by iterm2 on mac as the terminal side.
https://st.suckless.org/ used to have a circa st-0.8 fork that supported full color sixel graphics, but it seems that specific patch is not in the official list anymore. [1] I think the work moved to https://github.com/jhhuh.
You can even compose the gnuplots with the scrollback patch to scroll back in your gnuplots. I use this all the time. In fact, I just have GNUTERM="sixelgd enhanced linewidth 3 fontscale 2 size 1600,900 truecolor" in my environment variables.
Combined with shell history (or gnuplot history) this makes for a rudimentary "notebook"-like interface, but with a log instead of a file to record state.
You could also use the techniques of [1] but use `set term png` and `set output "/tmp/pl.png"` instead and then auto-launch any image viewer on "/tmp/pl.png" instead of relying on terminal graphics at all.
Is gnuplot better for the use cases demonstrated on the page here?
I've always avoided gnuplot because it has looked pretty hard to get anything useful out of. But uplot looks much more approachable. Just piping some data to "uplot hist --nbins 20" is something I'll remember.
Within the gnuplot shell you use `<` at the start of a "filename" like
gnuplot> plot '<pipeline'
It just uses system(3) for "pipeline". So, technically you could have a whole script in there with maybe tricky gnuplot-quoting/escaping of shell stuff.
You do have 2 different history logs this way - the shell one and the plot one while the uplot way is integrated.
If you really want integrated, you could drive gnuplot with temp files, though each shell command-line would probably have to pass a lot of controls. E.g.,
#!/bin/sh
cat > /tmp/dat # should use mktemp -d
cat > /tmp/p.gpi <<-EOF
plot '/tmp/dat' $*
EOF
gnuplot /tmp/p.gpi
and then
$ seq 1 10 | gpl with lines
It is an exercise for the reader (well, it has probably been done N times...) to harden the temp paths, clean up afterward, generalize to source user/maybe per-directory `foo.gpi` setup and so on.
In the unlikely event temp space is actually any sort of issue then you might be able to use mkfifo (I've never tried) or else generate a .gpi script that uses the plot '<string' syntax escaping `string`.
Oh, that goes to show you how little I use it. I read the documentation and merely assumed that it would work for stdin, but gnuplot exits with an error in that case. This will work, but it’s pretty funky:
This worked directly in Konsole for me without "xterm -ti 340" and it renders a high res image, which surprised me: I have used low-res images in the terminal using block characters and 24-bit colors before, but never seen this high res
How does it do this?
One weird thing seems to be that it doesn't support zooming in/out the same way the regular text does.
No, for the VT340 they devised a set of escape sequences for encoding bitmaps called Sixels; each character encodes a vertical stripe of six pixels. They used it both for displaying graphics and printing. They also did a vector graphics system called ReGIS a few years earlier.
someone please enlighten me, why can xterm do this cool drawing while the modern gnome-terminal can not, I tested the GPU oriented kitty that can display images in terminal, but it could not run gnuplot as xterm. what're missing?
XTerm implements an old bitmap protocol invented in the 80s. The author of Kitty rightly points out that it’s inefficient, limited to one color per column of 6 pixels (if you want a second color you can go back to the start of the line and print over). Rather than implement support for the Sixel protocol, the author of Kitty choose to implement something modern. It’s actually rather nice; the program can print out a filename for Kitty to load, or even point to a shared memory buffer. Those are very efficient options, provided your program is running on your local machine.
Meanwhile Gnuplot supports a wide variety of “terminals”, many of which are just outputs to files of various types, some of which are GUIs, others of which are for actual terminals, like “dumb” (ordinary printable characters), “tek40” and “xterm” which use a protocol invented for Tektronix terminals, “sixelgd” which uses the sixel protocol from the VT340, half a dozen types of printers, etc.
But nobody has added one for the Kitty protocol, so it doesn’t work there. The downsides of inventing something new I suppose; the existing software doesn’t automatically support it, someone has to go around and add that support.
The second link points to libvte, which is the terminal engine behind gnome-terminal where the actual terminalling happens. The changes to gnome-terminal itself are mostly translations and uninteresting desktop stuff:
It certainly can. Since more than 20 years ago! I remember that in 2003, as a "little kid", I changed my configuration from latin-15 to utf8 and it was already supported.
Would love to see something like this built into tqdm[0]. Being able to attach a graph to the output would be a fantastic complement to postfixing the progress bar with current numbers.
The weakest part about distributing these tools in Ruby for me has been rbenv wiping them away on switches. I rarely switch Ruby versions these days, but this used to be pain all of the time
So many times I've wanted a quick histogram of a list of values to get a feel for their distribution, but it's always felt like it's too much effort with the tools that I had available to me. This is perfect for it! Would be nice to be able to specify the bin size or clamp the values to a range, but that can be done with other tools in the pipeline.
You have been able to draw plots from proper graphing libraries using actual images for years in terminals that support the kitty graphics protocol. See
I'm pretty sure I've seen such a thing (my first reaction was to check if this was the same thing I'd seen before and it wasn't), but I'm forgetting what language it was for. Given my work and interests it probably was R, but might have been Julia, Python, or Ocaml.
This is so cool. It reminds me of Markdown and Mermaid (https://github.com/mermaid-js/mermaid), which can do a similar thing within a plain text file. Keep it up; looking forward to trying it out.
This will be the most hideous comment I've ever made on the internet.
I would die for something like this to be an emacs package, to be written in elisp. I do all my development and data processing in emacs on remote clusters and it is insanely efficient and quick to iterate. The only thing that slows me down is getting and making plots. I can, of course, but I still mount the drive and transfer plots as compressed images. Which is horrifically inefficient for doing very quick rapid iterations on the processing of data....
Of course, the effort to duplicate the functionality of this in elisp that properly displays in the emacs TUI would be herculean. But there's no way I can install ruby on my remote clusters :(
Not sure if this is what you want, but you can pipe emacs regions into shell commands, which interoperates nicely with lots of stuff. I routinely hit M-| to make plots with feedgnuplot. Works great
Ok, yeah. I had no clue that was a thing. That will be extremely useful. I'm often running python in a buffer and being able to run commands on output is a dream. Thanks dima55 and thank you emacs.
what's the point in all these terminal programs posted here every day? why would i ever draw stuff with text when it's just going to be converted back to pixels by the OS anyway? there's clearly a bigger reason than just being able to do stuff without the slow desktop environment. but what is it?
> there's clearly a bigger reason than just being able to do stuff without the slow desktop environment. but what is it?
For me, it’s visualisation of data on a remote HPC cluster. Shuffling data back and forth is dangerous because then everything is duplicated and you never know where the latest version is. SSH tunnels and remote X sessions are finicky and in several contexts blocked intentionally or not. Sixels are perfect: the plots are accurate enough to actually see what’s going on, nothing is moved around, and it works with a wobbly VPN server over some dodgy wifi (or 3G).
totally, and most significantly: without having to shuffle a table off to another app to then be graphed. I definitely see high value in this for when you are doing adhoc analysis of some data (such as logs) and want to see the items which stand out. It's easier to recognize some patterns visually for sure. sort/uniq -c/awk are great, but when measuring things relative to other things, visualizations are powerful for humans.
Aside from the convenience of having the output exactly where you're issuing commands, and the ability to copy-paste the output into text documents (admittedly not without its rough spots), I frequently find unexpected uses for things like grep, sort, uniq, etc. - standard unix tools at the command line, even for supposedly purely visual output.
As an example, for the last chart shown:
cat gencode.v35.annotation.gff3 \
| grep -v '#' | grep 'gene' | cut -f1 \
| uplot count -t "The number of human gene annotations per chromosome" -c blue
| sort
gives an alphabetical ordering, rather than by descending count. Or you could search only for a single row of interest, or filter out duplicates, or ....
I feel like an in-terminal plotting tool would be a great fit for nushell (https://www.nushell.sh), because they already have the philosophy that tools where possible should return structured data rather than just text.
This is great (as is seeing all the other links in this thread for other variations). Makes me want to make a rpi dashboard for a retro "ops view" instead of the fancy/pretty graphs in APM tools.
Not saying I'd give those up, but would just a nice lil desktop ornament :)
gnome-terminal really need to support kitty like features, that is, draw images and plots directly inside the terminal, xterm can do that, konsole is adding them, gnome-terminal please add the support so I do not need switch to kitty(which is OK, but)
I remember trying to display graphics on a VT100 type terminal over a modem. It took forever to render on screen (you could see individual lines being drawn one by one).
Great! I like the idea of the depth limit as well as how you inlined part of the quadratic equation, I'd like to have a flag/switch for something like that too, e.g. maybe print out the condition part of a while statement inline.
As for DAG's. I'm trying to pick up a semi-abandoned side project, in it there's this 50% complete (& buggy) function to turn basic-blocks into DAG's for analysis. Once I get it work, it'd be nice to have some better way to visualize its output than just printing out a list of labels & edges.
PS: LOL!! Good for your friend, hopefully still going strong :)
I'll just say that I'm in my 50's and things are starting to get interesting. Then again there's Gene Dykes (The ultrageezer, https://twitter.com/theultrageezer) there's hope... Have no wish to become as fast as he is, as long as I can keep running ;)
For DAGs, I'm guessing it's better to use some sort of let/where notation, because doing the APL/Lisp Reader thing of naming a defining use and then referring to it elsewhere involves an arbitrary choice of which instance to use as the def'n.
although there's still an arbitrary decision to make as to how to order references when there's more than one dup, so maybe picking an encounter order as in the latter is as good as it gets?
Good one, should stay pretty readable for non-trivial graphs. And I agree, as-found-on-traversal ordering is likely as good as any other.
I guess the Dream DAG would be some sort interactive zoom&click to expand thing, probably beyond my use case (and certainly beyond my console programming knowledge!)
Anyways, as a user of the three, I find that the main advantage of gnuplot is that you can do simpler plots more easily than with the others, as there's often no boilerplate needed. I don't mean, "almost no boilerplate"; I actually mean zero boilerplate. The complete gnuplot program
plot sin(x)
is difficult to beat. However, even if you can do everything that you want with gnuplot, some complex plots may become a bit unwieldy to describe.
Regarding quality, I guess this concerns mainly the default settings. The answer depends entirely on your tastes. In my case I find the matlab defaults of a very good quality, followed by those of gnuplot. I don't like the default settings of plotly and matplotlib.
Thanks! Yes, a bit off topic, but it was the closest post in which to ask this question that I had.
I have used all three. GnuPlot is clearly fastest, but the documentation and community help are limited.
It seems not very flexible either.PGFPlots beats them all IMHO!
I tend to think most of the Gnu software is in decline.
I do like CLI apps, but due to the non-standard state of GUI development we reach for very inefficient hacks to display basically pixel data in a fundamentally text-based medium. I would much prefer well-integrated actual GUIs using more than 100x100 pixels.
Edit: I don’t really have a problem with this specific program. My point is more general in that we perhaps have the wrong abstraction level for our GUI programs. Those should be standardized and cross platform as well besides supporting remote access .
Terminals use a standardized protocol and enable cross-platform applications with minimal code and runtime footprint, which also work remotely via ssh.
I really would like to see a proper and universally supported pixel framebuffer standard for terminals though (sixels don't really cut it).
This is true if you want to output ascii and mostly true for ANSI colours but otherwise I think this is very false. To point out some of the ways that it is false:
- different terminal (emulators) support different abilities
- those abilities are controlled with different control codes
- there isn’t much of a standard. There are some de-facto standards for advanced features from whichever terminal emulator first implemented them but there is a lack of bug-for-bug compatibility
- Unicode, character widths, rtl, etc. Unicode matters for things like this plotting program. What happens if you draw a double-width character? And then position your cursor ‘half-way’ through it?
- there is terminfo but it works in a janky way and you can get all sorts of problems if eg the remote box doesn’t have your terminal (or all it’s new features) in the terminfo file. To some extent you can copy over terminfo files but that doesn’t sound much like ‘standardized protocol’ or ‘cross-platform applications with minimal code’ to me.
- some apps don’t look at term info and eg just assume your terminal supports the same escape codes as the author’s
I basically feel like the above comment is making broad claims about the advantages of terminals however those claims are only narrowly true and importantly, aren’t true for the situation being talked about in the comment which those claims are made in response to.
It's not quite as bad as you are describing it. IME, TUIs via ncurses, UNICODE characters (e.g. for box drawing) and at least 256 colors work pretty much everywhere and gets you pretty far (think 'Turbo Pascal' or 'htop' style UIs).
I would say: composability. As you can see in the examples the datasources are very different, and for some one off observation this can be totally handy (if you don't need to massage the data too much, probably).
one use case that I can think of is for monitoring something. Let's see you have tmux open fullscreen, working in one of the panes and have an auto-updating graph at one of the corners to check the value of your stocks (?).
Various unique graphical symbols are arranged and manipulated across a uniform fixed grid (typically also in colour).
The defining feature of the terminals graphics system is this grid which makes both location of updates and the display speed largely uniform quantities. These can then be anticipated, accustomed to and relied upon.
Ingesting data is faster and more meditative when free of the additional distractions of more complex graphical environments. These charts present complex information without breaking the terminals unique advantages.
You don't get to dictate how I interact with my terminal. I like colors in my terminal, I like nicely formatted output with columns, I like ligatures, I like emojis in output.
>Isn't the point of terminal to escape the graphics-riddled world
No, or at least not for me.
I use terminal because it is the best tool I have found to solve my problems. My problem with graphical user interfaces is lack of customization options and having to conform into certain way(s) of working.
In my terminal I can easily construct the the UI how I want and I can use all the tools as they were intended (of course assuming the tools were designed to work on CLI). I like building tiny and light terminal UIs for to help me.
Data is the outlier. I can wrangle the data just fine using `$EDITOR`, but I have to visualize it somehow. Often I just end up working in a Jupyter notebook (inside a browser) and lamenting how I don't have nice access to some tool. I don't know if this plotter tool will change anything, but I will give it a go.
Depends on your viewpoint. To me, the terminal is a fixed sized canvas (as long as you're not resizing e.g. a window or something). The fact there's auto-scrolling and a backlog are features of your shell, less the terminal emulator itself (even though backlog is actually implemented by the emulator).
This comes down more to philosophy than anything, though.
When I was a young one doing physics in the '80s, we used CERN's HBOOK[1] to do all our (statistical) plotting. Recently while working on a Common Lisp project I had a use for something similar, remembered HBOOK, and "rolled my own"[2] (much simpler version).
Yes, a nice clean graph in a GUI or PDF is cleaner, but if you're working at the terminal already or in a REPL, it can be nice to just see the output there.
At the risk of downvotes: I do wish this particular project didn't require a working Ruby / Gem installation -- nothing against Ruby, but I'd be curious if there was an equivalent stand-alone executable written in Go or similar... something like [3]?
[1] https://cds.cern.ch/record/307945/files/ [2] https://github.com/eigenhombre/hbook [3] https://github.com/gizak/termui