Dashboard site with Hexo and Vega-Lite

最近写一篇论文需要画 10 张实验数据图,我用一套祖传的 Matplotlib 脚本读取 csv 实验数据画图。这个过程有几个很痛苦的问题:

  1. 实验数据管理比较混乱,例如我可能每次批量做实验只会更新表格的一行/一列,csv 又没有注释,到后面就忘记每行是什么时候做的了
  2. 每张图的样子都不太一样,并且脚本代码高度耦合,所以基本上我为每张图都要维护一个脚本
  3. 我和合作者希望能在线实时共享实验数据

为了解决 3,我们日常在用飞书智能表格的仪表盘功能登记数据,但它的格式无法定制而且比较丑,导致用在论文里的图还得重新画。并且没有历史记录功能,也就是解决不了 1 和 2。

我尝试为这三个问题寻找成熟的解决方案。对于问题 1,直观的解决方案就是用 Git 对 csv 进行版本管理;实际上这还有一点小问题就是 csv 的修改有时是和画图脚本绑定的,也就是 csv 和画图脚本需要同时做版本管理。这就来到了问题 2,我认为我们 csv 入图片出的流程是没有问题的,但这个转换流程的实现不够理想,理想情况应该存在一个 markup language,描述数据到图片的映射过程,对这个 markup language 做版本管理就比管理画图脚本要美丽的多。ChatGPT 告诉了我 Vega-Lite 这个项目,我认为它完美地做到了我需要的事。问题 3 解决方案就比较多了,无非是创建一个网站,我最熟悉的就是 Hexo 引擎。

他们结合在一起之后,就得到了一个我非常喜欢的、有点 Unix 哲学的工具链(do one thing and do it well):用 Hexo 生成静态网站,用 Vega-Lite 描述图片格式,用 Git 对源数据和图片格式做版本管理。它被实现为我个人博客主题的一个特性。

Preview

欢迎使用!

使用流程就是写一篇普通的博客,插入一个代码块,指定语言为 vega-lite:

```vega-lite
data:
  url: /data/cars.csv
mark: point
encoding: 
  x: 
    field: kmpl
    type: quantitative
  y: 
    field: price
    type: quantitative
```

然后创建一个 source/data/car.csv 文件:

brand,model,price,kmpl,bhp,type
Chevrolet,Beat,421,18.6,79,Hatchback
Chevrolet,Sail,551,18.2,82,Sedan
Chevrolet,Sail Hatchback,468,18.2,82,Hatchback
Chevrolet,Spark,345,16.2,62,Hatchback
Fiat,Linea Classic,612,14.9,89,Sedan
Fiat,Linea,700,15.7,112,Sedan
Fiat,Punto Evo,499,15.8,67,Hatchback
Ford,Classic,506,14.1,100,Sedan
Ford,Figo,414,15.3,70,Hatchback
Honda,Amaze,519,18,87,Sedan
Honda,Brio,421,19.4,87,Hatchback
Hyundai,EON,302,21.1,55,Hatchback
Hyundai,i10,418,19.8,68,Hatchback
Hyundai,i20,523,18.6,82,Hatchback
Hyundai,Verna,774,17.4,106,Sedan
Hyundai,Xcent,496,19.1,82,Sedan
Suzuki,Alto,315,24.1,67,Hatchback
Suzuki,Alto 800,248,22.7,47,Hatchback
Suzuki,Celerio,392,23.1,67,Hatchback
Suzuki,Ciaz,725,20.7,91,Sedan
Suzuki,Estilo,338,19,67,Hatchback
Suzuki,Ritz,442,18.5,86,Hatchback
Suzuki,Swift,462,20.4,83,Hatchback
Suzuki,Swift DZire,508,19.1,86,Sedan
Suzuki,SX4,715,16.5,103,Sedan
Suzuki,Wagon-R,363,20.5,67,Hatchback
Nissan,Datsun GO,312,20.6,67,Hatchback
Nissan,Micra,413,19.5,67,Hatchback
Nissan,Sunny,699,16.9,98,Sedan
Renault,Pulse,446,18,74,Hatchback
Renault,Scala,724,16.9,98,Sedan
San,Storm,595,16,59,Sedan
Skoda,Fabia,503,16.4,75,Hatchback
Skoda,Rapid,756,15,104,Sedan
Tata,Indigo,499,14,65,Sedan
Tata,Nano,199,23.9,38,Hatchback
Tata,Zest,481,17.6,89,Sedan
Toyota,Etios,603,16.8,89,Sedan
Toyota,Etios Liva,500,17.7,79,Hatchback
Volkswagen,Polo,535,16.5,74,Hatchback
Volkswagen,Up,360,21,74,Hatchback
Volkswagen,Vento,785,16.1,104,Sedan

原本代码块的位置就会变成一张数据图,效果如下:

visdown preview

Future Work

我还没有重度使用这个工具链,所以暂时还是不知道版本管理的负担有没有变轻,以及这样的静态网站是否真的能满足共享数据需求,但总体而言他目前的样子我很喜欢,并且图片调好之后基本可以直接放到论文里用(但还需要根据论文排版调整一些大小/比例之类的)。

Do one thing and do it well 也不一定永远是好的,因为 thing 的定义可能很善变,例如我可能有一天会想对比两个 git 版本的图到底区别如何,hexo 看起来就不能很方便地做好这件事情。再比如 dashboard 可能需要布局来在一屏之内放尽可能多的图,这对我的博客主题而言也很难实现。

现在已经可以导出 svg,但 LaTeX 里用的话还需要转换成 pdf,转换成 pdf 并裁切的功能应该比较实用。