I am Charmie

メモとログ

export interactive Bokeh plot to csv

目的

オンラインで学生実験を行うためのwebアプリ開発 - コンデンサの充放電の実験

作ってみたサンプル

Bokehのサンプルプログラムを改造して,サインカーブの一部をcsvとして保存するページを作った.

charmie11.github.io

要件

  • github上で公開可能 (インストール不要)
  • 各種パラメータをインタラクティブに設定可能
  • 変更したパラメータを基にグラフを表示
    • 表示しているグラフのデータをcsvで出力

検討

Bokehを採用 - 対話的プロットツールとしてBokehplotlyを検討 - パラメータ調整: 両者ともWidget(ボタン,スライダー,ドロップダウンリスト)を使えばできる - Bokeh - plotly - csv出力: Bokehは公式レポジトリにサンプルがあった!! - Bokeh - plotly

サンプル

Bokehのサンプルプログラムを改造してみた.
pyファイルと同じディレクトリにdownload.jsを保存すれば動作する.

from os.path import dirname, join
import numpy as np

from bokeh.layouts import column, row
from bokeh.models import (Button, CustomJS, Slider)
from bokeh.plotting import ColumnDataSource, figure, show


if __name__ == '__main__':

    x = np.linspace(0, 10, 500)
    y = np.sin(x)

    s1 = ColumnDataSource(data=dict(x=x, y=y))
    s2 = ColumnDataSource(data=dict(x=x, y=y))
    plot = figure(x_range=(x.min(), x.max()),
                  y_range=(y.min(), y.max()),
                  plot_width=400, plot_height=400)
    plot.line('x', 'y', source=s2, line_width=3, line_alpha=0.6)

    slider = Slider(start=x.min(), end=x.max(), value=0.0, step=.1, title="x threshold")
    code_slider = """
        var d1 = s1.data;
        var d2 = s2.data;
        var threshold = slider.value
        d2['x'] = []
        d2['y'] = []
        for (var i = 0; i < d1['x'].length; i++) {
            if(d1['x'][i] > threshold){
                d2['x'].push(d1['x'][i])
                d2['y'].push(d1['y'][i])
            }
        }
        s2.change.emit();
    """
    callback_slider = CustomJS(args=dict(s1=s1, s2=s2, slider=slider),
                               code=code_slider)
    slider.js_on_change('value', callback_slider)

    button = Button(label="Download", button_type="success")
    callback_button = CustomJS(args=dict(source=s2),
                               code=open(join(dirname(__file__), "download.js")).read())
    button.js_on_click(callback_button)

    show(row(plot, column(slider, button)))