简体   繁体   English

使用 matplotlib 按三列分组条形图

[英]Grouped bar chart by three column using matplotlib

I am trying to display a grouped bar chart by categorical values on columns.我正在尝试按列上的分类值显示分组条形图。

An example data is below.示例数据如下。

df = pd.DataFrame({'Type': ['A','A','A','A','A','A','A','A','A','B','B','B','B','B','B','B','B','B'],
                   'Ratio': [3, 3, 3, 5, 5, 5, 7, 7, 7,3, 3, 3, 5, 5, 5, 7, 7, 7],
                   'Method': ['X','Y','Z','X','Y','Z','X','Y','Z','X','Y','Z','X','Y','Z','X','Y','Z'],
                   'Result': [90, 85, 96, 89, 82, 80, 78, 72, 75, 91, 82, 94, 87, 86, 84, 71, 78, 86]})

Values in "Type" column can be on the same chart or two subplot graphs. “类型”列中的值可以在同一个图表或两个子图上。 The Y axis must display the value in "Result" and the legend of the bar chart must display the value in "Method" Y 轴必须显示“结果”中的值,条形图的图例必须显示“方法”中的值

Example例子

My dataset is quite large compared to the example above so a loop or function would be more useful.与上面的示例相比,我的数据集非常大,因此循环或 function 会更有用。

My code below is not working as I want.我下面的代码无法正常工作。

fig, ax = plt.subplots(figsize=(4,3))

for t in ["A", "B"]:
    
    df1 = df.loc[df["Type"] == t]
    
    for r, w in zip([3,5,7], [5, 10, 15]):
        
        df2 = df1.loc[df1["Ratio"] == r]
        
        for m, i in zip(["X","Y","Z"], range(3)):
            
            df3 = df2.loc[df2["Method"] == m]
            
            label = str(m)
            ax.bar((w+i), df3["Result"], label=label)
            
plt.savefig("test.svg")
import pandas as pd
import matplotlib.pyplot as plt


grouped_A = df[df['Type'] == 'A']
grouped_B = df[df['Type'] == 'B']

fig, ax = plt.subplots(1, 2, figsize=(15, 5))

for r, w in zip([3,5,7], [5, 10, 15]):
    
    A = grouped_df_A.loc[grouped_df_A["Ratio"] == r]
    B = grouped_df_B.loc[grouped_df_B["Ratio"] == r]
    
    for m, i in zip(["X","Y","Z"], range(3)):
        
        methodA = A.loc[A["Method"] == m]
        methodB = B.loc[B["Method"] == m]
            
        label = str(m)
        ax[0].bar((w+i), methodA["Result"], label=label)
        ax[0].set_title("Type A")
        
        ax[1].bar((w+i), methodB["Result"], label=label)
        ax[1].set_title("Type B")
            
plt.show()

Consider a subset loop with pandas DataFrame.groupby , then pivoting data with DataFrame.pivot_table , and finally running plot with DataFrame.plot :考虑使用 pandas DataFrame.groupby的子集循环,然后使用DataFrame.pivot_table旋转数据,最后使用 DataFrame.plot 运行DataFrame.plot

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

df = pd.DataFrame({
    'Type': ['A','A','A','A','A','A','A','A','A','B','B','B','B','B','B','B','B','B'],
    'Ratio': [3, 3, 3, 5, 5, 5, 7, 7, 7,3, 3, 3, 5, 5, 5, 7, 7, 7],
    'Method': ['X','Y','Z','X','Y','Z','X','Y','Z','X','Y','Z','X','Y','Z','X','Y','Z'],
    'Result': [90, 85, 96, 89, 82, 80, 78, 72, 75, 91, 82, 94, 87, 86, 84, 71, 78, 86]
})


num_types = len(df["Type"].unique())
fig, axes = plt.subplots(figsize=(12,4), ncols=num_types, nrows=1)

# FLATTEN MULTI-DIMENSIONAL ARRAY
axes = np.ravel(axes)

# ITERATE THROUGH TYPE GROUPS
for (g, df), ax in zip(df.groupby("Type"), axes):
    # PIVOT FOR  WIDE DATA FOR BAR CHART
    (
        df.pivot_table(index="Ratio", columns="Method", values="Result", aggfunc="sum")
          .plot(kind="bar", ax=ax, rot=0, title=f"{g} - Bar Chart")
    )

plt.show()
fig.savefig("bar_chart.png")

plt.clf()
plt.close()

条形图输出

This should work multiple types in your Type column creating vertical subplots for each.这应该可以在您的类型列中使用多种类型,为每种类型创建垂直子图。

item_list = list(df.Type.unique())
fig, ax = plt.subplots(len(item_list), figsize=(12, 8))
for t in range(len(item_list)):    
    df1 = df.loc[df["Type"] == item_list[t]]    
    for r, w in zip([3,5,7], [5, 10, 15]):
        
        df2 = df1.loc[df1["Ratio"] == r]
        
        for m, i in zip(["X","Y","Z"], range(3)):
            
            df3 = df2.loc[df2["Method"] == m]
            
            label = str(m)
            ax[t].bar((w+i), df3["Result"], label=label)
            ax[t].set_title(f'Type{item_list[t]}')

see plots here在这里查看地块

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

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