よちよちpython

独習 python/Qpython/Pydroid3/termux/Linux

【Matplotlib、Bokeh、Plotly】グラフライブラリ主要3種類で時系列折れ線グラフを描く

今回は、3種類のグラフ描画ライブラリMaplotlibBokehPlotlyで簡単な時系列データの折れ線グラフを描きます。



はじめに

前回FlaskPandasを使って、データフレームから生成したテーブルをWebページに表示する簡単なアプリを作りました。

Pandasを使うなら、次はグラフ表示だろう!


グラフをWebページに表示させるにはどうしたらいい?

まず思い付いたのは Matplotlib を使った方法。多くの人がPythonで最初に触るグラフ描画ライブラリだろう。png・jpg・svgなどの画像ファイルとして保存できますので、imgタグで貼り付ければWebに表示出来るだろうと。しかしこの方法は全ユーザーに同一の画像を表示させる場合は良いかも知れないが、ユーザー毎のアクションによってグラフが変わるような場合は好ましくない感じ。



検索してみると、 【Python】Flask+MatplotlibでWebアプリにプロットしたグラフを表示する | ミナピピンの研究室 では画像データをioライブラリでバイナリデータを渡して表示させる方法がとられている。



他にどんな方法があるだろうか。
Pythonのグラフ描画ライブラリのポピュラートップ3は、順に

  1. Matplotlib
  2. Bokeh
  3. Plotly

だそうです。

BokehPlotlyで作ったグラフはインタラクティブ(対話的)にマウスで操作したりできるようになっており、htmlコードでも取り出すことが出来るようだ。
Plotlyに関しては元々JavaScriptのライブラリで、グラフをWebに表示するDashというPythonライブラリが既にあるようです。DashPlotlyのグラフをwebで表示し簡単にダッシュボード(※複数の情報源からデータを集め、概要をまとめて一覧表示する機能や画面、ソフトウェアなどを指す)にできるWebアプリ。バックでFlaskが動いている。これで済むならこれが一番早いかな。



BokehPlotlyは初めて触る。全てのグラフライブラリの書き方が統一されてれば楽なんだが・・・・



実行環境

  • Windows10 Home
  • Python3.9.7
  • Jupyter Notebook 6.4.5
  • 外部ライブラリ
    • matplotlib 3.5.0
    • bokeh 2.4.2
    • plotly 5.5.0



グラフ描画

3種類のライブラリでグラフを描いていきます。その前に適当なデータを作る。

時系列データを適当に生成

import pandas as pd
import random
random.seed(0)

# 売上データを生成
df = pd.DataFrame({
    '日付' : pd.date_range(start='2021/1/1', freq='d', periods=365),
    '数量' : random.choices(range(1,1001), k=365)
})

# 日付をインデックスに変更
df = df.set_index('日付')

# 表示
df
数量
日付
2021-01-01 845
2021-01-02 758
2021-01-03 421
2021-01-04 259
2021-01-05 512
... ...
2021-12-27 36
2021-12-28 149
2021-12-29 257
2021-12-30 785
2021-12-31 843

365 rows × 1 columns



◇ matplotlibを使って描く

ライブラリのインストールは、ターミナルから

# condaの場合
conda install -c conda-forge matplotlib

# pipの場合
pip install matplotlib

Anaconda参照 : https://anaconda.org/conda-forge/matplotlib

import matplotlib.pyplot as plt
import japanize_matplotlib  # 日本語文字化け対応用

plt.plot(df)
plt.grid()
plt.title("時系列データ matplotlib")
plt.xlabel("日付")
plt.ylabel("値")

plt.savefig('mat.jpg')
plt.show()

f:id:chayarokurokuro:20220120173742j:plain
matplotlib



◇ Bokehを使う

ライブラリのインストールは、ターミナルから

# condaの場合
conda install -c bokeh

# pip の場合
pip install bokeh

Anaconda参照: https://anaconda.org/anaconda/bokeh

from bokeh.plotting import figure, show
from bokeh.io import output_notebook
output_notebook()    # Notebookに出力させる(省略するとブラウザの別タブに出力される)


# x,y軸のデータ
X = df.index
Y = df['数量']

# グラフの設定
p = figure(x_axis_type="datetime",  #X軸のタイプを設定
           plot_height=350,         # グラフの高さ設定
           plot_width=800,          # グラフの幅設定
           title="時系列データ"    # グラフのタイトル設置
          )

# プロット
p.line(x=X, y=Y)

# グラフの装飾等
p.xgrid.grid_line_color='gray'
p.ygrid.grid_line_alpha=0.5
p.xaxis.axis_label = '日付'
p.yaxis.axis_label = '値'

# 表示
show(p)

f:id:chayarokurokuro:20220120173610g:plain
Bokeh


ボタンでPNG画像に保存できるようにもなっている。



◇ Plotlyを使う

ライブラリのインストールは、ターミナルから

# condaの場合 
conda install -c conda-forge plotly

# pipの場合
pip install plotly

Anaconda参照: https://anaconda.org/conda-forge/plotly

from plotly.graph_objs import Scatter
from plotly.graph_objs import Scatter, Figure, Layout
from plotly.offline import init_notebook_mode, iplot
init_notebook_mode()    # Notebookに出力

# x,y軸のデータ
X = df.index
Y = df['数量']

# データを散布図に設定
scatter1 = Scatter(x=X, y=Y)

# レイアウト設定
fig = Figure(data=[scatter1], layout=Layout(width=800, height=400))

# 表示
iplot(fig)    # Notebookに出力するにはiplot関数を使う

f:id:chayarokurokuro:20220120173821g:plain
plotly


こちらもBokeh同様、ボタンでPNG画像に保存できるようにもなっている。



おわりに

3種類のライブラリのインストールと実行確認が出来た。 次回からは個別でFlaskのWebページへの表示方法を見ていく。BokehとPlotlyはhtmlで取り出してしまえば出来ると思う。簡単ならいいが・・・ BokehとPlotlyの日本語サイトが少ない。調べるのに時間がかかりそうなのでFlaskへのグラフ表示は出来次第、ということにします。



以上です。

参考リンク