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

时间:2020-08-02 09:42:47

标签: python pandas bokeh

我对此并不陌生,并感谢任何将我推向正确方向的指针/帮助。基本上,我试图提供一个带有滑块的交互式Bokeh饼图,该滑块可以帮助相应地过滤数据(在这种情况下为年份)。饼形图显示了劳动力中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')

当前饼图的输出:

Output of current pie chart

1 个答案:

答案 0 :(得分:0)

如果要进行交互,则需要使用js_ *回调在Java中指定回调,或者像下面的示例一样,使用纯python回调,但是如果不将它们托管在bokeh服务器上,它们将无法在常规浏览器中使用由于常规html不会支持python。我已经到了你现在的位置,请参阅我的问题(Export interactive Bokeh plots with widgets to standalone HTML)和答案。

为了看到它能正常工作,我使用Jupyter笔记本运行代码并设计交互。我发现这是构建bokeh应用程序的最便捷方法,但是您也可以使用bokeh服务。

要使其在jupyter笔记本中工作:

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)))