2

I am new to Bokeh and I would really appreciate some help in figuring out how to use Bokeh to plot a simple interactive pie chart in Jupyer/Python. I am planning to use 'CustomJS with a Python function' in Bokeh as explained at the bottom of the page here. The pie chart consists of two entries with a slider that can change the shape of one pie 'v2' inside the circle shape of (v1+v2). I have tried to follow the example in bokeh website that shows the interactivity with a sine plot, but I just cannot get it to work with my pie chart. Any help would be greatly appreciated. Below is the code block I am using inside a Jupyter notebook.

import numpy as np
import matplotlib.pyplot as plt
from bokeh.layouts import column
from bokeh.models import CustomJS, ColumnDataSource, Slider
from bokeh.plotting import Figure, output_file, show, output_notebook
from bokeh.charts import Donut, show

#output_file('donut.html')
output_notebook()

v1=1
v2=.2
import pandas as pd
data = pd.Series([v1,v2], index = list('ab')) 
plot = Figure(plot_width=400, plot_height=400)
plot = Donut(data) 
    
    
def pie_chart(source=data,window=None,deltav=None):
    data = source.data
    v2 = deltav.value
    #v2 = data['v2']
    source.trigger('change')
    
slider = Slider(start=.1, end=1., value=.2, step=.1, title="delta-V", callback=CustomJS.from_py_func(pie_chart))
callback.args["deltav"] = slider
    
l = column(slider, plot)
show(l)

4 Answers 4

4

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, show
from bokeh.layouts import column
from 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))

enter image description here

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.

Sign up to request clarification or add additional context in comments.

5 Comments

This is excellent! Thanks a bunch for suggesting this. I had no idea about the limitation of bokeh.charts. Now, is there any way to remove the axis, grid and the white behind the pie chart? Also, is it possible to draw a donut chart (pie with a hole) using the bokeh.plotting?
Yes, see the Styling Visual Attributes section of the user's guide. For the other question, yes, there is also an annular_wedge glyph method that takes both inner and outer radii
Actually to get rid of axes completely you'd want figure(..., x_axis_location=None, ...) which I guess is documented elsewhere. Getting rid of grids is a syling issue tho (set grid line color to none)
CustomJS.from_py_func has been removed from Bokeh.
Yes, it relied on a flaky third party library and was ultimately unsupportable. Happily, it's generally possible to accomplish the same thing with a few lines of JS: docs.bokeh.org/en/latest/docs/user_guide/interaction/…
0

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"

Comments

0

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.py

from math import pi
from bokeh.io import curdoc
from bokeh.io import output_file, show
from bokeh.layouts import column
from 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))

Comments

0

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 figures

def modify_doc(doc):

    # create the data for the plot
    def make_data(setting):
        return ColumnDataSource(data=dict(start=[0, 0.2], end=[setting, 2*pi], color=['firebrick', 'navy']))

    # make the plot
    def make_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 plot
    def update(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")

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.