""" Automation and data acquisition """
from itertools import cycle
from bokeh.plotting import figure
from bokeh.plotting import show as show_
from bokeh.palettes import Category10_8 as palette
from bokeh.models import Legend
from bokeh.layouts import gridplot
from numpy import arange, random
[docs]def plot(x, ys, xlabel, ylabel, n_markers=10, legend_labels=None, fig_kwargs=None, plot_kwargs=None):
"""Cleaned-up line chart implementation using sparse markers with random offsets"""
colors = cycle(palette[::-1]) # one color more than marker shapes -> rarely repeat combination
markers = cycle(["diamond", "+", "inverted_triangle", "x", "o", "square", "triangle", "*", "ox"])
fig_kwargs = fig_kwargs or dict(plot_width=800, plot_height=250)
plot_kwargs = plot_kwargs or {}
f = figure(**fig_kwargs)
f.xaxis.axis_label = xlabel
f.yaxis.axis_label = ylabel
f.grid.grid_line_alpha = 1.0
for i, y in enumerate(ys):
color = next(colors)
plot_kwargs.update({"color": color})
f.line(x, y, **plot_kwargs)
stride = int(len(x) / max(n_markers, 1))
offset = int(random.uniform(0, stride))
marker_inds = arange(offset, len(x), stride)
if legend_labels is not None:
f.scatter(x[marker_inds], y[marker_inds], legend_label=legend_labels[i],
marker=next(markers), color=color)
else:
f.scatter(x[marker_inds], y[marker_inds], marker=next(markers), color=color)
if legend_labels is not None:
f.legend.visible = False
legend = Legend(items=f.legend.items, location=(0, 0))
legend.label_text_font_size = '8pt'
legend.spacing = -8
legend.padding = 2
f.add_layout(legend, "right")
return f
[docs]def show(*figures):
"""Quickly show a list of figures as a 1xN grid"""
show_(gridplot([[f] for f in figures]))