LoginSignup
5
2

More than 1 year has passed since last update.

Livebook 事始め (Elixir)

Last updated at Posted at 2022-10-26

Livebook は Elixir版 Jupyter Notebook と言われているものです。私も PythonJuliaJupyter Notebook を少しだけ使ったことがあり、ちょっとした利用には大変便利だと感じていたので、Livebook も試してみました。

すこし驚いたのが、LivebookPhoenix LiveView のアプリケーションだということです。とても安定して動いているし、機能も結構豊富だということです。特にVegaLiteKino を使って高度なグラフを描くことができるのは大変魅力的です。

関連記事
VegaLite で埼玉県を切る( Elixir, Livebook) - Qiita
Vega-Lite の View Composition (Elixir, Livebook) - Qiita
VegaLite の基礎 (Elixir, Livebook) -Qiita
Livebook 事始め (Elixir) - Qiita

この記事は 「東京電力電力供給状況監視 - Livebook」 というタイトルにすべきものでしたが、記事の趣旨が Livebook の使用感にあるため表記のタイトルとしました。
東京電力電力供給状況監視 - Phoenix LiveView

1. VegaLite と Kino について

Livebook

Livebook は Elixir版 Jupyter Notebook です

docker で動かす
docker run -p 8080:8080 -p 8081:8081 --pull always livebook/livebook

Livebook のインストール

git clone https://github.com/livebook-dev/livebook.git
cd livebook
mix deps.get --only prod

Windows コマンドプロンプトでの起動

set MIX_ENV=prod
mix phx.server

起動エラー時に試してみること

iex --sname foo

VegaLite

VegaLiteVega-LiteElixir bindings です。
Vega-Lite is ハイレベルな、会話的グラフィックのための文法です。(D3.jsは低レベル)。それは宣言的な JSON 文法を使います。VegaLite でも JSON 文法を使うことができるようですが、主に Elixir の文法が使われます。

Kino

KinoLivebook で使われるライブラリで、Elixir コードを使って直接リッチでインタラクティブな描画を可能とするものです。
Kino は単独でも使われますが、Kino.VegaLite という形で VegaLite とともに使われることが一般的です。
しかし Kino v0.5.2 までは Kino.VegaLite がドキュメントにあるのですが、Kino v0.6.0 以降は消えています。代わりに以下の別パッケージを使うみたいです。(名前にドットが入っていないだけなので勘違いしそうですが。)関数の説明などは Kino v0.5.2 の方を参照した方が良いです。

2. Livebook のコード

必要なパッケージをインストールします。

Mix.install([
  {:vega_lite, "~> 0.1.6"},
  {:kino_vega_lite, "~> 0.1.4"},
  {:httpoison, "~> 1.8"} 
])

alias VegaLite, as: Vl

VegaLiteKino でグラフを描きます。グラフは5分おき(300000 ms)に自動更新されます。

chart =
  Vl.new(width: 600, height: 300)
  |> Vl.mark(:line)
  |> Vl.encode_field(:x, "x", type: :quantitative )
  |> Vl.encode_field(:y, "y", type: :quantitative, scale: [domain: [3100,3400]] )
  |> Kino.VegaLite.new()
  |> Kino.render()


Kino.VegaLite.periodically(chart, 300000, 0, fn i ->
  denki =
    case HTTPoison.get("http://tepco-usage-api.appspot.com/quick.txt") do
      {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> body
      {:ok, %HTTPoison.Response{status_code: 404}} -> "0,0,0"
      {:error, %HTTPoison.Error{reason: _reason}} -> "0,0,0"
    end
  [_, y, _] = String.split(denki, ",")
  point = %{x: i, y: String.to_integer(y)}
  Kino.VegaLite.push(chart, point)
  {:cont, i + 1}
end)

コードは以上なのですが、驚くほど短いです

2. 動作画像

コードとグラフが同時にキャプチャーできるなんて、Livebook っぽくてかっこいいですね。
image.png

3. Kino や VegaLite 関数の説明

new(opts \\ [])

VegaLite struct でラッピングされた新しい specification を返します。

Kino.VegaLite.new(vl)

引数の VegaLite 定義で widget process をスタートします。

Kino.render(term)

引数の term を render します。

encode_field(vl, channel, field, opts \\ [])

Adds field encodingspecification に追加します。

  |> Vl.encode_field(:y, "y", type: :quantitative, scale: [domain: [3100,3400]] )

ここでは opts として type: オプションと scale: オプションを指定しています。

Kino.VegaLite.periodically(widget, interval_ms, acc, fun)

KinoVegaLite のドキュメントには明記されてませんが、Kino.VegaLite v0.5.2 のドキュメントには以下の関数があり、そのまま KinoVegaLite でも使えるみたいです。

  • widget process を定期的に走らせるための callback を登録する関数
  • callback は **interval_ms ** ミリ秒ごとに走る
  • そして accumulated value を受け取る
  • callback 以下の2つのうちどれかをリターンしなければならない
    * {:cont, acc} - 新しい accumulated valuecallback を続ける
    * :halt - もはや callback のスケジュールを停止する

今回は以上です。
コード自体は、本当に驚くほど短くて、素晴らしいプラットフォームだと感じました。しかし VegaLite の機能が豊富すぎるし、独特なので、少なからぬ試行錯誤を要しました。ドキュメントを読みこなす慣れが必要です。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2