Sherman-Morrison/ci/vfc_ci_report/plot.py
2021-05-03 15:47:44 +02:00

143 lines
4.3 KiB
Python

# General functions for filling plots with data in all report's views
from bokeh.plotting import figure
from bokeh.models import HoverTool, TapTool, CustomJS
from math import pi
def fill_dotplot(
plot, source, data_field,
tooltips=None, tooltips_formatters=None,
js_tap_callback=None, server_tap_callback=None,
lines=False,
lower_bound=False
):
# (Optional) Tooltip and tooltip formatters
if tooltips is not None:
hover = HoverTool(tooltips=tooltips, mode="vline", names=["circle"])
if tooltips_formatters is not None:
hover.formatters = tooltips_formatters
plot.add_tools(hover)
# (Optional) Add TapTool (for JS tap callback)
if js_tap_callback is not None:
tap = TapTool(callback=CustomJS(code=js_tap_callback))
plot.add_tools(tap)
# (Optional) Add segment to represent a lower bound
if lower_bound:
lower_segment = plot.segment(
x0="%s_x" % data_field, y0=data_field,
x1="%s_x" % data_field, y1="%s_lower_bound" % data_field,
source=source, line_color="black"
)
# Draw dots (actually Bokeh circles)
circle = plot.circle(
name="circle",
x="%s_x" % data_field, y=data_field, source=source, size=12
)
# (Optional) Draw lines between dots
if lines:
line = plot.line(x="%s_x" % data_field, y=data_field, source=source)
# (Optional) Add server tap callback
if server_tap_callback is not None:
circle.data_source.selected.on_change("indices", server_tap_callback)
# Plot appearance
plot.xgrid.grid_line_color = None
plot.ygrid.grid_line_color = None
plot.yaxis[0].formatter.power_limit_high = 0
plot.yaxis[0].formatter.power_limit_low = 0
plot.yaxis[0].formatter.precision = 3
plot.xaxis[0].major_label_orientation = pi / 8
def fill_boxplot(
plot, source,
prefix="",
tooltips=None, tooltips_formatters=None,
js_tap_callback=None, server_tap_callback=None
):
# (Optional) Tooltip and tooltip formatters
if tooltips is not None:
hover = HoverTool(tooltips=tooltips, mode="vline", names=["full_box"])
if tooltips_formatters is not None:
hover.formatters = tooltips_formatters
plot.add_tools(hover)
# (Optional) Add TapTool (for JS tap callback)
if js_tap_callback is not None:
tap = TapTool(callback=CustomJS(code=js_tap_callback))
plot.add_tools(tap)
# Draw boxes (the prefix argument modifies the fields of ColumnDataSource
# that are used)
if prefix != "":
prefix = "%s_" % prefix
# Stems
top_stem = plot.segment(
x0="%sx" % prefix, y0="%smax" % prefix,
x1="%sx" % prefix, y1="%squantile75" % prefix,
source=source, line_color="black"
)
bottom_stem = plot.segment(
x0="%sx" % prefix, y0="%smin" % prefix,
x1="%sx" % prefix, y1="%squantile25" % prefix,
source=source, line_color="black"
)
# Boxes
full_box = plot.vbar(
name="full_box",
x="%sx" % prefix, width=0.5,
top="%squantile75" % prefix, bottom="%squantile25" % prefix,
source=source, line_color="black"
)
bottom_box = plot.vbar(
x="%sx" % prefix, width=0.5,
top="%squantile50" % prefix, bottom="%squantile25" % prefix,
source=source, line_color="black"
)
# Mu dot
mu_dot = plot.dot(
x="%sx" % prefix, y="%smu" % prefix, size=30, source=source,
color="black"
)
# (Optional) Add server tap callback
if server_tap_callback is not None:
top_stem.data_source.selected.on_change("indices", server_tap_callback)
bottom_stem.data_source.selected.on_change(
"indices", server_tap_callback)
full_box.data_source.selected.on_change("indices", server_tap_callback)
bottom_box.data_source.selected.on_change(
"indices", server_tap_callback)
mu_dot.data_source.selected.on_change("indices", server_tap_callback)
# Plot appearance
plot.xgrid.grid_line_color = None
plot.ygrid.grid_line_color = None
plot.yaxis[0].formatter.power_limit_high = 0
plot.yaxis[0].formatter.power_limit_low = 0
plot.yaxis[0].formatter.precision = 3
plot.xaxis[0].major_label_orientation = pi / 8