在Jupyter中使用Bokeh RadioGroup绘制Pandas DataFrame的选定子集。

问题描述 投票:0回答:1

目标

在Pandas DataFrame中通过选择一列的特定值来绘制行的子集。

理想的情况是在jupyter笔记本上绘制。

我做了什么

我对Javascript的了解非常少,所以我通过运行Bokeh服务器,用Python编写的所有内容来绘制。

然而,我无法在Jupyter笔记本上用Javascript回调来实现。我的方法听起来有点愚蠢:通过列的值将DataFrame分割成子集,并将它们放入一个dict中,然后我可以通过RadioGroup中的活动选择来选择一个子集。

这是我的代码例子。


import pandas as pd
import bokeh
from bokeh.io import output_notebook, show
import bokeh.plotting as bp
import bokeh.models as bm
from bokeh.layouts import column, row

data = {
    'Datetime': ['2020-04-09T10:23:38Z', '2020-04-09T22:23:38Z','2020-04-09T23:23:38Z', '2020-01-09T10:23:38Z', '2020-01-09T22:23:38Z', '2020-01-09T23:23:38Z'],
    'Month': ['Apr', 'Apr', 'Apr', 'Jan', 'Jan', 'Jan'],
    'Values': [1.2, 1.3, 1.5, 1.1, 3, 1.3]
}

df = pd.DataFrame.from_dict(data)
month_list = df['Month'].unique().tolist()

plot_height = 600
plot_width = 1000
col2plot = 'Values'

month_dict = {}
for m in month_list:
    subset = df[df['Month'] == m].reset_index(drop=True)
    month_dict[m] = subset[['Datetime', col2plot]].to_dict()

p1 = bp.figure(
    plot_height=plot_height, 
    plot_width=plot_width, 
    title='Values',
    toolbar_location=None,
    tools="hover",
    tooltips=[("DateTime", "@Datetime")]
)

src = bm.ColumnDataSource(df[df['Month'] == 'Jan'].reset_index(drop=True))
p1.line(x='index', y=col2plot, alpha=0.8, source=src)

month_selector = bm.widgets.RadioGroup(labels=month_list, active=1)

jscode = """
var month = cb_obj.labels[cb_obj.active] //selected month
const new_data = source[month]
src.data = new_data
src.change.omit()
"""
callback = bm.CustomJS(args=dict(src=src, source=month_dict), code=jscode)
month_selector.js_on_change('active', callback)
output_notebook()
show(row(p1, month_selector))

代码运行了,但是通过选择某个月份,情节没有更新。这可能是由于JS回调的处理不好,有什么办法可以解决这个问题吗?非常感谢大家的帮助

javascript python dataframe jupyter-notebook bokeh
1个回答
0
投票

你的代码的问题。

  • 在... p.line,你使用的是 index 列。但当你调用 pd.DataFrame.to_dict()栏目不存在。可以通过再添加一个 .reset_index() 之前 .to_dict()
  • to_dict() 以 dict 的形式返回数据,但 ColumnDataSource 需要一个list的dict。将该调用替换为to_dict('list')
  • src.change.omit() - 错别字,应该是 emit. 但由于你要更换整个 data 属性,而不是仅仅改变一些数据,你可以简单地将这一行完全删除。
© www.soinside.com 2019 - 2024. All rights reserved.