我的绘图工具箱

由于在写作中经常需要配图,本文分享下我常用的绘图工具以及如何存储并展示配图。

白板绘图

Excalidraw

白板绘图的好处在于灵活度非常高。好的白板工具可以很方便的绘制自由的图片和预定义的结构化图形,这方面我在用的工具是 Excalidraw,由于是本工具是开源的,我也部署了自己的 Excalidraw 白板工具。在 基于纯文本的人生管理 这篇文章里所有的配图都是用 Excalidraw 绘制,比如下图:

一个好的白板工具应该需要有什么特性呢?Excalidraw 的创始人写了一篇很好的文章 Rethinking Virtual Whiteboard 来回答这个问题。

Excalidraw 的优点有以下:

  • 无需注册,直接使用,用完即走;
  • 代码开源,免费使用,不用担心商业问题;
  • 多人实时协作,共同绘制;
  • 数据可导出,可通过链接直接分享给任何人;
  • 数据存储在浏览器本地,文件可离线编辑;
  • 扩展性强,可以导入其他人绘制的资源库;
  • 数据采用端到端加密,服务器端数据加密存储,隐私保护很可靠;
  • 保存的文件可直接在 VSCode 编辑(通过插件),同时可被其他网站嵌入使用,比如不只是笔记工具的 Logseq 里的绘图功能就是嵌入 Excalidraw 完成的;

拥有这么多特性,用 Excalidraw 能画啥图得取决于你的想象力了:在 One Year of ExcalidrawCreate Diagrams That Look Like Hand-drawn 这两篇文章里可以看到使用 Excalidraw 画常见的结构图如架构图、结构图、流程图与交互图等,也可以自由绘制如品牌Logo、事件风暴图、原型图、对比图、手绘图、四格漫画与平面图等。

除了 Excalidraw 外,其创始人早期用了另一个白板工具近 10 年,这个工具是 zwibbler,我看了下感觉用 Excalidraw 完全可以替代它。

Miro && Mural && Figma

这几个在线白板很适合团队协作(比如敏捷工作流如 Retro、站会、头脑风暴、工作坊等),和 Excalidraw 不同之处在于,它们支持的模版更为丰富,还能集成不同的 App,比如在白板里插入表格和图片之类。其中 Figma 虽然是个类似 Sketch 的设计工具,但是也支持白板的用法。

不好的地方在于它们都不是开源的,但是也提供了免费版。当然也可以用 Google 出品的 jamboard 替代,虽然没有提供模版,但是基本功能都类似。

Perfect FreeHand

带有压感的在线手写板工具,以下是用手写板手写的效果:

文本绘图

文本绘图的好处在于修改、存储方便,很简单即可绘制出固定模式的图,如时序图、架构图、部署图、线框图、甘特图、WBS与思维导图。 PlantUML 是一个支持文本绘制类UML图的工具,可以在 Real World Plantuml 找到很多用它实现的图。我一般用它来绘制以下一些图。

思维导图

文本如下:

@startmindmap
skinparam monochrome true
* Markdown排版
** 写作
*** 博客
*** 知乎专栏
*** 微信公众号
** 幻灯片
** 专业报告
** 笔记
@endmindmap

可以使用在线编辑器 PlantUML Editor 在线编辑预览。

除了PlantUML外还可以用 Markmap,相比PlantUML的好处在于它基于Web,不需要通过渲染生成图片的方式就可以从文本生成可交互的思维导图。比如下面的通过Markdown生成思维导图的例子:

# markmap

## Links

- <https://markmap.js.org/>
- [GitHub](https://github.com/gera2ld/markmap)

## Related

- [coc-markmap](https://github.com/gera2ld/coc-markmap)
- [gatsby-remark-markmap](https://github.com/gera2ld/gatsby-remark-markmap)

## Features

- links
- **inline** ~~text~~ *styles*
- multiline
  text
- `inline code`
-
    ```js
    console.log('code block');
    ```
- Katex - $x = {-b \pm \sqrt{b^2-4ac} \over 2a}$

## 当然也支持中文啦

通过此库最终生成的效果:

# markmap

## Links

- <https://markmap.js.org/>
- [GitHub](https://github.com/gera2ld/markmap)

## Related

- [coc-markmap](https://github.com/gera2ld/coc-markmap)
- [gatsby-remark-markmap](https://github.com/gera2ld/gatsby-remark-markmap)

## Features

- links
- **inline** ~~text~~ *styles*
- multiline
  text
- `inline code`
-
    ```js
    console.log('code block');
    ```
- Katex - $x = {-b \pm \sqrt{b^2-4ac} \over 2a}$

## 当然也支持中文啦

架构图

源文本见 arch_aws.plantuml

除了PlantUML外还可以用 Mermaid 来通过文本生成各种UML图。比如下面通过文本生成时序图的例子:

sequenceDiagram
    autonumber
    张三->>李四: Hello John, how are you?
    loop Healthcheck
        李四->>李四: Fight against hypochondria
    end
    Note right of 李四: Rational thoughts!
    李四-->>张三: Great!
    李四->>王五: How about you?
    王五-->>李四: Jolly good!

生成的效果图如下:

sequenceDiagram
    autonumber
    张三->>李四: Hello John, how are you?
    loop Healthcheck
        李四->>李四: Fight against hypochondria
    end
    Note right of 李四: Rational thoughts!
    李四-->>张三: Great!
    李四->>王五: How about you?
    王五-->>李四: Jolly good!

GitHub的Markdown已经支持Mermaid了,相比PlantUML的优势在于其原生支持Web,无需通过生成图片即可集成到网站页面中。

如果想更灵活的绘制复杂的架构图,推荐使用PlantUML底层使用的graphviz工具,它的效果可参考这篇Graphviz and Hugo文章。甚至可以用它来绘制RFC协议标准里的ascii风格的文本配图,比如下面的例子:

digraph {
    subgraph cluster_0 {
        a0 -> a1 -> a2 -> a3;
        label = "process \#1";
    }

    subgraph cluster_1 {
        b0 -> b1 -> b2 -> b3;
        label = "process \#2";
    }

    start -> a0;
    start -> b0;
    a1 -> b3;
    b2 -> a3;
    a3 -> a0;
    a3 -> end;
    b3 -> end;
}

会生成如下ascii文本图形:

     +- - - - - - - - - - - - - +
     '        process #1        '
     '                          '
     ' +----+            +----+ '       +----------+
  +- ' | a1 | <--------- | a0 | ' <--   |  start   |
  |  ' +----+            +----+ '       +----------+
  |  '   |                 ^    '         |
  |  '   |                 |    '         |
  |  '   |                 |    '         v
  |  '   |                 |    '     + - - - - - - -+
  |  '   |                 |    '     '  process #2  '
  |  '   v                 |    '     '              '
  |  ' +----+              |    '     ' +----------+ '
  |  ' | a2 |              |    '     ' |    b0    | '
  |  ' +----+              |    '     ' +----------+ '
  |  '   |                 |    '     '   |          '
  |  '   |                 |    '     '   |          '
  |  '   |                 |    '     '   v          '
  |  '   |                 |    '     ' +----------+ '
  |  '   |                 |    '     ' |    b1    | '
  |  '   |                 |    '     ' +----------+ '
  |  '   |                 |    '     '   |          '
  |  '   |                 |    '     '   |          '
  |  '   |                 |    '     '   v          '
  |  '   |               +----+ '     ' +----------+ '
  |  '   +-------------> | a3 | ' <-- ' |    b2    | '
  |  '                   +----+ '     ' +----------+ '
  |  '                          '     '   |          '
  |  +- - - - - - - - - - - - - +     '   |          '
  |                        |          '   |          '
  |                        |          '   |          '
  |                        |          '   v          '
  |                        |          ' +----------+ '
  +------------------------+--------> ' |    b3    | '
                           |          ' +----------+ '
                           |          '              '
                           |          + - - - - - - -+
                           |              |
                           |              |
                           |              v
                           |            +----------+
                           +-------->   |   end    |
                                        +----------+

可以通过graphviz的命令行工具来生成,也可以使用这个在线网站:dot-to-ascii

关于如何用文本画好一幅好的架构图,推荐看 C4 Model 的作者的这篇 Software architecture diagrams as text

专业绘图

ASCII

ASCII风格的绘图很适合放在代码或纯文本文档中,如:

手工画显然太困难,可以使用相关的工具绘制:

  1. asciiflow是款功能简单的免费在线绘制ASCII风格图的网站。
  2. monodraw是Mac上功能强大的付费App,可以绘制复杂的ASCII图形,如下图:

Sketch/OmniGraffle

源文件见 Serverless.sketch

要想用 Sketch 画好配图,配色很重要,这方面可以看 draveness 写的这篇《技术文章配图指南》。当然 Sketch 可以做的远不止这些,不过这不在本文讨论范围。

draw.io/Google Drawings

这类工具都可以绘制各类你想要的配图,唯一限制的就是你的想象力了。

在线绘图工具如 Google Drawings 的多人实时协作功能更是团队协作绘图利器。这篇《分布式事务中的时间戳》中的配图就是用 Google Drawings 绘制的。

代码绘图

Plotly

Plotly是一个基于d3.jsstack.gl的图形库,它可以用来绘制各种类型的图表,比如散点图、折线图、饼图、柱状图甚至3D图形等。

  • 与Hugo的集成可参考这篇Plotly & Hugo

  • 如果是想基于各类数据库做商业数据分析的话还可以使用如Metabase这类开源方案。

Python Jupyter Notebook

我用这个绘制一些数据分析的图,比如这种:

源代码见 index_month_quote_change.ipynb

其他工具

Excel

用 Excel 画图不是不可以,你可以用数据绘制图,也可以用单元格来绘制马赛克的图,不过我一般用它来绘制投资组合的一些走势图和状态图。

配图存储与展示

图片我一般用 VSCode 插件 markdown image paste 配置 AWS S3 后,可将复制到剪贴板的图片一键上传至 S3 桶,之后可通过桶绑定的域名访问图片,本博客所有的配图都是如此存储与展示的。具体详见《我的笔记系统》VSCode插件一键存储图片至S3节。

关于绘图工具的思考

没有一种工具是万能的,万能如 Excalidraw 也无法替代 Lucidchart/Draw.io/Google Drawings/Visio 这些复杂的工具(他们更适合复杂的对精确性有高度要求的图)。更没有一种软件工具能替代纸和笔。工具更重要的是背后使用它的人,能用图片讲好一个故事才是我们需要不断提升的能力,一个工具能做到不限制你的发挥就算适合的好的工具。

进一步阅读