4
6

More than 3 years have passed since last update.

DataframeからBokeh(Rangetoolとselect)でインタラクティブなグラフを描こう

Last updated at Posted at 2020-03-22

概要

 普段はArduinoやM5stackなどのマイコンやガジェットをいじってるのですが、何台もセンサーをつないでデータが集まったのはいいものの、それをインタラクティブに可視化する手段があまりない。何かいいのはないか?ということでBokehを見つけて勉強を始めました。
 ところが日本語の参考になる記事は多くなく公式ドキュメントGallery-Bokeh 2.0.0 Documentation、Qiita記事を参考にしましたがなかなか苦労したのでこの記事を見て役に立てれば幸いです。

完成したグラフ

 読み込んだcsvをDataframeにし、X-AxisとY-Axisにcsv内のcolumnをSelectを使って選択しグラフ化しています。下グラフの選択範囲をRangetoolで選択し拡大画像が上に描画されるようにしています。
 なお今回csvはcsvからbokehグラフ出力の記事のcsvをそのままお借りしています。本来はcolumnが2種類以上あるcsvであればどんなデータでも問題ありません。
image.png

実行環境

Windows10
Anaconda
Python3.7
pandas1.0.1
Bokeh 1.4

ソースコード

range_select.py
import pandas as pd
from bokeh.io import curdoc
from bokeh.layouts import column, layout, row
from bokeh.models import  RangeTool, Select
from bokeh.plotting import figure

df = pd.read_csv('bachelors.csv')
columns = sorted(df.columns)

#create figure function
def create_figure():
    xs = df[x.value].values
    ys = df[y.value].values
    x_title = x.value.title()
    y_title = y.value.title()

    kw = dict()
    kw['title'] = "%s vs %s" % (x_title, y_title)

    p = figure(plot_height=250, plot_width=600, tools="pan,box_zoom,reset,save",
                 **kw,x_range=(xs[10], xs[15]))

    p.xaxis.axis_label = x_title
    p.yaxis.axis_label = y_title
    p.line(x=xs, y=ys)

    range_select = figure(title="選択ボックスの中央と端をドラッグして、上の範囲を変更します。",
                plot_height=250, plot_width=600, y_range=p.y_range,
                tools="", toolbar_location=None )

    range_tool = RangeTool(x_range=p.x_range)
    range_tool.overlay.fill_color = "navy"
    range_tool.overlay.fill_alpha = 0.2

    range_select.line(x=xs, y=ys)
    range_select.ygrid.grid_line_color = None
    range_select.add_tools(range_tool)
    range_select.toolbar.active_multi = range_tool
    range_select.xaxis.axis_label = x_title
    range_select.yaxis.axis_label = y_title

    controls = column(x, y, width=200)
    graph = column(p, range_select)

    return controls, graph

#update function
def update(attr, old, new):
    layout.children[:] = create_figure()[:]

#create select widget
x = Select(title='X-Axis', value='Year', options=columns)
x.on_change('value', update)

y = Select(title='Y-Axis', value='Agriculture', options=columns)
y.on_change('value', update)

controls = column(x, y, width=200)
graph = create_figure()[1]
layout = row(controls, graph)

curdoc().add_root(layout)

実行方法

以下をターミナルで打ち込み実行すると、Bokeh serverが立ち上がりローカルホストからctrl+クリックでブラウザにグラフを表示させることができます。

bokeh serve range_select.py

image.png

おわりに

インタラクティブなグラフが手軽にできると見てるだけで結構楽しいです。60行程度のコードでできるのも驚きです。
Dataframeでグラフ化できると機械学習モデルの結果を同時に表示させたりsqlから多種のデータを読みこんで描画させたり、など応用が広がってよさそうです。

参考

Gallery-Bokeh 2.0.0 Documentation
@kimisyoさんのBokeh記事@Qiita
csvからbokehグラフ出力

4
6
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
4
6