Plotly は対話型視覚化ライブラリである。中身はJavaScriptだがPythonやRなどで操作できる。
ここでは,私の平均身長の推移のデータをimabari_ehimeさんがPlotlyでグラフ化された平均身長の推移をplotlyでグラフ化という記事を参考にして,Plotlyを触ってみよう。
まずは pip install plotly
などとしてインストールする。
import pandas as pd
pd.options.plotting.backend = "plotly"
df = pd.read_csv("https://okumuralab.org/~okumura/python/data/height.csv",
index_col=0)
fig = df[["男17歳", "男16歳", "男15歳"]].plot(markers=True)
ここまででは何も起こらない。ここで
fig.show()
と打ち込むと,http://127.0.0.1:53999 のようなアドレスがデフォルトのWebブラウザで開き,グラフが表示される。マウスで範囲指定すれば,その部分が拡大表示される。図をダブルクリック(スマホならダブルタップ)するか右上の「🏠 Reset axes」ボタンを押せば元のサイズに戻る。「📷 Download plot as a png」でPNG画像としてダウンロードできる。
対話型のままの図をWebで公開するには,いくつかの方法がある。まず
fig.write_html("fig.html")
で,スタンドアローンの巨大なHTMLファイルができる。
別ページにインクルードするための軽い図を出力するには,例えば
fig.write_html("fig.html", include_plotlyjs=False, full_html=False, default_width=800, default_height=600)
のようにする(default_width="100%"
でブラウザの幅いっぱいの図になる)。これを別ページにコピペすればよい(あるいは何らかの方法でインクルードする)。別ページのヘッダには次の2行を入れておく:
<script>window.PlotlyConfig = {MathJaxConfig: 'local'};</script> <script src="https://cdn.plot.ly/plotly-2.9.0.min.js"></script>
これを実際に行うと,次のようになる:
範囲指定したりして対話型に動作することを確認されたい。
上と同じ図を Plotly Express の折れ線グラフを使って描いてみよう:
import pandas as pd import plotly.express as px df = pd.read_csv("https://okumuralab.org/~okumura/python/data/height.csv") fig = px.line(df, x='年度', y=["男17歳", "男16歳", "男15歳"], markers=True) fig.write_html("fig.html", include_plotlyjs=False, full_html=False, default_width=800, default_height=600)
結果は上とほぼ同じなので省略する。
棒グラフの例として,毎日の東京都のCOVID-19感染確認者数:
import pandas as pd
import plotly.express as px
df = pd.read_csv("https://okumuralab.org/~okumura/python/data/COVID-tokyo.csv")
fig = px.bar(df.query('date >= "2022-01-01"'), x='date', y='confirmed')
fig.write_html("fig.html", include_plotlyjs=False, full_html=False,
default_width=800, default_height=600)
棒の幅を丸一日(86400000ミリ秒)に広げたいときは fig = ...
の次に fig.update_traces(width=86400000)
を入れる。
fig.write_html()
が吐き出すHTMLは <div id="..." class="plotly-graph-div" style="height:600px; width:800px;"></div>
のような図の入れ場所以外はJavaScriptコードなので,これらを分離すれば,インクルードがより簡単にできる。
具体的には,例えば次のようにする:
import re (グラフを描く部分は略) fig.write_html("fig.html", include_plotlyjs=False, full_html=False, default_width=800, default_height=600, div_id="plotly_ex1") with open("fig.html") as f: text = f.read() m = re.search('(<div id="(.*?)".*?</div>) *<script type="text/javascript"> *(.*) *</script>', text) if m: div = m[1] id = m[2] js = m[3] js = re.sub(" *", "\n", js) print(div) print('<script src="js/' + id +'.js"></script>') with open(id + ".js", "w") as f: f.write(js)
標準出力に出力される2行だけをHTMLにコピペし,ファイルとして出力されるJavaScriptコードを js/
サブディレクトリに入れる。最終的にこのページはそのようにして作った。
なお,style="height:600px; width:800px;"
の代わりに style="max-width:100%"
とするとブラウザの幅になる。自殺統計の図はそのようにした。どちらが使いやすいであろうか。
Last modified: