简体   繁体   English

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

[英]Plotting Multiple Plots of Bar Charts in Bokeh Using Looping

I have a dataframe with multiple columns as below:我有一个 dataframe 多列如下:

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

I want to plot multiple bar graphs in different plots and i managed to do it one by one using the code below:我想在不同的图中 plot 多个条形图,我设法使用下面的代码一一完成:

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)

As you can see, this is very ineffective way because i need to repetitively define y_max, figure, and vbar .如您所见,这是非常无效的方法,因为我需要重复定义y_max、figure 和 vbar How do i do this using loop because I have more than 20 columns to plot.我如何使用循环来执行此操作,因为我有超过 20 列到 plot。

You don't need to set the ranges manually - just specify the start value and the span.您不需要手动设置范围 - 只需指定起始值和跨度。 Bokeh will compute the end value for you. 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']))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM