ars_noise_measurement/bokehtest.py

80 lines
2.4 KiB
Python

from dataclasses import fields
from typing import Iterable, Sequence
from bokeh.core.enums import SizingMode, SizingModeType
from bokeh.io import curdoc
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, MultiChoice, Select
from bokeh.plotting import figure
import pickle
from measurement_station import OpPointData
def oppoint_data_src(p: OpPointData) -> dict[str, float]:
ret = {}
# print(fields(p.data_thrust_stand_avg)[0])
ret.update({k: v for k, v in field_entries(p.data_thrust_stand_avg).items()})
return ret
def field_entries(datacls) -> dict[str, float]:
fnames = [f.name for f in fields(datacls)]
return {n: getattr(datacls, n) for n in fnames}
def read_series(fname: str) -> dict[int, OpPointData]:
with open(fname, 'rb') as f:
return pickle.load(f)
def series_dataclosrc(series: dict[int, OpPointData]) -> ColumnDataSource:
# entries = [field_entries(v) for v in series.values()]
entries = [oppoint_data_src(p) for p in series.values()]
keys = entries[0].keys()
data = { key: [e[key] for e in entries] for key in keys }
return ColumnDataSource(data)
filespeed = 15
files = [ f'./dmuch/gf7035_v{filespeed}.pickle', f'./dmuch/gf7042_v{filespeed}.pickle', f'./dmuch/apc838_v{filespeed}.pickle', f'./dmuch/apc938_v{filespeed}.pickle', f'./dmuch/ep_v{filespeed}.pickle' ]
series = [ read_series(f) for f in files ]
print(oppoint_data_src(series[0][1500]))
print(series_dataclosrc(series[0]))
sources = [series_dataclosrc(s) for s in series]
keys = list(sources[0].data.keys())
p = figure(title="Dynamic Column Plot", x_axis_label='Index', y_axis_label='Value', tools=['hover', 'pan', 'xwheel_zoom'])
p.sizing_mode = 'scale_both' # type: ignore
multi_choice = MultiChoice(title="Choose Columns to Plot", options=keys)
xsel = Select(title="Y axis:", value="cos", options=keys)
colors = ['blue', 'green', 'red', 'yellow', 'orange']
def update_plot(attr, _, new_values):
p.renderers = [] # type: ignore
for source, fname, color in zip(sources, files, colors):
for column in multi_choice.value: # type: ignore
p.line(x=xsel.value, y=column, source=source, legend_label=f'{fname} {column}', line_width=2, color=color)
multi_choice.on_change('value', update_plot)
xsel.on_change('value', update_plot)
layout = column(multi_choice, xsel, p)
layout.sizing_mode = 'scale_both' # type: ignore
curdoc().add_root(layout)