首页 > 解决方案 > Bokeh 中的堆积条形图;交互式绘制分组数据

问题描述

我正在尝试在 Bokeh 中创建一个堆积条形图,它可以按日期和按列/值进行交互式过滤以进行绘图。我可以生成一个简单的条形图,并且可以按日期过滤,但我想将其转换为堆叠版本,并能够根据我从下拉框中选择的列对其进行更新。这是我的代码和输出:-

from bokeh.models import ColumnDataSource, CustomJS, Select
from bokeh.plotting import figure, output_file, show
from numpy import source
import pandas as pd
from functools import lru_cache
from os.path import dirname, join
from bokeh.models.callbacks import CustomJS
from numpy import select
from bokeh.core.properties import value
import pandas as pd
import numpy as np
from datetime import datetime
from bokeh.io import output_file
from bokeh.layouts import column, row
from bokeh.models import ColumnDataSource, PreText, Select, Slider,CDSView, BooleanFilter,DateRangeSlider,FactorRange, TextInput, BasicTickFormatter
from bokeh.plotting import figure, output_file, show,curdoc
from bokeh.palettes import Blues8
from bokeh.transform import factor_cmap
from bokeh.layouts import widgetbox
from bokeh.models.widgets import Dropdown



colors = ["#c9d9d3", "#718dbf", "#e84d60"]

category_a = ['A','B','C']
category_b = ['X','Y','Z']

df_random = pd.DataFrame({
   'id': np.arange(0, 100),
   'date': pd.date_range(start='1/1/2021', periods=100, freq='D'),
   'month':np.random.randint(1, 12, 100),
   'sensor_1': np.random.uniform(0, 1,100),
   'sensor_2': np.random.uniform(10, 150, 100),
   'sensor_3': np.random.randint(0, 90, 100),
   'sensor_4': np.random.randint(0, 450, 100),
   'sensor_5': np.random.randint(0, 352, 100),
   'categorya': np.random.choice(category_a, 100, p=[0.2, 0.4, 0.4]),
   'categoryb': np.random.choice(category_b, 100, p=[0.6, 0.2, 0.2]),
})

mindate = df_random['date'].min()
maxdate = df_random['date'].max()

columnchoices=['sensor_1','sensor_2','sensor_3','sensor_4','sensor_5']

init_value = (df_random['date'].min(), df_random['date'].max())
p = figure(plot_width=800, plot_height=350, x_axis_type="datetime")
date_range_slider = DateRangeSlider(start=init_value[0], end=init_value[1], value=init_value)

date_range_slider.js_on_change("value", CustomJS(code="""
    console.log('date_range_slider: value=' + this.value, this.toString())
"""))
ds = ColumnDataSource(data=df_random)
date_filter = BooleanFilter(booleans=[True] * df_random.shape[0])

date_range_slider.js_on_change('value', CustomJS(args=dict(f=date_filter, ds=ds),
                                      code="""\
                                          const [start, end] = cb_obj.value;
                                          f.booleans = Array.from(ds.data['date']).map(d => (d >= start && d <= end));
                                          // Needed because of https://github.com/bokeh/bokeh/issues/7273
                                          ds.change.emit();
                                      """))


p.vbar('date', top='sensor_1', source=ds, view=CDSView(source=ds, filters=[date_filter]),
         color='navy', alpha=0.5, legend_label="sensor_1", line_width=2)


handlerbar_y=CustomJS(args=dict(p=p), code = """
p.glyph.top ={field: cb_obj.value};
"""
)

selectbar = Select(title="Select variable", options=list(columnchoices))

selectbar.js_on_change('value', handlerbar_y)


show(column(p, date_range_slider,selectbar))


和输出: -

在此处输入图像描述

滑块有效,但当我使用下拉选择器更改要绘制的列时它不会更新。另外,有人可以向我展示或更改我的代码以制作堆叠条形图,并在其中分组categoryadf_random?我将不胜感激任何帮助:)

标签: pythonpandasbokehstacked-chart

解决方案


推荐阅读