Itâs often useful to link plots to add connected interactivity between plots. This section shows an easy way to do this, using the bokeh.plotting interface.
Linked panning#Itâs often desired to link pan or zooming actions across many plots. All that is needed to enable this feature is to share range objects between figure()
calls.
from bokeh.layouts import gridplot from bokeh.plotting import figure, show x = list(range(21)) y0 = x y1 = [20-xx for xx in x] y2 = [abs(xx-10) for xx in x] # create a new plot s1 = figure(width=250, height=250, title=None) s1.scatter(x, y0, size=10, color="navy", alpha=0.5) # create a new plot and share both ranges s2 = figure(width=250, height=250, x_range=s1.x_range, y_range=s1.y_range, title=None) s2.scatter(x, y1, size=10, marker="triangle", color="firebrick", alpha=0.5) # create a new plot and share only one range s3 = figure(width=250, height=250, x_range=s1.x_range, title=None) s3.scatter(x, y2, size=10, marker="square", color="olive", alpha=0.5) p = gridplot([[s1, s2, s3]], toolbar_location=None) show(p)
Now you have learned how to link panning between multiple plots with the bokeh.plotting interface.
A more sophisticated example of a linked scatterplot matrix can be found in the SPLOM section of the Statistical plots chapter.
Linked brushing#Linked brushing in Bokeh is expressed by sharing data sources between glyph renderers. This is all Bokeh needs to understand that selections acted on one glyph must pass to all other glyphs that share that same source. To see how linked selection extends to glyph renderers that plot only a subset of data from a data source, see Linked selection with filtered data.
The following code shows an example of linked brushing between circle glyphs on two different figure()
calls:
from bokeh.layouts import gridplot from bokeh.models import ColumnDataSource from bokeh.plotting import figure, show from bokeh.sampledata.penguins import data from bokeh.transform import factor_cmap SPECIES = sorted(data.species.unique()) TOOLS = "box_select,lasso_select,help" source = ColumnDataSource(data) left = figure(width=300, height=400, title=None, tools=TOOLS, background_fill_color="#fafafa") left.scatter("bill_length_mm", "body_mass_g", source=source, color=factor_cmap('species', 'Category10_3', SPECIES)) right = figure(width=300, height=400, title=None, tools=TOOLS, background_fill_color="#fafafa", y_axis_location="right") right.scatter("bill_depth_mm", "body_mass_g", source=source, color=factor_cmap('species', 'Category10_3', SPECIES)) show(gridplot([[left, right]]))
A more sophisticated example below demonstrates linked selection between a DataTable
widget and a scatter plot:
from bokeh.layouts import column from bokeh.models import (ColumnDataSource, DataTable, HoverTool, IntEditor, NumberEditor, NumberFormatter, SelectEditor, StringEditor, StringFormatter, TableColumn) from bokeh.plotting import figure, show from bokeh.sampledata.autompg2 import autompg2 as mpg source = ColumnDataSource(mpg) manufacturers = sorted(mpg["manufacturer"].unique()) models = sorted(mpg["model"].unique()) transmissions = sorted(mpg["trans"].unique()) drives = sorted(mpg["drv"].unique()) classes = sorted(mpg["class"].unique()) columns = [ TableColumn(field="manufacturer", title="Manufacturer", editor=SelectEditor(options=manufacturers), formatter=StringFormatter(font_style="bold")), TableColumn(field="model", title="Model", editor=StringEditor(completions=models)), TableColumn(field="displ", title="Displacement", editor=NumberEditor(step=0.1), formatter=NumberFormatter(format="0.0")), TableColumn(field="year", title="Year", editor=IntEditor()), TableColumn(field="cyl", title="Cylinders", editor=IntEditor()), TableColumn(field="trans", title="Transmission", editor=SelectEditor(options=transmissions)), TableColumn(field="drv", title="Drive", editor=SelectEditor(options=drives)), TableColumn(field="class", title="Class", editor=SelectEditor(options=classes)), TableColumn(field="cty", title="City MPG", editor=IntEditor()), TableColumn(field="hwy", title="Highway MPG", editor=IntEditor()), ] data_table = DataTable(source=source, columns=columns, editable=True, width=800, index_position=-1, index_header="row index", index_width=60) p = figure(width=800, height=300, tools="pan,wheel_zoom,xbox_select,reset", active_drag="xbox_select") cty = p.scatter(x="index", y="cty", fill_color="#396285", size=8, alpha=0.5, source=source) hwy = p.scatter(x="index", y="hwy", fill_color="#CE603D", size=8, alpha=0.5, source=source) tooltips = [ ("Manufacturer", "@manufacturer"), ("Model", "@model"), ("Displacement", "@displ"), ("Year", "@year"), ("Cylinders", "@cyl"), ("Transmission", "@trans"), ("Drive", "@drv"), ("Class", "@class"), ] cty_hover_tool = HoverTool(renderers=[cty], tooltips=[*tooltips, ("City MPG", "@cty")]) hwy_hover_tool = HoverTool(renderers=[hwy], tooltips=[*tooltips, ("Highway MPG", "@hwy")]) p.add_tools(cty_hover_tool, hwy_hover_tool) show(column(p, data_table))Linked crosshair#
Linking crosshair tools between plots is another technique that can help make comparisons across different plots easier. In Bokeh, crosshair tools may be configured with shared Span
instances for their overlays, which will cause those crosshairs to be linked together. This is demonstrated below:
from random import random from bokeh.layouts import row from bokeh.models import CrosshairTool, Span from bokeh.plotting import figure, show x = [random() * 10 for _ in range(200)] y = [random() * 10 for _ in range(200)] width = Span(dimension="width", line_dash="dashed", line_width=2) height = Span(dimension="height", line_dash="dotted", line_width=2) p1 = figure(height=400, width=400, x_range=(0, 10), y_range=(0, 10), tools="hover", toolbar_location=None) p1.add_tools(CrosshairTool(overlay=[width, height])) p1.circle(x, y, radius=0.2, alpha=0.3, hover_alpha=1.0) p2 = figure(height=400, width=250, x_range=(0, 10), y_range=(0, 10), tools="hover", toolbar_location=None) p2.add_tools(CrosshairTool(overlay=[width, height])) p2.circle(x, y, radius=0.2, alpha=0.3, hover_alpha=1.0) show(row(p1, p2))Linked properties#
It is also possible to link values of Bokeh model properties together so that they remain synchronized, using the js_link()
method. The example below links a circle glyph radius to the value of a Slider widget:
from bokeh.layouts import column from bokeh.models import Slider from bokeh.plotting import figure, show plot = figure(width=400, height=400) r = plot.circle([1,2,3,4,5], [3,2,5,6,4], radius=0.2, alpha=0.5) slider = Slider(start=0.1, end=2, step=0.01, value=0.2) slider.js_link('value', r.glyph, 'radius') show(column(plot, slider))
The linking is accomplished in JavaScript, so this method works in standalone Bokeh documents, or in Bokeh server applications.
See Widgets and DOM elements for more information about different widgets, and JavaScript callbacks for more information about creating arbitrary JavaScript callbacks.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4