【问题标题】:Annotate values for stacked horizontal bar in pandas注释熊猫中堆叠水平条的值
【发布时间】:2018-12-24 03:08:26
【问题描述】:

我正在尝试对使用 pandas 创建的堆叠水平条形图的值进行注释。当前代码如下

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

d = {'group 1': [1, 2, 5, 7, 4, 5, 10],
     'group 2': [5, 6, 1, 8, 2, 6, 2],
     'group 3': [12, 2, 2, 4, 4, 8, 4]}
df = pd.DataFrame(d)

ax = df.plot.barh(stacked=True, figsize=(10,12))

for p in ax.patches:
    ax.annotate(str(p.get_x()), xy=(p.get_x(), p.get_y()+0.2))

plt.legend(bbox_to_anchor=(0, -0.15), loc=3, prop={'size': 14}, frameon=False)

问题是我使用的注释方法给出了 x 起点,而不是每个段的值。我希望能够在每个条的每个段的中心注释每个段的值。

example

编辑:为清楚起见,我想要实现的是这样的,其中每个段的值水平(和垂直)居中:

enter image description here

任何帮助将不胜感激。

【问题讨论】:

  • 您能否再次解释一下您希望注释的位置。举个例子,假设 y 的一个固定值。

标签: python pandas matplotlib


【解决方案1】:

您可以使用补丁bbox 来获取您想要的信息。

ax = df.plot.barh(stacked=True, figsize=(10, 12))
for p in ax.patches:
    left, bottom, width, height = p.get_bbox().bounds
    ax.annotate(str(width), xy=(left+width/2, bottom+height/2), 
                ha='center', va='center')

【讨论】:

    【解决方案2】:

    另一种可能的解决方案是通过values = df.values.flatten("F") 将您的df.values 转换为扁平数组

    %matplotlib inline
    import pandas as pd 
    import matplotlib.pyplot as plt
    import numpy as np
    
    d = {'group 1': [1, 2, 5, 7, 4, 5, 10],
         'group 2': [5, 6, 1, 8, 2, 6, 2],
         'group 3': [12, 2, 2, 4, 4, 8, 4]}
    df = pd.DataFrame(d)
    
    ax = df.plot.barh(stacked=True, figsize=(10,12))
    
    values = df.values.flatten("F")
    
    for i, p in enumerate(ax.patches):
        ax.annotate(str(values[i]), xy=(p.get_x()+ values[i]/2, p.get_y()+0.2))
    
    plt.legend(bbox_to_anchor=(0, -0.15), loc=3, prop={'size': 14}, frameon=False);
    

    【讨论】: