
Show HN: GNUplot with sixel – Mix images, ANSI colors and plots - csdvrx
https://github.com/csdvrx/sixel-gnuplot
======
sprash
There seems to be desperate demand for graphics output in terminals. Sixels
are a rather crude method dating from a time where terminals were optimized
for low bandwidth serial connections and very constrained resources in the
device that actually renders the content. We have 3D graphic cards now!

This is why right now I'm working on a terminal emulator that implements
escape codes that allows a subset of "byte compiled" OpenGL commands to run
directly in the terminal window. You now can render a complex 3D scene just by
cat'ing a file without any boiler plate code. I think there are many potential
use cases for this. It allows for example remote graphics accelerated
applications running on another machine via ssh. Once all the textures are
uploaded to the GPU RAM the bandwidth required for the display commands is
rather low even for interactive games.

~~~
csdvrx
You should not dismiss "crude" methods so easily: the same output can be
rendered inside GNU screen or tmux, which would be complicated otherwise.

And low bandwidth is useful when doing SSH: I posted this quick example of
what I use everyday as a reply "ROSshow: ASCII art visualizations for robot
sensor data"
([https://news.ycombinator.com/item?id=19519165](https://news.ycombinator.com/item?id=19519165))
by ssh'ing to my remote host (which does not have a GPU) from my laptop (which
doesn't have a GPU either).

I wanted to share something that you can use right now, and that works
reliably even in non optimal conditions.

Notice how my loadavg is above 10, and how I'm using a mlterm binary
downloaded straight from mlterm.sf.net/bin.html

The same will work with a vanilla msys2 installation, or with the in-kernel
console of "old powerless machines" as noted on
[https://saitoha.github.io/libsixel/#sayaka-
chan](https://saitoha.github.io/libsixel/#sayaka-chan)

~~~
sprash
With a serialized GPU commands the remote host does not need a GPU since
everything is rendered locally. Only the machine running the terminal emulator
needs one. And this would also work within screen or tmux if they don't meddle
with unknown escape codes.

~~~
chubot
Even if they don't mess with unknown escape codes, wouldn't they have to know
how wide what is being drawn is?

I ran into this issue while writing a shell. All shells use wcwidth() to
determine the width of a unicode character. I think all terminals need that
information too, and they would also need the analogous information for
unknown escapes.

~~~
sprash
It will certainly mess up multi window screen/termux arrangements. The
dimensions of the current terminal can be obtained easily. However the
position can not. And it will still be possible to draw over other windows.

------
zimbatm
I would love it if all terminals agreed and implemented libsixel or another
graphics format.

libsixel is not supported by urxvt, alacritty, any VTE-based terminals as far
as I know.

iTerm2 has a custom base64-encodig based image format.

there are even more: [https://github.com/dylanaraps/neofetch/wiki/Image-
Backends](https://github.com/dylanaraps/neofetch/wiki/Image-Backends)

~~~
csdvrx
You're right- more terminals need to implement a common format.

I wish VTE and gnome-terminal would add sixel support

~~~
rbanffy
While we are at it, let's add Tektronix 4010 graphics. With bright drawing
beam and flash screen erase ;-)

It'd be nice to have an agreed-upon simple standard for graphics in terminals.
At the same time, Unicode 13 will add 2x3 graphics blocks from ITU T.100 and
T.101 standards and a couple fonts will start supporting them from the start,
so some lower resolution graphics will be immediately useful.

I'm not sure if sixels will work under tmux or screen - someone mentioned they
do, but I'm not sure how: the same problem we have with double-width and
double-height (I wanted VTW to support them) and we all agreed it'd make tmux
and screen essentially unusable.

~~~
csdvrx
sixel work under tmux and screen. Check my repository
[https://github.com/csdvrx](https://github.com/csdvrx) which is just cloned
from existing branch by arakiken

I added screenshots of gnuplot running under both tmux and screen, using msys2
and mlterm

A vectorial support would be nice, but adding svg and a custom format like for
iterm may better: Tektronix 4010 graphics is not as widely supported as sixel,
and it may be a better start from scratch.

~~~
rbanffy
How does it account for character width? Isn't a sixel a 1-pixel wide, 6-pixel
tall bitmap? Does an actual DEC terminal round them to the next character
boundary? Can you write text to a line that started with sixels? Can you write
sixels after outputting some characters in the same line? How does a vertical
screen partition look like? Are sixel graphics compressed when the terminal is
in 132-column mode?

I saw this video of an actual VT-320 terminal displaying sixel graphics:
[https://www.youtube.com/watch?v=0SasrQ7pnbA](https://www.youtube.com/watch?v=0SasrQ7pnbA).
Someone should check what the behavior is under tmux and screen (at least).

The person also has REGIS and 4014:
[https://www.youtube.com/watch?v=afNuDH7QpYA](https://www.youtube.com/watch?v=afNuDH7QpYA)
and
[https://www.youtube.com/watch?v=kIF0sXQn0RI](https://www.youtube.com/watch?v=kIF0sXQn0RI)

------
enriquto
prediction: in a few weeks somebody will rediscover the existence of tektronix
emulation on xterm and the community will go crazy about it

~~~
mindcrime
That's not necessarily a bad thing though. Sometimes it's good to revisit some
(seemingly) "forgotten" technologies which still have a lot of potential.

~~~
enriquto
> That's not necessarily a bad thing though.

I did not say it ironically! Tektronix is super-cool! It could be could be
realistically rendered as sgv, and easily extended to add colors and stuff.

------
thatsaguy
Sixel is nice (and I use it all the time), but we do have better nowadays.

iterm's image handling [1] is superior: it just encodes a modern and more
efficient image format and sends it inbound to be decoded by the terminal. png
was always at least equal if not more efficient than sixel at indexed
colormaps. You can send jpegs for drastically more efficient true-color
images.

The "OSC1337" is not unique to iterm. mlterm also supports it, and I do
remember a few others as well. You can use "ranger" to have image previews on
a remote server without having to jump through hoops.

[1] [https://iterm2.com/documentation-
images.html](https://iterm2.com/documentation-images.html)

~~~
csdvrx
some terminal emulators support specific formats, but sixel strength is that I
don't have to specifically install there emulators.

Also, what if I use an OS where they don't work? (Windows 10?)

~~~
thatsaguy
I have nothing against sixel, of course. But to put things in perspective,
Sixel support by itself is not great. Definitely more supported than iterm's,
but not universal.

But when developing a new program that wants to output graphics to the
terminal, OSC1337 is damn easy (you'll likely not need any new dependency or
image handling routines), while for sixel you'd probably need libsixel or
write your own encoder.

As a developer, I vastly edge towards iterm's handling. (and to be honest, as
a user as well. png encoding is faster too!)

------
jpalomaki
Wikipedia article for sixel:
[https://en.m.wikipedia.org/wiki/Sixel](https://en.m.wikipedia.org/wiki/Sixel)

------
iheartpotatoes
Doesn't really make sense to me that "cat <jpg>" should render the bitmap to
the screen. 'cat' is a concatenation tool. 'cat'ing two JPEGs together isn't
the same as 'cat'ing two text files. So why? Use another tool, don't break the
idiom.

~~~
csdvrx
cat /etc/debian_version shows the file

cat /etc/debian_version /etc/debian_version shows the file twice

Shockingly, cat sixel1.six sixel2.six sixel3.six or img2sixel file1.jpg
file2.jpg file3.jpg works in the exact same way: cf
[https://github.com/csdvrx/sixel-
testsuite/blob/master/3-sixe...](https://github.com/csdvrx/sixel-
testsuite/blob/master/3-sixels.jpg)

Simply screenshot and edit the result when you are done.

But if you want to create another tool, for example to trim white boarders and
concatenate, by all means please do!

Follow the example of
[https://github.com/hackerb9/lsix](https://github.com/hackerb9/lsix) who wrote
a great tool!

------
swiley
NOTE: this repo is only the patch for the debian packages, it appears gnuplot
already supports sixel output if it's configured --with-bitmap-terminals

~~~
csdvrx
Yes that's indicated in the README. Nothing super complicated, I just wanted
to show how it was super practical.

------
dima55
Where are the sources? If you're releasing modified binaries, you're violating
the gnuplot license.

~~~
csdvrx
Do you understand that I just added one compile flag to debian official
sources?

~~~
dima55
Clearly I did not understand this :) Is there any reason to not make this the
default? I've never used this feature, but if you think it's generically
useful, you can email the debian-science list with the suggestion. The
maintainer is generally responsive.

~~~
csdvrx
:)

Already emailed, unfortunately it's too late to be included in the next
release!

------
black-tea
A github repo full of binaries? What is this?

~~~
csdvrx
It is just apt-get source gnuplot/testing ; cat debian/rules | sed -e
's/\--with-gd/\--with-gd --with-bitmap-terminals' > debian-rules ; dpkg-
buildpackage . (or something approximately like that)

But you are welcome to apt-get build-deb and do that by yourself if you don't
trust my binaries or my memory :-)

------
daleroberts
For Matplotlib, checkout this:
[https://github.com/daleroberts/itermplot](https://github.com/daleroberts/itermplot)

~~~
saagarjha
n.b. this only works in iTerm.

