给 Bokeh 堆叠柱状图添加交互。

3
使用此处的示例

http://docs.bokeh.org/en/latest/docs/gallery/stacked_bar_chart.html

这里还附带交互示例:

http://docs.bokeh.org/en/latest/docs/user_guide/interaction.html#userguide-interaction

似乎使用滑块改变堆叠条形图的可视化效果应该是非常直接的。然而,问题在于来自bokeh.charts库的Bar对象没有公开渲染在条形图中的数据源。据我所知,这是因为charts模块没有维护这些数据。
是否可能使用Bar对象实现上述交互?我卡在了从哪里获取数据以便在滑块移动时更新条形图。我真的不想每次滑块移动时都需要显式地从基元素重新构建整个条形图。
非常感谢任何帮助。我的最后一次尝试如下:
from collections import OrderedDict
import pandas as pd
from bokeh.charts import Bar, output_file, show
from bokeh.sampledata.olympics2014 import data
from bokeh.io import vform
from bokeh.models import Callback, ColumnDataSource, Slider
from bokeh.plotting import figure

output_file("callback_bar_graph.html")

df = pd.io.json.json_normalize(data['data'])

# filter by countries with at least one medal and sort
df = df[df['medals.total'] > 0]
df = df.sort("medals.total", ascending=False)

# get the countries and we group the data by medal type
countries = df.abbr.values.tolist()
gold = df['medals.gold'].astype(float).values
silver = df['medals.silver'].astype(float).values
bronze = df['medals.bronze'].astype(float).values

# build a dict containing the grouped data
medals = OrderedDict(bronze=bronze, silver=silver, gold=gold)

# any of the following commented are also alid Bar inputs
medals = pd.DataFrame(medals)

source = ColumnDataSource(data=dict(medals=medals, countries=countries))

bar = Bar(medals, countries, title="Stacked bars", stacked=True)

callback = Callback(args=dict(source=source), code="""
    var data = source.get('data');
    var f = cb_obj.get('value')
    medals = data['medals']
    countries = data['countries']
    for (i = 0; i < medals.bronze.length; i++) {
        medals.bronze[i] = 2*medals.bronze[i]
    }
    source.trigger('change');
""")

slider = Slider(start=-2, end=2, value=1, step=.1,
                title="value", callback=callback)

layout = vform(slider, bar)

show(layout)

就直接使用“BarChart”对象而言,我没有找到任何明显的方法来修改绘图对象,以便实现您要查找的内容。原因是“BarChart”将其所有图表数据存储在其渲染器中。如果您可以将另一个“BarChart”的渲染器传递给回调函数,那么这不会成为问题,但回调函数只能接收“PlotObject”作为参数,因此您的渲染器列表立即被淘汰了... - StevieP
此外,这可能对您没有帮助,但我能够汇集一个交互式堆栈条形图。看看这个链接:http://nbviewer.ipython.org/github/stevenpollack/middle_middle/blob/master/middle_middle.ipynb - StevieP
1个回答

2
答案是回调函数!
来源:http://docs.bokeh.org/en/latest/docs/user_guide/interaction.html#callbacks-for-widgets 基本上,您需要创建一个包含条形图数据的ColumnDataSource对象。然后,您将创建一个回调对象,将ColumnDataSource实例作为参数,并使用JS代码从滑块交互中获取数据并更新数据实例/触发更改。
如果您无法使其工作,请发布您拥有的代码,我会尽力帮助。

1
你说得对,bokeh.charts中的Bar类没有暴露“source”属性。您将需要使用bokeh.plotting api,并且可能需要从rects构建堆叠条形图。您希望滑块对条形图执行什么操作? - Luke Canavan
这正是我试图避免的。我不知道如何做,更不用说如何连接到JavaScript进行动态交互了。 - reckoner
1
@reckoner 这里有一个好例子,展示如何使用bokeh.plotting而不是bokeh.charts创建堆叠和非堆叠条形图。 - Josh Sherick
链接又坏了。 - Marco Castelluccio
这段代码可能已经过时了,但是请看一下这个链接:https://github.com/bokeh/bokeh-build/blob/master/sphinx/source/docs/tutorials/solutions/olympics.py - Chris
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接