bokeh vbar_stack:正侧为正值,负侧为负值

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

示例程序

import bokeh.colors
import pandas as pd
from bokeh.plotting import figure, show
import bokeh.models
import bokeh.palettes
import bokeh.transform

data = {
    'date': ['2024-04-15', '2024-04-16', '2024-04-17' ],
    'Bill': [1,  1, -1],
    'Note': [1, -1, -1],
    'Bond': [1,  0, -1]
}

df = pd.DataFrame(data)

df['date'] = pd.to_datetime(df['date'])

df.set_index('date', inplace=True)

p = figure(sizing_mode='stretch_both', x_axis_type='datetime', x_axis_label='date', y_axis_label='change')

p.vbar_stack(stackers=['Bill', 'Note', 'Bond'], x='date', width=pd.Timedelta(days=0.9), color=bokeh.palettes.Category20[3], source=df, legend_label=['Bill', 'Note', 'Bond'])

p.legend.click_policy = 'hide'

show(p)

输出

注释

在第一列中,所有三个值都是正数,因此它们按预期向上堆叠。

在第三列中,所有三个值都是负数,因此它们按预期向下堆叠。

在中间一列中,我们有 1 个正值,因此它向上堆叠,然后我们有 1 个负值,因此它向下堆叠。结果是,我们最终得到了高度为 1 的堆栈的外观。

问题

有没有办法让正值仅叠加在 y 轴的正侧,而负值仅显示在 y 轴的负侧?

换句话说,图表如下所示:

python bokeh
1个回答
0
投票

技巧是将 DataFrame 分为正数和负数,并绘制两个堆栈器。

这是代码:

p = figure(x_axis_type='datetime', x_axis_label='date', y_axis_label='change')

p.vbar_stack(
    stackers=['Bill', 'Note', 'Bond'],
    x='date', width=pd.Timedelta(days=0.9),
    color=bokeh.palettes.Category20[3],
    source=df[df<0].fillna(0),
    legend_label=['Bill', 'Note', 'Bond'],
    line_width=0,
)
p.vbar_stack(
    stackers=['Bill', 'Note', 'Bond'],
    x='date', width=pd.Timedelta(days=0.9),
    color=bokeh.palettes.Category20[3],
    source=df[df>0].fillna(0),
    legend_label=['Bill', 'Note', 'Bond'],
    line_width=0,
)
p.legend.click_policy = 'hide'

show(p)

用零填充选择很重要,以避免使用

np.nan
添加。我还添加了
line_width=0
,以避免栏两侧出现薄橙色框。

结果如下所示:

© www.soinside.com 2019 - 2024. All rights reserved.