【问题标题】:How to align annotations at the end of a horizontal bar plot如何在水平条形图的末尾对齐注释
【发布时间】:2020-08-18 23:30:37
【问题描述】:

我正在尝试正确对齐我正在制作的条形图中的数字和百分比,以便它们恰好在每个条形之后,但是尝试这样做时遇到了一些麻烦。我希望:“数字(百分比)”恰好在每个条之后(之间的空间很小)。但是,现在在排名靠前的(前 200 名、前 400 名)的情况下,数量和百分比已经比排名靠后的(前 1-50 名)更靠前。因此,当我尝试移动它们时,底部的缺少上部的,导致外观不太美观。有没有办法解决这个问题?

import matplotlib
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams.update(plt.rcParamsDefault)

labels = ["Top1", "Top3", "Top5", "Top10", "Top20", "Top50", "Top100", "Top200", "Top400"]
native_shape_1000=[38, 42, 44, 48, 52, 57, 61, 66, 68] #Native pose (restr. to shapes & it0 1000)
native_pocket_1000=[43, 51, 51,57,60,64,67,68,69] #Native pose (restr. to pocket residues)

x = np.arange(len(native_shape_1000))  # the label locations
width = 0.4  
fig, axes = plt.subplots(2,2, figsize=(12,8), sharey= False, sharex=False)
axes= axes.flatten()
rects1=axes[0].barh(x - width/2, native_shape_1000, width, label=' Restraints to rank 1 \n pocket shapes;\n it0 = 1000')
rects2=axes[0].barh(x + width/2, native_pocket_1000, width, label=' Restraints to rank 1 \n pocket residues;\n it0 = 1000')

axes[0].set_xlim(xmin=0, xmax=102)
axes[0].set_xticks([x for x in range(0,103,10)])
axes[0].set_yticks(x)
axes[0].set_yticklabels(labels)
axes[0].legend(loc=4, prop={'size': 8})


def autolabel(rects, axes):

    for rect in rects:
        width = rect.get_width()
        perc=int(round(width/102*100))
        axes.annotate(f'{width} ({perc}%) ',
                      xy=(width, rect.get_y()+ rect.get_height()), 
                      xytext=(0,0),
                      textcoords="offset points",
                      ha='left', va='bottom')

autolabel(rects1, axes[0])
# autolabel(rects2)
# autolabel rects3,4 etc.
# fig.tight_layout()

plt.show()

【问题讨论】:

    标签: python matplotlib


    【解决方案1】:

    matplotlib >= 3.4.2

    def autolabel(rects, axes):
        labels = [f'{w} ({int(round(w/102*100))}%)' for rect in rects if (w := rect.get_width()) is not None]
        axes.bar_label(rects, labels=labels, label_type='edge', fontsize=8, padding=3)
    

    matplotlib < 3.4.2

    • rect.get_y() + rect.get_height() / 2 看到rect.get_height() 需要除以2。
    • 更改为va='center_baseline' 并添加fontsize=8
    def autolabel(rects, axes):
        for rect in rects:
            width = rect.get_width()
            perc=int(round(width/102*100))
            axes.annotate(f'{width} ({perc}%)',
                          xy=(width, rect.get_y() + rect.get_height() / 2), 
                          xytext=(0, 0),
                          textcoords="offset points",
                          ha='left', va='center_baseline', fontsize=8)
    
    
    autolabel(rects1, axes[0])
    autolabel(rects2, axes[0])
    

    【讨论】:

      猜你喜欢
      • 2017-08-09
      • 2020-11-22
      • 2017-08-25
      • 2020-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-13
      相关资源
      最近更新 更多