使用滑块通过过滤掉数据来更新饼图(散景)

Using slider to update pie chart (Bokeh) via filtering out of data

我是新手,感谢任何 pointers/help 将我推向正确的方向。基本上我试图想出一个带有滑块的交互式散景饼图,可以帮助相应地过滤数据(在这种情况下是年份)。饼图显示了 65 岁及以上的劳动力比例,最终目标是能够使用滑块查看多年来的比例增长。非常感谢大家。

https://data.gov.sg/dataset/total-residents-aged-15-years-and-over-by-labour-force-status-and-age-group-june-annual?resource_id=6549bb00-6ae8-4608-ab6a-1613b1121266

from math import pi

from bokeh.io import output_file, show
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, Slider
from bokeh.plotting import figure
from bokeh.application.handlers import FunctionHandler
from bokeh.palettes import Category20b
from bokeh.transform import cumsum
from bokeh.application import Application

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
pd.options.mode.chained_assignment = None 

output_file("pie.html")

df1 = pd.read_csv('data CA2/total-residents-aged-15-years-and-over-by-age-group.csv',na_values =["na"])

rows_to_keep = ["65 Years & Over"]
rows_to_keep2 = ["Total Residents In The Labour Force", "Total Residents Outside The Labour Force"]
df2 = df1[df1['level_2'].isin(rows_to_keep)]
df3 = df2[df2["level_1"].isin(rows_to_keep2)] 


df4 = df3.groupby(['year', 'level_1', ]).sum()

df5 = df4.reset_index(drop=False)
df6 = df5[df5["year"] == 2019]

df6['angle'] = df6['value']/df6['value'].sum() * 2*pi
df6['color'] = ["purple","blue"]


p = figure(plot_height=350, title="Pie Chart", toolbar_location=None,
            tools="hover", tooltips="@level_1: @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', source=df6)

slider = Slider(start=1990, end=2019, value=2001, step=1, title="Year")


def update(source=df6, slider=slider, window=None):
    df6 = df5[df5["year"] == slider.value]
    source.trigger('change')

当前饼图输出:

如果你想要交互,你要么需要在 java 中使用 js_* 回调指定回调,要么就像我下面的例子一样,使用纯 python 回调,但它们在没有将它们托管在散景服务器上的常规浏览器,因为常规 html 不支持 python。我一直在你现在所在的位置,请参阅我的问题 () 和答案。

为了查看它的运行情况,我使用 Jupyter notebook 运行 编写代码并设计交互。我发现这是构建散景应用程序最方便的方式,但您也可以使用散景服务。

让它在 jupyter notebook 中运行:

from bokeh.io import output_notebook
output_notebook()

您需要将您的代码包装在一个函数中,然后将其传递给 FunctionHandler 和 Application 函数,然后您可以显示它。

我进行了一些调整以使其正常工作,请参见下文:

df1 = pd.read_csv('total-residents-aged-15-years-and-over-by-age-group.csv',na_values =["na"])

rows_to_keep = ["65 Years & Over"]
rows_to_keep2 = ["Total Residents In The Labour Force", "Total Residents Outside The Labour Force"]
df2 = df1[df1['level_2'].isin(rows_to_keep)]
df3 = df2[df2["level_1"].isin(rows_to_keep2)] 


df4 = df3.groupby(['year', 'level_1', ]).sum()

df5 = df4.reset_index(drop=False)


def viz(doc):

    def update(attr,old,new):        
        df6 = grabData(new)
        src.data.update(ColumnDataSource(df6).data)

    def grabData(year):
        df6 = df5[df5["year"] == year]

        df6['angle'] = df6['value']/df6['value'].sum() * 2*pi
        df6['angle1'] = [0,df6['angle'].iloc[0]]
        df6['angle2'] = [df6['angle'].iloc[0],2*pi]
        df6['color'] = ["purple","blue"]
        return df6

    df6 = grabData(2001)
    src = ColumnDataSource(df6)

    p = figure(plot_height=350, title="Pie Chart", toolbar_location=None,
                tools="hover", tooltips="@level_1: @value",x_range=(-0.5, 1.0))

    p.wedge(source=src,x=0, y=1, radius=0.4,
            start_angle= 'angle1', end_angle='angle2',
            line_color="white", fill_color='color')

    slider = Slider(start=1990, end=2019, value=2001, step=1, title="Year")
    slider.on_change('value',update)
    doc.add_root(column(p,slider))




show(Application(FunctionHandler(viz)))