Node.jsでお手軽グラフ表示

Node.jsで手軽にグラフ表示できるライブラリの[nodeplotlib](https://www.npmjs.com/package/nodeplotlib)が便利だったので使ってみました。

# はじめに

Node.jsでデータを扱う作業をしている際にグラフ表示したい時ありませんか？
データ扱いたいならpythonでやれというのはあるんですが、Node.jsでベースを作ってるんでNode.jsでやりたいんですよ。。。

ということで、良いライブラリがないか探してみると`nodeplotlib`というライブラリを見つけまして、デモのGIF画像がなかなか良さげだったので使ってみました。

![demo](https://raw.githubusercontent.com/ngfelixl/nodeplotlib/master/img/animation.gif)


# nodeplotlibとは？

[README](https://github.com/ngfelixl/nodeplotlib#nodeplotlib) によると

> Library to create top-notch plots directly within NodeJS on top of plotly.js without any front-end preparations. Inspired by matplotlib.

ということで、グラフ描画ライブラリの[Plotly.js](https://plot.ly/javascript/)をフロントエンドのコードなしで使えるようにしたライブラリとのことです。
Plotly.jsは使ったことはなかったんですが、可視化のライブラリとしては有名なんですね。実際見た目も機能面もよくて使いやすかったです。
Python、R、Javascript、MATLAB、Juliaなど様々対応しているみたいで色々な記事が見つかりました。

* [plotly.jsでインタラクティブなグラフを描画する - Qiita](https://qiita.com/icchi_h/items/404d24e9aa6e553ca4e7)
* [[Python] Plotlyでぐりぐり動かせるグラフを作る - Qiita](https://qiita.com/inoory/items/12028af62018bf367722)

`Plotly.js`をJavascriptで使う場合はフロントエンド側で実装する必要があるんですが、`nodeplotlib`を使うと、フロントエンドの用意なしでNode.jsから直接グラフを描画してくれるようです。


# 使ってみた

お試しで書いたコードは[github](https://github.com/dbgso/hello-nodeplotlib)に上げたので、サクッと試したい方はcloneしてもらえればすぐ使えるはずです

```console
$ git clone https://github.com/dbgso/hello-nodeplotlib.git
$ cd hello-nodeplotlib
$ yarn
$ yarn ts-node src/index.ts
```

以降で中身を見ていきます

## インストール

yarnかnpmで入ります

```bash
$ yarn add nodeplotlib
# or
$ npm install nodeplotlib
```

## サンプルコード実行

[Quick start](https://github.com/ngfelixl/nodeplotlib#quick-start)にサンプルコードがあったので実行してみます。

```src/index.ts
import { plot, stack, clear, Plot } from 'nodeplotlib';

const data: Plot[] = [{
  x: [ 1, 3, 4, 6, 7],
  y: [ 2, 4, 6, 8, 9],
  type: 'scatter'
}];

stack(data);
stack(data);
stack(data);
plot();
```

実行

```console
$ yarn ts-node src/index.ts
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/330514/ab71ecf3-340b-bdfe-742e-23c3e4bbfaae.png)

できました。同じグラフが３つ表示されました。
公式GIFにもありますが、処理が完了するとデフォルトのブラウザが開いてグラフが表示されます。

ちょっとコードを見てみますがまあ簡単ですね。
`x`,`y`のグラフのデータを指定して`type`でグラフの形式を指定する。
指定できるデータ形式はTypescriptの型推論で教えてくれるので、非常に楽ちんです。(これがあるからNode.jsで書きたい)

描画には`stack`と`plot`メソッドが使われています。
`stack`メソッドを複数コールすることで複数グラフを並べることができるみたいですね。サンプルでは同じデータを渡していますが、全く違うデータ形式でも可能です。(折れ線グラフ、円グラフ、棒グラフなど)

ちなみに`stack`なしで、`plot`にデータを直接渡してもグラフ描画可能です。
その場合は３回呼ぶとタブが３つに別れます。

```diff
- stack(data);
- stack(data);
- stack(data);
- plot();
+ plot(data);
+ plot(data);
+ plot(data);
```

データ量にもよりますが、複数のグラフを`plot`で描画するとNode.js・ブラウザ共に重くなってしまうので、２つ別々に並べて見比べたいということがなければ`stack`で縦に並べることをおすすめします。(最初plotだけでやったら８コア全てを使い切ってCPU100%でフル回転してました)

その他にもサンプルがありますが、ここから先は`Plotly.js`の使い方の話になってくるのでやめておきます。
`Plotly.js`のまとめ記事を見てもらったほうが良いと思います。

# 動作の仕組み

なんとなく予想はつきますが、フロントのコードなしでどうやってるのかな？というのが気になりましたが、仕組みはREADMEの[Behind the scenes](https://github.com/ngfelixl/nodeplotlib#behind-the-scenes)に下記のように記載されていました。

> The lib launches a webserver and opens new tabs for every plot located at http://localhost:8080/plots/:id. At this address a temporary html template file, the nodeplotlib script and plotly.min.js are available. The client side js requests the plot data at http://localhost:8080/data/:id. After all pending plots are opened in a unique tab and all the data is requested, the server shuts down. If you fire another plot the server starts again provides your plot and shuts down automatically.

グラフ描画中だけ一時的なWebサーバを建てておいて、Plotly.jsでの描画完了時に落としているようです。
画面描画のためのコードはライブラリ側で持ってくれているのでお手軽に使えるわけですね。
フロントのコードの中身は https://github.com/ngfelixl/nodeplotlib/tree/master/src/www にありました。

ちなみにブラウザをリロードすると404ページになってしまうので注意してください。リロード時点ではサーバが落ちているので

# おわりに

非常にお手軽にグラフ表示ができてよかったです。
個人的に結構ありがたいライブラリだったのでどんどん活用していきたいです。