Seaborn 条形图显示来自 groupby 的数值

Seaborn barplot display numeric values from groupby

数据来自:https://www.kaggle.com/datasets/prasertk/homicide-suicide-rate-and-gdp

我有一个工作条形图。

代码:

df_mean_country = df.groupby(["country", "iso3c", "incomeLevel"])["Intentional homicides (per 100,000 people)"].mean().reset_index()
top_ten_hom = df_mean_country.sort_values("Intentional homicides (per 100,000 people)", ascending=False).head(10)
print(top_ten_hom, '\n')


plt.figure(figsize=(16, 8), dpi=200)
plt.xticks(rotation=45, fontsize=14)
plt.ylabel("Suicide mortality rate", fontsize=16, weight="bold")
plt.title("Top 10 countries with Homicides per 100,000 people", fontname="Impact", fontsize=25)
xy = sns.barplot(data=top_ten_hom,
                 y="Intentional homicides (per 100,000 people)",
                 x="country",
                 hue="incomeLevel",
                 dodge=False)
for item in xy.get_xticklabels():
    item.set_rotation(45)
    xy.bar_label(xy.containers[0])
plt.legend(fontsize=14, title="Income Level")
plt.tight_layout()
plt.show()

输出:

问题是它只显示 'Lower Middle Income' 个柱的值。

我假设这是用于创建 df 的 groupby 的某种功能,但我以前从未发生过这种情况。

值都存在:

                   country iso3c          incomeLevel  Intentional homicides (per 100,000 people)
68             El Salvador   SLV  Lower middle income                                      74.178
47                Colombia   COL  Upper middle income                                      50.996
102               Honduras   HND  Lower middle income                                      47.886
218           South Africa   ZAF  Upper middle income                                      42.121
119                Jamaica   JAM  Upper middle income                                      40.821
137                Lesotho   LSO  Lower middle income                                      36.921
256          Venezuela, RB   VEN       Not classified                                      36.432
258  Virgin Islands (U.S.)   VIR          High income                                      35.765
177                Nigeria   NGA  Lower middle income                                      34.524
95               Guatemala   GTM  Upper middle income                                      33.251 

我想要在所有条形图上显示值,而不仅仅是 'Lower Middle Income' 个条形图。

每个色调值都对应 ax.containers 中的一个条目。您可以遍历它们以添加标签。

一些补充说明:

  • Matplotlib 既有“旧的”pyplot 界面,也有“新的”object-oriented interface(已经超过 10 年了)。不混合它们有助于提高可读性和可维护性。一些较新的功能仅存在于 object-oriented 接口中(例如 ax.tick_params())。
  • 更改标签等最好在创建 seaborn 图之后进行,因为 seaborn 会设置自己的标签和参数。
  • 为了更轻松地将教程和代码示例映射到您的代码,将 sns.barplot 的 return 值命名为 ax.
  • 之类的名称会有所帮助
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd

df = pd.read_csv('suicide homicide gdp.csv')
df_mean_country = df.groupby(["country", "iso3c", "incomeLevel"])[
     "Intentional homicides (per 100,000 people)"].mean().reset_index()
top_ten_hom = df_mean_country.sort_values("Intentional homicides (per 100,000 people)", ascending=False).head(10)

plt.figure(figsize=(16, 8), dpi=200)
ax = sns.barplot(data=top_ten_hom,
                 y="Intentional homicides (per 100,000 people)",
                 x="country",
                 hue="incomeLevel",
                 dodge=False)
ax.set_ylabel("Suicide mortality rate", fontsize=16, weight="bold")
ax.set_xlabel("")
ax.set_title("Top 10 countries with Homicides per 100,000 people", fontname="Impact", fontsize=25)

ax.tick_params(axis='x', rotation=45, size=0, labelsize=14)

for bars in ax.containers:
     ax.bar_label(bars, fontsize=12, fmt='%.2f')
ax.legend(fontsize=14, title="Income Level", title_fontsize=18)
plt.tight_layout()
plt.show()