【问题标题】:Annotate bars with values on Pandas (on Seaborn factorplot bar plot)用 Pandas 上的值注释条形图(在 Seaborn factorplot 条形图上)
【发布时间】:2017-01-23 23:33:34
【问题描述】:

我写了一些代码来尝试解决这个问题: https://stackoverflow.com/questions/39477748/how-to-annotate-bars-with-values-on-pandas-on-seaborn-factorplot-bar-plot

我使用了可以在这里找到的部分代码: matplotlib advanced bar plot

为什么图这么小?该代码只是告诉从 Pandas dataframe 中获取准确性。

代码:

sns.set(style="white")
g = sns.factorplot(x="Stages", y="Accuracy", hue="Dataset", data=df, saturation = 5, size=4, aspect=2, kind="bar",
              palette= myPalette, legend=False)

ax=g.ax
def annotateBars(row, ax=ax):
    if row['Accuracy'] < 20:
        color = 'white'
        vertalign = 'bottom'
        vertpad = 2
    else:
        color = 'black'
        vertalign = 'top'
        vertpad = -2

    ax.text(row.name, row['Accuracy'] + vertpad, "{:.1f}%".format(row['Accuracy']),
            zorder=10, rotation=90, color=color,
            horizontalalignment='center',
            verticalalignment=vertalign,
            fontsize=12, weight='heavy')

junk = df.apply(annotateBars, ax=ax, axis=1)

这是注释每个条形的代码,但是...使用 Pandas 和 Matplotlib。唯一的问题是我不知道如何更改颜色和对“x 轴”进行分组:(

    df = df.set_index('Stages')
    ax = df.plot.bar(title="Accuracy")
    ax.set_ylim(0, 120)
    for p in ax.patches:
        ax.annotate("%.2f" % p.get_height(), (p.get_x() + p.get_width() / 2., p.get_height()),
             ha='center', va='center', rotation=90, xytext=(0, 20), textcoords='offset points')  #vertical bars

【问题讨论】:

  • 图表太小了,注释离右边太远了。您没有为 ax.annotate 提供良好的 x 值
  • 我怎样才能找到好的价值?我正在使用 g.ax;就像您使用的那样: fig, ax = plt.subplots(figsize=(8,3))
  • 查看g.ax.get_xlim()(您应该使用的X值范围)并与df.index(您正在使用的实际X值)进行比较
  • 我应该使用的值:(-0.5, 5.5)。我正在使用的值:(0, 24)。但我有 24 个精度。我无法改变这一点。因此,我将 (-0.5, 5.5) 更改为 (0, 24)。情节总是变小。 :( 所以“factorplot”将每组 4 个条视为 1 个条。:( 我想唯一的方法是使用 matplotlib。:(
  • 那是因为您将get_xlim 的输出分配给了您的ax 变量。不要那样做。我写了一个函数,在绘制条形图时对其进行注释并将其映射到 FacetGrid

标签: python-3.x pandas matplotlib plot seaborn


【解决方案1】:

现在可以更简洁地绘制它

  1. Axes.bar_label 自动标注条形[since matplotlib 3.4]

    for container in ax.containers:
        ax.bar_label(container)
    
  2. Axes.legend 包括 fontsizetitle_fontsize 参数 [自 matplotlib 3.0 起]

    ax.legend(fontsize=10, title='ACCURACY', title_fontsize=24)
    
  3. 另请注意,seaborn.factorplot 已重命名为 seaborn.catplot [从 seaborn 0.9 开始]


更新seaborn.catplot

colors = ['xkcd:windows blue', 'xkcd:orange red', 'xkcd:grey', 'xkcd:amber']  
g = sns.catplot(x='Stages', y='Accuracy', hue='Dataset', data=df,
                kind='bar', height=4, aspect=3, palette=colors, legend=False)

# auto-label bars
for container in g.ax.containers:
    g.ax.bar_label(container, fmt='%.2f', padding=2, rotation=90)

# add legend with custom font sizes
ax.legend(bbox_to_anchor=(0, 1.2, 1, 0.102), loc=10, ncol=4, fontsize=10,
          title='TOTAL ACCURACY AND PER STAGE-RANDOM FOREST', title_fontsize=24)

# redecorate
g.despine(right=False)
g.set_xlabels('')
g.set_ylabels('')
g.ax.set_yticklabels([])

更新DataFrame.plot.bar

ax = df.pivot('Stages', 'Dataset', 'Accuracy').plot.bar(legend=False)

# auto-label bars
for container in ax.containers:
    ax.bar_label(container, fmt='%.2f', padding=3, rotation=90, size='small')

# add legend with custom font sizes
ax.legend(bbox_to_anchor=(0, 1.1, 1, 0.102), loc=10, ncol=4, fontsize='small',
          title='TOTAL ACCURACY AND PER STAGE-RANDOM FOREST', title_fontsize='xx-large')

# redecorate
sns.despine(right=False)
ax.set_yticklabels([])
plt.xticks(rotation=0)

【讨论】:

    【解决方案2】:
        #Seaborn --factorplot
    
        colors = ["windows blue", "orange red", "grey", "amber"]  
        myPalette = sns.xkcd_palette(colors) #envío "colors" a la función xkcd_palette
    
        sns.set(style="white") #fondo blanco
        g = sns.factorplot(x="Stages", y="Accuracy", hue="Dataset", data=df, saturation=5, size=4, aspect=3, kind="bar",
                  palette= myPalette, legend=False) #se suprime la leyenda
    
        g.set(ylim=(0, 140)) 
        g.despine(right=False) 
        g.set_xlabels("") 
        g.set_ylabels("")  
        g.set_yticklabels("") 
    
    
       #Matplotlib --legend creation
    
         myLegend=plt.legend(bbox_to_anchor=(0., 1.2, 1., .102), prop ={'size':10}, loc=10, ncol=4,  #left, bottom, width, height
                    title=r'TOTAL ACCURACY AND PER STAGE-RANDOM FOREST')                    
         myLegend.get_title().set_fontsize('24')
    
    
    
         #Matplotlib --anotación de barras
    
           ax=g.ax #annotate axis = seaborn axis
           def annotateBars(row, ax=ax): 
           for p in ax.patches:
                 ax.annotate("%.2f" % p.get_height(), (p.get_x() + p.get_width() / 2., p.get_height()),
                     ha='center', va='center', fontsize=11, color='gray', rotation=90, xytext=(0, 20),
                     textcoords='offset points')  verticales
    
    
         plot = df.apply(annotateBars, ax=ax, axis=1)
    

    【讨论】:

      猜你喜欢
      • 2014-10-16
      • 2020-02-09
      • 1970-01-01
      相关资源
      最近更新 更多