【问题标题】:How to label bars with multiple custom values如何使用多个自定义值标记条形图
【发布时间】:2022-09-25 00:55:05
【问题描述】:

我有这个数据框

rules count    percentage    groups   weight

A      15      24%            1       10
B      5       2%             2       30
C      25      50%            3       50

我有以下代码:

sns.set(rc={\'figure.figsize\':(18,9.5)})
plots = sns.barplot(x=\"rules\", y=\"count\", data=df, hue=df[\'groups\'], dodge=False)
percentage = df[\'percentage\'].tolist()
weight = df[\'weight\'].tolist()
patches = plots.patches
for i in range(len(patches)):
   x = patches[i].get_x() + patches[i].get_width()/2
   y = patches[i].get_height()+.09
   plots.annotate(\'{:.1f}%\'.format(percentage[i]), (x, y), ha=\'center\',  va=\'bottom\', size=14)
   plots.annotate(\'{:.0f}\'.format(weight[i]), (x, y), ha=\'center\', va=\'top\', color=\'white\', size=15, fontweight=\"bold\")

尝试用百分比注释条形图时出现以下错误。

条形图内部是另一个数字,对应于 df 中的权重列。

IndexError                                Traceback (most recent call last)
<ipython-input-120-0ef14f891711> in <module>()
      7    x = patches[i].get_x() + patches[i].get_width()/2
      8    y = patches[i].get_height()+.09
----> 9    plots.annotate(\'{:.1f}%\'.format(percentage[i]), (x, y), ha=\'center\',  va=\'bottom\', size=14)
     10    plots.annotate(\'{:.0f}\'.format(weight[i]), (x, y), ha=\'center\', va=\'top\', color=\'white\', size=15, fontweight=\"bold\")
     11 plots.set_xticklabels(plots.get_xticklabels(), rotation=90, fontsize=15)

IndexError: list index out of range

    标签: python matplotlib seaborn bar-chart plot-annotations


    【解决方案1】:
    import pandas as pd
    import seaborn as sns
    
    # test data
    data = {'rules': ['A', 'B', 'C'], 'count': [15, 5, 25],
            'percentage': ['24%', '2%', '50%'], 'groups': [1, 2, 3], 'weight': [10, 30, 50]}
    df = pd.DataFrame(data)
    
    # plot
    ax = sns.barplot(x="rules", y="count", data=df, hue='groups', dodge=False)
    
    # since you are using hue, there are multiple containers
    for c in ax.containers:
        # set the bar label based on the y-axis
        ax.bar_label(c, label_type='center', padding=1)
        # add an annotations with custom labels
        ax.bar_label(c, labels=df.percentage, label_type='edge', padding=1)
    
    # pad the spacing between the number and the edge of the figure 
    ax.margins(y=0.1)
    


    • 带有两个自定义标签('weight''percentage')的注释。
    ax = sns.barplot(x="rules", y="count", data=df, hue='groups', dodge=False)
    
    # since you are using hue, there are multiple containers
    for c in ax.containers:
        # add an annotations with custom labels
        ax.bar_label(c, labels=df.weight, label_type='center')
        # add an annotations with custom labels
        ax.bar_label(c, labels=df.percentage, label_type='edge', padding=1)
        
    ax.margins(y=0.1)
    


    • 现有代码的问题是有9个补丁,如print(patches)list(patches)所示,可以通过只选择高度大于0的补丁来解决。
      • 出现这种情况是因为正在使用hue,但'groups' 中只有一个值对应'rules' 中的每个值。
    plots = sns.barplot(x="rules", y="count", data=df, hue=df['groups'], dodge=False)
    percentage = df['percentage'].tolist()
    weight = df['weight'].tolist()
    patches = plots.patches
    
    # select patches with a height > 0
    patches = [p for p in patches if p.get_height() > 0]
    
    for i, p in enumerate(patches):
        
        x = p.get_x() + patches[i].get_width()/2
        y = p.get_height()+.09
        
        plots.annotate(f'{percentage[i]}', (x, y), ha='center',  va='bottom', size=14)
        plots.annotate(f'{weight[i]:.0f}', (x, y), ha='center', va='top', color='white', size=15, fontweight="bold")
    

    【讨论】:

      猜你喜欢
      • 2017-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多