Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: GNUplot with sixel – Mix images, ANSI colors and plots (github.com/csdvrx)
110 points by csdvrx on March 29, 2019 | hide | past | favorite | 53 comments

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.

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) 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

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.

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.

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.

With the history of ^O bracketed paste handling exploits and the more recent spectre/meltdown exploits, I'm not sure serialized GPU rendering is such a bright idea.

If the concern is the speed of the scrollback on device rendering the content, wouldn't adding GPU support to say mlterm be enough?

Anyway, if someone has a desperate need of graphical output inside a terminal, this is an actual solution working with little risks and default tools: I only recompiled gnuplot with the proper compile-time flag, exported the GNUTERM variable, and voila!!

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

Yes, but still a throwback to 3 decades past+

Why fix what ain’t broke?

Because it's not only "broke" things that people want to fix -- it's also half-arsed, inadequate, slow, limited, etc things. And terminal graphics are all those.

Not sure if it was implied.

Sixel has lots of overhead compared to ascii/Unicode braille art. Using sixel to transmit decent images over ssh is very data-demanding

Please do not. The best thing you can do it get sixel working on more terminal emulators, particularly Windows ones like PuTTY and TeraTerm. Do any free native windows terminal emulators support Sixel?

I'm working on embedded software for some industrial equipment the runs over a serial port, and I'm running into all kinds of annoying problems.

I use Linux, customer uses Windows.

In Linux (Ubuntu 16), I found that large paste to Xterm does not work (I know for sure that this used to work in the past). It seems to discard data when Xon/Xoff flow control kicks in, or when a buffer is too large. I've tried minicom, PL2303, FTDI, picocom, my own serial program, XTerm and Gnome terminal. I'm pretty sure the problem is X or Unity (a C program that transfers data out the serial port works just fine). On the other hand, Xterm supports Sixel, so the embedded software can display graphs.

[Followup: I just traced this problem to "picocom", but it has been fixed in a newer version].

The idea is that I should be able to select calibration data from a spreadsheet and paste it into the terminal emulator connected to my device.

In Windows, embarrassingly, large paste works just fine, for example from TeraTerm. But Putty and TeraTerm do not support Sixel.

I suppose XTerm in Cygwin might work, but it would better to have a native Windows program.

I've not tried Mac, but nobody in the industrial world uses them.

100% right. Adding sixel support to more terminals would do more to broaden graphical support.

On linux, just adding sixel to gnome-terminal and libvte would go a long way.

FYI, I picked up sixel because it's the closest thing to a standard, and because technically I saw it as good enough for most cases.

> I use Linux

I use Windows :-)

> Do any free native windows terminal emulators support Sixel?

mintty on msys2 and mlterm do. I prefer mintty, it feels faster. I'm eagerly waiting for conpty and hopefully even better consoles in Windows!

Ah, on Windows, I would prefer a terminal emulator that can connect directly to a serial port. I don't think mintty and mlterm can do this.

Cygwin / mintty can do sixel


Most people are using tty apps because they don't want more crap that breaks when opengl (read, drivers) misbehaves.

Can you, github.com/jwilm, github.com/kovidgoyal et al get together and instead give us a better standard that all 3 of you implement? I am sorry but I won't use your terminal just for one feature, I can use a dedicated image viewer.

So far my version is just a crudely hacked together proof of concept on top of st I did as hobby. It just renders textured polygons without any shaders or more advanced stuff. Since this is my first OpenGL application ever it probably won't ever be released to the public. Somebody else with more experience should rather do it. A More advanced protocol like Valves Fossilize (https://github.com/ValveSoftware/Fossilize) should be used for that which means I can throw away my code anyways at this point.

However serialized graphics does not seem a project goal of either kitty or alacritty.


kitty has image support

It implements its own protocol (https://sw.kovidgoyal.net/kitty/graphics-protocol.html) to display images. This is something different from serialized OpenGL.

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

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

I wish VTE and gnome-terminal would add sixel support

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.

sixel work under tmux and screen. Check my repository 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.

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. 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 and https://www.youtube.com/watch?v=kIF0sXQn0RI

Anyone know if there's been any work to support libsixel in libvte?

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

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.

> 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.

I've played with it. Cool, but it is monochrome and font challenged. Neat for projecting a line map or similar for a retro-futurey look.

Some 3270 terminals also support vector graphics. I don't remember if x3270 implemented them.

I saw some impressive renderings on an IBM 3279. Sadly, it was never on my desk.

And you'd have to translate the text from ASCII to EBCDIC.

... and then proceed to re-invent VNC and RDP from first principles

I was going to say reinvent X11 and then X terminals but the same applies.

I'm pretty sure I saw a terminal emulator with ReGIS emulation out there, I'm surprised that's not become the fad.

https://github.com/saitoha/xserver-SIXEL I haven't tried that but issues tell that even mouse works with Firefox in terminal.

mlterm's emulation of it is better.

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

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?)

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!)

Wikipedia article for sixel: https://en.m.wikipedia.org/wiki/Sixel

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.

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...

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 who wrote a great tool!

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

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

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

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

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.


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

A github repo full of binaries? What is this?

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 :-)

For Matplotlib, checkout this: https://github.com/daleroberts/itermplot

n.b. this only works in iTerm.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact