散景使用聚合更新源

问题描述

我正在使用国家/地区数据构建bokeh仪表板,以动态更改折线图。

用户可以使用CheckBoxGroup选择多个国家/地区。

在选择/取消选择国家/地区时,我能够动态地对源表进行子集化。

在子集之后,我将汇总问题出处的图形的源表。 (按日期将所有国家/地区分组)

我了解我们必须直接使用source=src,但每次更新新源时都需要汇总。

关于如何解决此问题,是否有任何建议?

谢谢!

def make_plot(src):
    temp = pd.DataFrame.from_dict(src.data)
    agg_date_full = ColumnDataSource(temp.groupby('date').sum().reset_index())
    fig1.line('date','y',source=agg_date_full)

def update(attr,old,new):
    country_to_plot = [country_checkBox.labels[i] for i in country_checkBox.active]
    new_src = make_dataset(country_to_plot)
    src.data.update(new_src.data)

country_checkBox = CheckBoxGroup(labels=country_labels,active= list(range(0,len(country_labels))))
country_checkBox.on_change('active',update)

initial_countries = [country_checkBox.labels[i] for i in country_checkBox.active]

src = make_dataset(initial_countries)
    
p = make_plot(src)

解决方法

答案取决于您计划如何部署和使用仪表板。

如果您可以运行bokeh服务器,那么对您描述的数据进行动态转换就非常简单。

我们可以使用世界银行的API从世界银行获取示例时间序列数据集。根据您的描述,它应该足够接近:

http://api.worldbank.org/v2/country/eas;ecs;lcn;mea;nac;sas;ssf/indicator/EN.ATM.CO2E.KT?source=2&downloadformat=csv

整理一下之后,数据框应如下所示:

Country Name                Year    Value
East Asia & Pacific         1960    1.215380e+06
Europe & Central Asia       1960    4.583646e+06
Latin America & Caribbean   1960    3.024539e+05
Middle East & North Africa  1960    9.873685e+04
North America               1960    3.083749e+06
...

现在输入bokeh代码。我使用了docs中的单模块方法,但是您可以根据需要使其变得复杂。请注意,您应该将此代码放在.py文件中,而不是从Jupyter笔记本中运行

from bokeh.layouts import row
from bokeh.models import CheckboxGroup,NumeralTickFormatter
from bokeh.plotting import figure,curdoc

initial_x = df["Year"].unique()
initial_y = (
    df[df["Country Name"] == "Europe & Central Asia"]
        .groupby("Year")["Value"]
        .sum()
        .values
)

# create a plot and style its properties
p = figure(height=400,width=600,toolbar_location=None)
p.yaxis[0].formatter = NumeralTickFormatter(format="0.0a")
p.yaxis.axis_label = "CO2 emissions (kt)"
p.xaxis.axis_label = "Years"

# create line renderer
line = p.line(x=initial_x,y=initial_y,line_width=2)

ds = line.data_source

# create a callback that will reset the datasource
def callback(self):

    selected = [checkbox_group.labels[i] for i in checkbox_group.active]
    filtered =  df[df["Country Name"].isin(selected)]
    new_data = dict()
    new_x = filtered["Year"].unique()
    new_y = filtered.groupby("Year")["Value"].sum().values
    new_data["x"] = new_x
    new_data["y"] = new_y

    ds.data = new_data

# add checkboxes and the callback
labels = list(df["Country Name"].unique())
checkbox_group = CheckboxGroup(labels=labels,active=[1])
checkbox_group.on_click(callback)

# put the checkboxes and plot in a layout and add to the document
curdoc().add_root(row(checkbox_group,p))

现在,当您从终端bokeh serve --show app.py运行以下命令时,将可以在浏览器中看到仪表板,如下所示:

enter image description here

当您单击不同的区域时,它们的碳排放量将相加并绘制为一条线。