Using Bokeh To Plot Interactive Pie Chart In Jupyter/python
Solution 1:
If you want to interactively update things, then you will be better off using the bokeh.plotting
API. For some fairly uninteresting technical reasons, the bokeh.charts
API (including Donut
) is not well-suited for use cases that require updating things in place.
With bokeh.plotting
there is a wedge
glyph method that you can use to draw pie charts. Here is a complete example written (using Bokeh 0.12.5
) that updates a pie chart with a slider:
from math import pi
from bokeh.io import output_file, showfrom bokeh.layouts import columnfrom bokeh.models import ColumnDataSource, CustomJS, Slider
from bokeh.plotting import figure
output_file("pie.html")
source = ColumnDataSource(data=dict(
start=[0, 0.2], end=[0.2, 2*pi], color=['firebrick', 'navy']
))
plot = figure()
plot.wedge(x=0, y=0, start_angle='start', end_angle='end', radius=1,
color='color', alpha=0.6, source=source)
slider = Slider(start=.1, end=1., value=.2, step=.1, title="delta-V")
def update(source=source, slider=slider, window=None):
data = source.data
data['end'][0] = slider.value
source.trigger('change')
slider.js_on_change('value', CustomJS.from_py_func(update))
show(column(slider, plot))
It's slightly more verbose than the Donut
version, but the relationship between the data structures on the python side and on the JS side are much more clear and direct.
Solution 2:
I think I found my answer. Here is the code in case it helps
''' Present an interactive function explorer with slider widgets.
Scrub the slider to change the pie shape in the donut plot
Use the ``bokeh serve`` command to run the example by executing:
bokeh serve donuts.py
at your command prompt. Then navigate to the URL
http://localhost:5006/donuts
in your browser.
'''
import numpy as np
from bokeh.io import curdoc
from bokeh.layouts import row, widgetbox
from bokeh.models import ColumnDataSource
from bokeh.models.widgets import Slider, TextInput
from bokeh.plotting import figure
from math import pi
# Set up data
source = ColumnDataSource(data=dict(
start=[0, 0], end=[0., 2*pi], color=["white", "red"]
))
# Set up plot
plot = figure(x_axis_location=None, y_axis_location=None, plot_width=400, plot_height=400,)
plot.annular_wedge(x=0, y=0, start_angle='start', end_angle='end', inner_radius=.4, outer_radius=.8,
color="color", alpha=1., source=source)
#plot.background_fill_color = None
plot.xgrid.grid_line_color = None
plot.ygrid.grid_line_color = None
# Set up widgets
slider = Slider(start=.0, end=round(2*pi,2), value=.0, step=.1, title="delta-V")
# Set up callbacks
def update(attrname, old, new):
# Get the current slider values
z = slider.value
source.data = dict(start=[pi,pi+z], end=[pi+z, pi], color=["yellow", "red"])
for w in [slider]:
w.on_change('value', update)
# Set up layouts and add to document
inputs = widgetbox(slider)
curdoc().add_root(row(inputs, plot, width=800))
curdoc().title = "Donut"
Solution 3:
The code from bigreddot didn't work for me. Plot showed but didn't change. Here is my slight modification for anyone that could use it.
#cd file directory
#bokeh serve --show filename.pyfrom math import pi
from bokeh.io import curdoc
from bokeh.io import output_file, showfrom bokeh.layouts import columnfrom bokeh.models import ColumnDataSource, CustomJS, Slider
from bokeh.plotting import figure
source = ColumnDataSource(data=dict(
start=[0, 0.2], end=[0.2, 2*pi], color=['firebrick', 'navy']
))
plot = figure()
plot.wedge(x=0, y=0, start_angle='start', end_angle='end', radius=1,
color='color', alpha=0.6, source=source)
slider = Slider(start=.1, end=1., value=.2, step=.1, title="delta-V")
def update(attrname, old, new):
data = source.data
data['end'][0] = slider.value
source.data=data
slider.on_change('value', update)
curdoc().add_root(column(slider, plot))
Solution 4:
I'm using Bokeh 1.0.4 and the answer by bigreddot doesn't work for me. The slider doesn't actually change the plot. I put together a complete working answer that works for me in JupyterLab v0.27.0 using bigreddot's example and this website.
from math import pi
from bokeh.io import show, output_notebook
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, Slider
from bokeh.plotting import figure
from bokeh.application.handlers import FunctionHandler
from bokeh.application import Application
output_notebook() # allow inline output of figuresdefmodify_doc(doc):
# create the data for the plotdefmake_data(setting):
return ColumnDataSource(data=dict(start=[0, 0.2], end=[setting, 2*pi], color=['firebrick', 'navy']))
# make the plotdefmake_plot(source):
plot = figure()
plot.wedge(x=0, y=0, start_angle='start', end_angle='end', radius=1,
color='color', alpha=0.6, source=source)
return plot
# update the plotdefupdate(attrname,old,new):
setting = slider.value
src = make_data(setting)
source.data.update(src.data)
# controls
slider = Slider(start=.1, end=1., value=.2, step=.1, title="delta-V")
slider.on_change('value',update)
source = ColumnDataSource(data=dict(
start=[0, 0.2], end=[0.2, 2*pi], color=['firebrick', 'navy']
))
p = make_plot(source)
layout = column(slider, p)
doc.add_root(layout)
app = Application(FunctionHandler(modify_doc))
doc = app.create_document()
show(app,notebook_url="localhost:8888")
Post a Comment for "Using Bokeh To Plot Interactive Pie Chart In Jupyter/python"