📜  如何在Python中的分组条形图中注释条形?

📅  最后修改于: 2022-05-13 01:55:51.561000             🧑  作者: Mango

如何在Python中的分组条形图中注释条形?

条形图是表示类别特征和数字特征之间关系的图形。许多矩形条对应分类特征的每个类别,这些条的大小代表相应的值。使用分组条形图,我们可以研究两个以上特征之间的关系。

在Python中,我们可以使用 Matplotlib 库或 seaborn 库绘制条形图,它是构建在 Matplotlib 上的更高级别的库,它也支持 Pandas 数据结构。在本文中,我们使用 seaborn.barplot()函数绘制分组条形图。

使用条形图进行数据可视化的另一个重要方面是使用注释,即添加文本以更好地理解图表。这可以通过使用 matplotlib 库的 pyplot 模块中的 annotate()函数来实现,如以下步骤所述。

步骤 1:导入库和使用的数据集。这里我们使用了泰坦尼克号数据集,它内置于 seaborn 中。

Python3
# importing the libraries used
import seaborn as sns
import matplotlib.pyplot as plt
  
# Importing the dataset
df = sns.load_dataset("titanic")
print(df.head())


Python3
# transforming the dataset for barplot
data_df = df.groupby(['sex', 'class']).agg(
    avg_age=('age', 'mean'), count=('sex', 'count'))
  
data_df = data_df.reset_index()
print(data_df.head())


Python3
# code to plot a simple grouped barplot
plt.figure(figsize=(8, 6))
sns.barplot(x="class", y="avg_age",
            hue="sex", data=data_df,
            palette='Greens')
  
plt.ylabel("Average Age", size=14)
plt.xlabel("Ticket Class", size=14)
plt.title("Simple Grouped Barplot", size=18)


Python3
# code for annotated grouped barplot
plt.figure(figsize=(8, 6))
splot = sns.barplot(x="class", y="avg_age", hue="sex",
                    data=data_df, palette='Greens')
  
for p in splot.patches:
    splot.annotate(format(p.get_height()),
                   (p.get_x() + p.get_width() / 2., p.get_height()),
                   ha='center', va='center',
                   xytext=(0, 9),
                   textcoords='offset points')
      
plt.ylabel("Average Age", size=14)
plt.xlabel("Ticket Class", size=14)
plt.title("Grouped Barplot with annotations", size=18)


Python3
# code for annotated barplot
plt.figure(figsize=(8, 6))
splot = sns.barplot(x="class", y="avg_age", hue="sex",
                    data=data_df, palette='Greens')
  
plt.ylabel("Average Age", size=14)
plt.xlabel("Ticket Class", size=14)
plt.title("Grouped Barplot with annotations", size=18)
for p in splot.patches:
    splot.annotate(format(round(p.get_height()), '.0f')+"Years",
                   (p.get_x() + p.get_width() / 2., p.get_height()),
                   ha='center', va='center',
                   size=14,
                   xytext=(0, -12),
                   textcoords='offset points')


输出:

原始数据集

我们将绘制一个分组条形图,以分析不同机票等级中泰坦尼克号上旅客的平均年龄和数量,按性别划分。为此,我们需要转换数据集。

第 2 步:在原始数据集上使用分组和聚合来转换数据集。

蟒蛇3

# transforming the dataset for barplot
data_df = df.groupby(['sex', 'class']).agg(
    avg_age=('age', 'mean'), count=('sex', 'count'))
  
data_df = data_df.reset_index()
print(data_df.head())

输出:

转换后的数据集

说明:分组条形图至少需要两个分类特征和一个数值特征。在这里,我们使用 pandas.Dataframe.groupby()函数过滤掉了要分类的 'class' 特征和对条形进行分组的 'sex' 特征。然后我们使用 pandas.core.groupby.DataFrameGroupBy.agg() 汇总了每个组的平均年龄和计数。之前的操作导致了多索引数据帧,因此我们重置索引以获得如下所示的数据集。

第 3 步:现在,我们使用 seaborn.barplot()函数使用转换后的数据集绘制一个简单的条形图。

蟒蛇3

# code to plot a simple grouped barplot
plt.figure(figsize=(8, 6))
sns.barplot(x="class", y="avg_age",
            hue="sex", data=data_df,
            palette='Greens')
  
plt.ylabel("Average Age", size=14)
plt.xlabel("Ticket Class", size=14)
plt.title("Simple Grouped Barplot", size=18)

输出 :

请注意,我们已使用 'hue' 关键字参数根据 'sex' 特征对条形进行分组。

第 4 步:注释条形

蟒蛇3

# code for annotated grouped barplot
plt.figure(figsize=(8, 6))
splot = sns.barplot(x="class", y="avg_age", hue="sex",
                    data=data_df, palette='Greens')
  
for p in splot.patches:
    splot.annotate(format(p.get_height()),
                   (p.get_x() + p.get_width() / 2., p.get_height()),
                   ha='center', va='center',
                   xytext=(0, 9),
                   textcoords='offset points')
      
plt.ylabel("Average Age", size=14)
plt.xlabel("Ticket Class", size=14)
plt.title("Grouped Barplot with annotations", size=18)

输出:

说明:在上面的代码中,我们使用了 seaborn 绘图对象的 'patches' 属性来遍历每个条。我们已经使用 annotate函数为每个条形计算了高度、坐标和放置文本。

第 5 步:由于每个条形都代表年龄,因此设置小数点并不能使其值合理。我们将通过四舍五入到最接近的整数来自定义我们的文本,然后使用 format()函数,如下面的代码所示。

蟒蛇3

# code for annotated barplot
plt.figure(figsize=(8, 6))
splot = sns.barplot(x="class", y="avg_age", hue="sex",
                    data=data_df, palette='Greens')
  
plt.ylabel("Average Age", size=14)
plt.xlabel("Ticket Class", size=14)
plt.title("Grouped Barplot with annotations", size=18)
for p in splot.patches:
    splot.annotate(format(round(p.get_height()), '.0f')+"Years",
                   (p.get_x() + p.get_width() / 2., p.get_height()),
                   ha='center', va='center',
                   size=14,
                   xytext=(0, -12),
                   textcoords='offset points')

输出:

此外,通过更改坐标,我们已经在栏中移动了我们的文本。