[英]Using bokeh 2.3.2 to plot interactive pie chart in Jupyter/Python
我正在嘗試在帶有 Bokeh 的 jupyter 筆記本中創建一個餅圖,該餅圖可以使用 slider 進行更新。 我有一個自定義的 function,它從預先存在的 dataframe 創建data
。 我希望 slider 操縱 function 的輸入f
,以便在餅圖中顯示時data
不同。 這是一個例子:
vals = [20, 100, 50]
names = ["Agnostic", "Competetive", "Loyalist"]
def data_generator(names, vals, f):
data = pd.DataFrame([[name, val * f] for name, val in zip(names, vals)])
return data
data = data_generator(names, vals, 10)
data['angle'] = data['value']/data['value'].sum() * 2*pi
data['color'] = Plasma[len(data)]
p = figure(plot_height=350, title="Loyalty Breakout", toolbar_location=None,
tools="hover", tooltips="@segment: @value", x_range=(-0.5, 1.0))
p.wedge(x=0, y=1, radius=0.4,
start_angle=cumsum('angle', include_zero=True), end_angle=cumsum('angle'),
line_color="white", fill_color='color', legend_field='segment', source=data)
# This is where I need help
update = CustomJS(args=dict(xr=p.x_range), code="""
// I got this JS code from somewhere else. I need this to update the 'f' value in my input funciton.
// JavaScript code goes here
var a = 10;
// the model that triggered the callback is cb_obj:
var f = cb_obj.value;
// models passed as args are automagically available
xr.start = a;
xr.end = b;
""")
lookback_slider = Slider(start=0, end=180, value=30, step=1, title="Lookback (days)")
lookback_slider.js_on_change('value',update)
p.axis.axis_label=None
p.axis.visible=False
p.grid.grid_line_color = None
show(column(lookback_slider, p))
這將創建餅圖和 slider,但 slider 不起作用。 我發現了這一點: 在 Jupyter/Python 中使用散景到 plot 交互式餅圖,但不幸的是, CustomJS.from_py_func(update)
不起作用,因為from_py_func
在最新版本的散景中已被棄用。 誰能幫我用散景更新餅圖?
您需要完全在 JavaScript 回調中實現data_generator
function 以及角度計算。 目前尚不清楚您要使用代碼實現什么,但這里有一些基於您的代碼的示例 JS 回調實現,它改變了餅角(使用 Bokeh v2.1.1 測試):
from re import I
import pandas as pd
from bokeh.plotting import show, figure, output_notebook
from bokeh.models import CustomJS, Slider, Column
from bokeh.palettes import Plasma
from bokeh.transform import cumsum
from math import pi
output_notebook()
vals = [20, 100, 50]
names = ["Agnostic", "Competetive", "Loyalist"]
def data_generator(names, vals, f):
data = pd.DataFrame([[name, val * f] for name, val in zip(names, vals)], columns=['name', 'value'])
return data
f_start = 30
data = data_generator(names, vals, f_start)
data['angle'] = data['value']/data['value'].sum() * 2*pi # print(data.to_string())
data['color'] = Plasma[len(data)]
p = figure(plot_height=350, title="Loyalty Breakout", toolbar_location=None,
tools="hover", tooltips="@segment: @value", x_range=(-0.5, 1.0))
wedge = p.wedge(x=0, y=1, radius=0.4,
start_angle=cumsum('angle', include_zero=True), end_angle=cumsum('angle'),
line_color="white", fill_color='color', legend_field='name', source=data)
update = CustomJS(args=dict(wedge=wedge, vals=vals, xr=p.x_range), code="""
var f = cb_obj.value;
//var scaled = Array.from(vals, (x) => x*f)
var scaled = Array.from(vals, (x, i) => i==0?x*f/10:x)
var sum = scaled.reduce((a, b) => a + b, 0)
var angles = Array.from(scaled, (x) => x/sum * 2 * Math.PI)
wedge.data_source.data['angle'] = angles
wedge.data_source.data['value'] = scaled
wedge.data_source.change.emit()
//xr.start = a;
//xr.end = b;
""")
lookback_slider = Slider(start=0, end=180, value=f_start, step=1, title="Lookback (days)")
lookback_slider.js_on_change('value',update)
p.axis.axis_label=None
p.axis.visible=False
p.grid.grid_line_color = None
show(Column(lookback_slider, p))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.