zoco

怎么在iTerm2上画个图?

2020-07-29


工作中经常需要临时跑一些数据,包括自己分析后者最后给别人看的其实就是浓缩出来的几条数据,之前要么是对着terminal看数字,但是看图的确能比纯看数据直观上得到的信息更多,更何况是给其他人看。

要么是之前写了个echarts-builder的工具把数据套进去看,或者有些数据分析的同学用excel画图表,甚至建个grafana的系统,但这都太不方便了!我就想把生成的数据一行命令把图直接在terminal展示出来。

我先尝试用字符直接在iterm2上画,结果画出最好看的就是这样的:

aZvpIP.png

太丑了。

其实用RStudio也可以直接满足这个需求,而且数据分析的工具也很多,但是和工程上的对接不方便。比如我要从mysql中拿1000w条数据出来,用go开N个协程就很快把结果跑出来。

然后我找到了GitHub - gonum/plot: A repository for plotting and visualizing data

Images - Documentation - iTerm2 - macOS Terminal Replacement

基本原理是

iTerm2 extends the xterm protocol with a set of proprietary escape sequences. In general, the pattern is: ESC ] 1337 ; key = value ^G

上述1337被称为一个 OSC code ,全称是 operating system command terminal control sequences,是用来控制 terminal 的行为的。

在 iTerm2 里要展示一个图像文件,可以用脚本 imgcat 。下载之后,在 iTerm2 里运行下述命令即可。

./imgcat a.png

这个命令干了什么呢?仔细读一读源码,发现它向标准输出打印了如下内容

\033]1337;File=name=图像文件名;size=图像大小;inline=0:图像内容(Sixel编码);\a

我以前没有用过 Sixel 图像格式,所以查了一下 Wikipedia,原来是一种把图像编码成 ASCII 序列的编码方式。

Sixel - Wikipedia

Sixel, short for “six pixels”, is a bitmap graphics format supported by terminals and printers from DEC . It consists of a pattern six pixels high and one wide, resulting in 64 possible patterns. Each possible pattern is assigned an ASCII character, making the sixels easy to transmit on 7-bit serial links.

知道关键是输出 Sixel 格式的图像给 iTerm,那么用任何语言写一个程序,向标准输出写一个 Sixel 格式的图像文件,即可在 iTerm2 里显示图片了。

有人已经完成了这个工作:

GitHub - mattn/go-sixel

比如可以把图片直接ls到终端,不用通过window查看了;还可以集成到有一些数据库中,比如mysql,mongodb之类的,查出来的数据可以直接图形查看。

我操作最频繁的就是拿到一组数,然后line chart展示。 比如下面这组数据:

[-6.4062824 1.1397738 1.9211388 2.9974246 2.5751376 3.070317 2.5280557 2.8509731 1.4308753 2.0060067 1.6766437 1.9481306 1.738145 1.7371098 1.634459 1.541113 1.6059783 1.473517 1.4876183 1.3171686 1.2432184 1.3464177 1.2287861 1.2016274 1.0938609 1.096902 0.94116783 1.0109215 0.9812323 0.92964137 1.0425683 1.011936 1.0779625 1.0728405 1.0201957 1.0106804 0.9396344 0.9463366 0.895773 0.88059026 0.89044374 0.8245517 0.7634141 0.74606377 0.74447554 0.62331617 0.65547746 0.60883343 0.5527544 0.5496284 0.54787344 0.4685537 0.4491693 0.45508364 0.44680938 0.42242846 0.39545557 0.42467472 0.42354652 0.35238484 0.3278334 0.35248998 0.29977313 0.20945604 0.21039158 0.23303731 0.2760194 0.24477984 0.32918194 0.34745342 0.3770558 0.3861287 0.3676358 0.34756434 0.34648046 0.3786597 0.41689637 0.42572907 0.3880029 0.35344404]

那么我展示出来的图应该是这样的

aZvmaq.png

是不是很直观?

源码在这里:

GitHub - yezuozuo/draw-iterm2

只要一行代码就可以画出三种图:

Line chart

draw_iterm2.Line([]float64{1,2,3,4});

aZvKiV.png

Histogram chart

draw_iterm2.Histogram([]float64{1,2,3,4,5,6});

aZvQRU.png

Pie chart

draw_iterm2.Pie([]float64{1,2,3,4});

aZv3M4.png