[英]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 轴必须显示“结果”中的值,条形图的图例必须显示“方法”中的值
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]}')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.