line_compare#
Compare WebGL, SVG with canvas line.
import numpy as np
from bokeh.layouts import column, row
from bokeh.models import CustomJS, Dropdown, Slider
from bokeh.plotting import figure, show
p1 = figure(title="Canvas", width=400, height= 400, output_backend="canvas")
p2 = figure(title="SVG", width=400, height= 400, output_backend="svg")
p3 = figure(title="WebGL", width=400, height= 400, output_backend="webgl")
ys = 10  # yscale, to increase anisotropy
lines = []
for p in (p1, p2, p3):
    t = np.linspace(0, 2 * np.pi, 50)
    x = np.sin(t) * 10
    y = np.cos(t) * 10
    l1 = p.line(x, y * ys, color="#2222aa",
                line_width=6, line_cap='butt',
                line_join='round', line_dash=(10, 6, 3, 6, 3, 6))
    t = np.linspace(0, 4 * np.pi, 150)
    x = t - 5
    y = np.sin(t) + 5
    l2 = p.line(x, y * ys, color="#22aa22",
                line_width=6, line_cap='butt', line_join='round')
    t = np.arange(10)
    x = t - 5
    y = 0.3 * (t + 1) * ((t % 2) * 2 - 1) - 6
    l3 = p.line(x, y * ys, color="#aa2222",
                line_width=6, line_cap='butt',
                line_join='round', line_dash=(10, 10))
    l4 = p.line(y, x * ys, color="#aa2222",
                line_width=6, line_cap='butt',
                line_join='round', line_dash=(10, 10))
    lines.extend([l1, l2, l3, l4])
def make_callback(widget, prop):
    return
def make_slider(prop, start, end, value):
    slider = Slider(title=prop, start=start, end=end, value=value)
    cb = CustomJS(args=dict(lines=lines, prop=prop), code="""
        for (let i = 0; i < lines.length; i++) {
            const glyph = lines[i].glyph;
            glyph[prop] = cb_obj.value;
        }
    """)
    slider.js_on_change('value', cb)
    return slider
def make_dropdown(prop, menu):
    dropdown = Dropdown(label=prop, menu=menu)
    cb = CustomJS(args=dict(lines=lines, prop=prop), code="""
        for (let i = 0; i < lines.length; i++) {
            const glyph = lines[i].glyph;
            glyph[prop] = cb_obj.item;
        }
    """)
    dropdown.js_on_event("menu_item_click", cb)
    return dropdown
sliders = [
    make_slider('line_width', start=0.2, end=16, value=5),
    make_slider('line_dash_offset', start=0, end=100, value=1),
    make_dropdown('line_cap', [("butt", "butt"), ("round", "round"), ("square", "square")]),
    make_dropdown('line_join', [("miter", "miter"), ("round", "round"), ("bevel", "bevel")]),
]
sliders = column(*sliders)
show(row(column(sliders), column(p1, p2, p3)))