Files
kabuki/plot1d.py

89 lines
2.2 KiB
Python

import numpy as np
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource, Band, Whisker
from bokeh.palettes import Category10_10
from buki import Object
BLUE = Category10_10[0]
RED = Category10_10[3]
class Plot1D(Object):
def __init__(self, name=None):
data = {
"x": [],
"y": [],
# "y-std": [],
# "y+std": [],
"avg": [],
# "avg-err": [],
# "avg+err": [],
}
self.source = source = ColumnDataSource(data=data)
fig = figure(name=name)
line1, circle1, errband1, errbars1 = add_curve(fig, source, "x", "y", "y-std", "y+std", BLUE)
line2, circle2, errband2, errbars2 = add_curve(fig, source, "x", "avg", "avg-err", "avg+err", RED)
# line1.visible = line2.visible = False
# circle1.visible = circle2.visible = False
# errband1.visible = errband2.visible = False
# errbars1.visible = errbars2.visible = False
super().__init__(fig)
def set(self, times, values):
y = values[-1]
if y is None: #TODO: is this needed?
return
n = len(values)
values = np.asarray(values)
x = np.arange(len(y))
std = values.std(axis=0)
#TODO: skip avg for n=1 ?
avg = values.mean(axis=0)
err = std / np.sqrt(n)
data = {
"x": x,
"y": y,
"y-std": y - std,
"y+std": y + std,
"avg": avg,
"avg-err": avg - err,
"avg+err": avg + err,
}
self.source.data.update(data)
def add_curve(fig, source, x, y, lower, upper, color):
line = fig.line(x=x, y=y, source=source, color=color)
circle = fig.circle(x=x, y=y, source=source, color=color)
errband = Band(base=x, lower=lower, upper=upper, source=source, level="underlay", line_width=1, line_color=color, fill_color=color, fill_alpha=0.5)
errbars = Whisker(base=x, lower=lower, upper=upper, source=source, line_color=color)
errbars.lower_head.line_color = color
errbars.upper_head.line_color = color
fig.add_layout(errband)
fig.add_layout(errbars)
return line, circle, errband, errbars