用多指标注释散点图

Annotate scatter plot with multiindex

我使用来自具有多索引的 DataFrame 的数据构建了一个散点图。索引是国家和年份

fig,ax=plt.subplots(1,1)
rel_pib=welfare["rel_pib_pc"].loc[:,1960:2010].groupby("country").mean()
rel_lambda=welfare["Lambda"].loc[:,1960:2010].groupby("country").mean()
ax.scatter(rel_pib,rel_lambda)
ax.set_ylim(0,2)
ax.set_ylabel('Bienestar(Lambda)')
ax.set_xlabel('PIBPc')
ax.plot([0,1],'red', linewidth=1)

我想用国家名称(如果可能的话,还有 Lambda 值)来注释每个点。我有以下代码

for i, txt in enumerate(welfare.index):
    plt.annotate(txt, (welfare["rel_pib_pc"].loc[:,1960:2010].groupby("country").mean()[i], welfare["Lambda"].loc[:,1960:2010].groupby("country").mean()[i]))

我不确定如何表示我想要国家名称,因为给定国家/地区的所有 lambdapib_pc 值都是作为单个值给出的,因为我使用.mean() 函数。

我试过使用 .xs(),但我试过的所有组合都不起作用。

我使用了以下测试数据:

               rel_pib_pc  Lambda
country  year                    
Country1 2007         260    1.12
         2008         265    1.13
         2009         268    1.10
Country2 2007         230    1.05
         2008         235    1.07
         2009         236    1.04
Country3 2007         200    1.02
         2008         203    1.07
         2009         208    1.05

然后,为了生成散点图,我使用了以下代码:

fig, ax = plt.subplots(1, 1)
ax.scatter(rel_pib,rel_lambda)
ax.set_ylabel('Bienestar(Lambda)')
ax.set_xlabel('PIBPc')
ax.set_xlim(190,280)
annot_dy = 0.005
for i, txt in enumerate(rel_lambda.index):
    ax.annotate(txt, (rel_pib.loc[txt], rel_lambda.loc[txt] + annot_dy), ha='center')
plt.show()

得到以下结果:

正确生成注释的技巧是:

  • 枚举已经生成的Series对象之一的索引, 以便 txt 包含国家/地区名称。
  • 从已经生成的 Series 对象中获取值(不计算 再次使用这些值)。
  • 通过当前索引值定位两个坐标。
  • 要将这些注释放在相应点的正上方,请使用:
    • ha(水平对齐)as 'center',
    • shift y 坐标向上一点(如果需要,可以尝试其他 annot_dy.
    • 的值

我还添加了 ax.set_xlim(190,280) 以便将注释保留在 图片矩形。也许你不需要它。