使用循环在散景中绘制多个条形图

雨123

我有一个包含多列的数据框,如下所示:

data = pd.DataFrame({'Year': ['2016', '2017', '2018', '2019', '2020'],
                 'A1 Qty': [743.85, 608.75, 1099.14, 1253.50, 239.45],
                 'A2 Qty': [0.0, 0.0, 0.0, 1280.78, 1138.66],
                 'B1 Qty': [153.3, 213.04, 125.85, 0.0, 0.0],
                 'B2 Qty': [832.93, 1080.74, 1188.46, 0.0, 0.0],
                 'C1 Qty': [11.47, 9.52, 11.57, 10.1, 1.52],
                 'C2 Qty': [14.33, 15.88, 2.53, 9.98, 1.87]
                })

我想在不同的图中绘制多个条形图,我设法使用以下代码一一完成:

src = ColumnDataSource(data)
y_max = max(src.data['A1 Qty'].max(), src.data['A2 Qty'].max())
y_max*=1.50

y_max1 =  max(src.data['B1 Qty'].max(), src.data['B2 Qty'].max())
y_max1*=1.50

y_max2 =  max(src.data['C1 Qty'].max(), src.data['C2 Qty'].max())
y_max2*=1.50

#if loop what change? y_range, title,

s = figure(x_range=src.data['Year'], y_range=(0, y_max), plot_height=250, title="A1 vs A2 by Year",
           toolbar_location=None, tools="")

s.vbar(x=dodge('Year', -0.25, range=s.x_range), top='A1 Qty', width=0.2, source=src,
       color="gold", legend="Actual")#, legend_label="Actual")

s.vbar(x=dodge('Year',  0, range=s.x_range), top='A2 Qty', width=0.2, source=src,
       color="indianred", legend="Recommended")#,  legend_label="Recommended")

s1 = figure(x_range=src.data['Year'], y_range=(0, y_max1), plot_height=250, title="B1 vs B2 by Year",
           toolbar_location=None, tools="")

s1.vbar(x=dodge('Year', -0.25, range=s1.x_range), top='B1 Qty', width=0.2, source=src,
       color="gold", legend="Actual")#, legend_label="Actual")

s1.vbar(x=dodge('Year',  0, range=s1.x_range), top='B2 Qty', width=0.2, source=src,
       color="indianred", legend="Recommended")#,  legend_label="Recommended")


s2 = figure(x_range=src.data['Year'], y_range=(0, y_max2), plot_height=250, title="C1 vs C2 by Year",
           toolbar_location=None, tools="")

s2.vbar(x=dodge('Year', -0.25, range=s2.x_range), top='C1 Qty', width=0.2, source=src,
       color="gold", legend="Actual")#, legend_label="Actual")

s2.vbar(x=dodge('Year',  0, range=s2.x_range), top='C2 Qty', width=0.2, source=src,
       color="indianred", legend="Recommended")#,  legend_label="Recommended")


layout = row(s,s1,s2)

show(layout)

如您所见,这是非常无效的方式,因为我需要重复定义y_max、figure 和 vbar我如何使用循环来执行此操作,因为我有 20 多列要绘制。

尤金·帕霍莫夫

您不需要手动设置范围 - 只需指定起始值和跨度。Bokeh 将为您计算最终值。

import pandas as pd

from bokeh.io import show
from bokeh.layouts import row
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure
from bokeh.transform import dodge

data = pd.DataFrame({'Year': ['2016', '2017', '2018', '2019', '2020'],
                     'A1 Qty': [743.85, 608.75, 1099.14, 1253.50, 239.45],
                     'A2 Qty': [0.0, 0.0, 0.0, 1280.78, 1138.66],
                     'B1 Qty': [153.3, 213.04, 125.85, 0.0, 0.0],
                     'B2 Qty': [832.93, 1080.74, 1188.46, 0.0, 0.0],
                     'C1 Qty': [11.47, 9.52, 11.57, 10.1, 1.52],
                     'C2 Qty': [14.33, 15.88, 2.53, 9.98, 1.87]})

src = ColumnDataSource(data)


def mk_plot(label1, label2):
    s = figure(x_range=src.data['Year'], plot_height=250, title=f"{label1} vs {label2} by Year",
               toolbar_location=None, tools="")
    s.y_range.start = 0
    # 1 instead of 0.5 because it gets divided by half, but the "start" half
    # is not taken into account because we set the start manually.
    s.y_range.range_padding = 1

    s.vbar(x=dodge('Year', -0.25, range=s.x_range), top=f'{label1} Qty', width=0.2, source=src,
           color="gold", legend_label="Actual")
    s.vbar(x=dodge('Year', 0, range=s.x_range), top=f'{label2} Qty', width=0.2, source=src,
           color="indianred", legend_label="Recommended")
    return s


show(row([mk_plot(f'{l}1', f'{l}2') for l in 'ABC']))

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章