如何根据 python 中的 .groupby 函数制作的 table 绘制多条形图?

How to draw a multi-bar graph based off a table made by .groupby function in python?

我似乎在将此 table(它是使用 group by 函数从数据框生成的)转换为我需要的图表时遇到了一些问题。 table 包含 10 个问题,要求用户以 1 到 5 的等级回答这些问题以及每个性别的平均答案。

Gender Q1 Q2 .......
0(male) 3.7 1.3
1(Female) 2.8 3.1
2(Other) 4.2 4.7

它看起来像这样 table 除了它对所有 10 个问题都适用。目前,当我使用名称为 table 的 .plot 函数时,它正在绘制不正确的图形。它正在绘制这张图:

当我希望每个问题的 3 个性别由 3 个不同的条表示而不是这个图表时。然后 10 个问题中的每一个都会沿着 x 轴。任何有关如何实现这一目标的帮助将不胜感激。

不清楚您的数据是如何组织的,也不清楚您是如何创建 table。

假设输入数据有 3 列:'gender'、'question'、'mark'。这是该表格中的一些数据,以便能够测试:

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

df = pd.DataFrame({'gender': np.random.choice(['male', 'female', 'other'], 1000),
                   'question': pd.Categorical.from_codes(codes=np.random.randint(0, 10, 1000),
                                                         categories=[f'Q{i}' for i in range(1, 11)]),
                   'mark': np.random.randint(1, 6, 1000)})
df['gender'] = pd.Categorical(df['gender'], categories=['male', 'female', 'other'])  # fix an order

然后您可以通过 df.pivot_table(index='gender', columns='question', values='mark') 创建一个 table 并将其绘制为条形图,类似于问题的图像:

df.pivot_table(index='gender', columns='question', values='mark').plot.bar(rot=0, width=0.8)

现在,以相反的方式创建 pivot_table 会将问题作为 x 位置,将性别作为着色:

df.pivot_table(index='question', columns='gender', values='mark').plot.bar(rot=0, width=0.8)

如果你的 table 已经创建,你可以在绘图之前转置它,也会导致 x 轴的问题:

df_table = df.pivot_table(index='gender', columns='question', values='mark')
df_table.T.plot.bar(rot=0, width=0.8)

另一种方法是使用 seaborn,它直接从原始数据帧创建条形图,并(可选)显示误差线(使用 ci=None 抑制误差线)。你只要告诉 seaborn 你想在 x 轴上看到什么,在 y 轴上看到什么,以及颜色分离是什么。

import seaborn as sns

ax = sns.barplot(data=df, x='question', y='mark', hue='gender')
ax.legend(bbox_to_anchor=[1.01, 1.01], loc='upper left')
plt.tight_layout()
plt.show()

现在,如果您的数据框如下所示:

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

df = pd.DataFrame({'Gender': np.arange(3),
                   **{f'Q{i}': np.random.randint(15, 46, 3) / 10 for i in range(1, 11)}})

例如:

  Gender   Q1   Q2   Q3   Q4   Q5   Q6   Q7   Q8   Q9  Q10
0      0  3.9  2.7  2.2  2.6  2.2  2.8  2.2  3.2  2.9  2.9
1      1  4.2  2.0  4.4  2.4  3.6  2.1  1.6  4.0  2.7  4.2
2      2  3.7  3.9  4.2  2.9  3.2  4.4  4.2  2.1  2.9  3.6

您可以使用专有名称使 'Gender' 列分类,将其用作索引,转置数据框并绘制:

df['Gender'] = pd.Categorical.from_codes(df['Gender'], categories=['Male', 'Female', 'Other'])
df.set_index('Gender').T.plot.bar(rot=0, width=0.8)