如何向条形图添加多个注释 [英] How to add multiple annotations to a barplot

查看:57
本文介绍了如何向条形图添加多个注释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将百分比值 - 除了计数 - 添加到我的 Pandas 条形图中.但是,我无法这样做.我的代码如下所示,到目前为止,我可以获得要显示的计数值.有人可以帮我在每个条形显示的计数值旁边/下方添加相对百分比值吗?

I would like to add percent values - in addition to counts - to my pandas barplot. However, I am not able to do so. My code is shown below and thus far I can get count values to display. Can somebody please help me add relative % values next to/below the count values displayed for each bar?

import matplotlib
import matplotlib.pyplot as plt
%matplotlib inline
plt.style.use('ggplot')

import seaborn as sns
sns.set_style("white")

fig = plt.figure()
fig.set_figheight(5)
fig.set_figwidth(10)

ax = fig.add_subplot(111)

counts = [29227, 102492,  53269, 504028, 802994]

y_ax = ('A','B','C','D','E')
y_tick = np.arange(len(y_ax))

ax.barh(range(len(counts)), counts, align = "center", color = "tab:blue")
ax.set_yticks(y_tick)
ax.set_yticklabels(y_ax, size = 8)

#annotate bar plot with values
for i in ax.patches:
    ax.text(i.get_width()+.09, i.get_y()+.3, str(round((i.get_width()), 1)), fontsize=8)

sns.despine()
plt.show();

我的代码的输出如下所示.如何在显示的每个计数值旁边添加 % 值?

The output of my code is shown below. How can one add % values next to each count value displayed?

推荐答案

With pandas

  • 使用 pandas v1.2.4 进行测试
  • import pandas as pd
    import matplotlib.pyplot as plt
    
    # create the dataframe from values in the OP
    counts = [29227, 102492,  53269, 504028, 802994]
    df = pd.DataFrame(data=counts, columns=['counts'], index=['A','B','C','D','E'])
    
    # add a percent column
    df['%'] = df.counts.div(df.counts.sum()).mul(100).round(2)
    
    # display(df)
       counts      %
    A   29227   1.96
    B  102492   6.87
    C   53269   3.57
    D  504028  33.78
    E  802994  53.82
    

    使用 3.4.2 版本的 matplotlib 绘图

    • 使用matplotlib.pyplot.bar_label
    • 有关其他格式选项,请参阅 matplotlib:条形标签演示页面.
    • 使用 pandas v1.2.4 进行测试,使用 matplotlib 作为绘图引擎.
    • 一些格式化可以使用 fmt 参数完成,但更复杂的格式化应该使用 labels 参数完成.
    • Plot use matplotlib from version 3.4.2

      • Use matplotlib.pyplot.bar_label
      • See the matplotlib: Bar Label Demo page for additional formatting options.
      • Tested with pandas v1.2.4, which is using matplotlib as the plot engine.
      • Some formatting can be done with the fmt parameter, but more sophisticated formatting should be done with the labels parameter.
      • ax = df.plot(kind='barh', y='counts', figsize=(10, 5), legend=False, width=.75,
                     title='This is the plot generated by all code examples in this answer')
        
        # customize the label to include the percent
        labels = [f' {v.get_width()}
         {df.iloc[i, 1]}%' for i, v in enumerate(ax.containers[0])]
        
        # set the bar label
        ax.bar_label(ax.containers[0], labels=labels, label_type='edge', size=13)
        
        ax.spines['right'].set_visible(False)
        ax.spines['top'].set_visible(False)
        plt.show()
        

        # plot the dataframe
        ax = df.plot(kind='barh', y='counts', figsize=(10, 5), legend=False, width=.75)
        for i, y in enumerate(ax.patches):
        
            # get the percent label
            label_per = df.iloc[i, 1]
            
            # add the value label
            ax.text(y.get_width()+.09, y.get_y()+.3, str(round((y.get_width()), 1)), fontsize=10)
            
            # add the percent label here
            ax.text(y.get_width()+.09, y.get_y()+.1, str(f'{round((label_per), 2)}%'), fontsize=10)
        
        ax.spines['right'].set_visible(False)
        ax.spines['top'].set_visible(False)
        plt.show()
        

        没有pandas的原始答案

        • 使用 matplotlib v3.3.4 进行测试
        • Original Answer without pandas

          • Tested with matplotlib v3.3.4
          • import matplotlib.pyplot as plt
            
            fig, ax = plt.subplots(figsize=(10, 5))
            
            counts = [29227, 102492,  53269, 504028, 802994]
            
            # calculate percents
            percents = [100*x/sum(counts) for x in counts]
            
            y_ax = ('A','B','C','D','E')
            y_tick = np.arange(len(y_ax))
            
            ax.barh(range(len(counts)), counts, align = "center", color = "tab:blue")
            ax.set_yticks(y_tick)
            ax.set_yticklabels(y_ax, size = 8)
            
            #annotate bar plot with values
            for i, y in enumerate(ax.patches):
                label_per = percents[i]
                ax.text(y.get_width()+.09, y.get_y()+.3, str(round((y.get_width()), 1)), fontsize=10)
                # add the percent label here
                # ax.text(y.get_width()+.09, y.get_y()+.3, str(round((label_per), 2)), ha='right', va='center', fontsize=10)
                ax.text(y.get_width()+.09, y.get_y()+.1, str(f'{round((label_per), 2)}%'), fontsize=10)
            
            ax.spines['right'].set_visible(False)
            ax.spines['top'].set_visible(False)
            plt.show()
            

            • 你可以玩定位.
            • JohanC
            • 提到的其他格式选项
            • 在一个字符串中打印文本的两个部分,中间有一个 以获得自然"行间距:
            • str(f'{round((y.get_width()), 1)} {round((label_per), 2)}%')
            • ax.text(..., va='center') 垂直居中并能够使用稍大的字体.
            • ax.set_xlim(0, max(counts) * 1.18) 为文本获得更多空间.
            • 以空格开始每行文本以获得自然的水平"填充.
            • str(f' {round((label_per), 2)}%'),注意{前的空格.
            • y.get_width()+.09 非常接近 y.get_width() 当这些值数以万计时.
              • You can play with the positioning.
              • Other formatting options mentioned by JohanC
              • Print both parts of the text in one string with a in between to get a "natural" line spacing:
              • str(f'{round((y.get_width()), 1)} {round((label_per), 2)}%')
              • ax.text(..., va='center') to vertically center and be able to use a slightly larger font.
              • ax.set_xlim(0, max(counts) * 1.18) to get a bit more space for the text.
              • Start each line of text with a space to get a natural "horizontal" padding.
              • str(f' {round((label_per), 2)}%'), note the space before {.
              • y.get_width()+.09 is extremely close to y.get_width() when these values are in the tens of thousands.
              • 这篇关于如何向条形图添加多个注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆