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

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

问题描述

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

  import matplotlib导入matplotlib.pyplot作为plt%matplotlib 内联plt.style.use('ggplot')将 seaborn 作为 sns 导入sns.set_style(白色")无花果= plt.figure()fig.set_figheight(5)fig.set_figwidth(10)ax = fig.add_subplot(111)计数 = [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)#用值注释条形图对于我在ax.patches中:ax.text(i.get_width()+.09, i.get_y()+.3, str(round((i.get_width()), 1)), fontsize=8)sns.despine()plt.show();

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

解决方案

使用 pandas

  • 使用 pandas v1.2.4 进行测试

导入和加载数据

 将熊猫作为pd导入导入matplotlib.pyplot作为plt# 从 OP 中的值创建数据框计数= [29227、102492、53269、504028、802994]df = pd.DataFrame(data=counts, columns=['counts'], index=['A','B','C','D','E'])# 添加百分比列df ['%'] = df.counts.div(df.counts.sum()).mul(100).round(2)# 显示(df)计数 %一个29227 1.96乙 102492 6.87C 53269 3.57D 504028 33.78E 802994 53.82

使用 3.4.2 版中的 matplotlib 绘图

  • 使用

    注释资源 - 来自 matplotlib v3.4.2

    • 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

      • Tested with pandas v1.2.4

      Imports and Load Data

      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
      

      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()}\n {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()
      

      Annotation Resources - from matplotlib v3.4.2

      Plot use matplotlib before version 3.4.2

      # 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()
      

      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()
      

      • You can play with the positioning.
      • Other formatting options mentioned by JohanC
      • Print both parts of the text in one string with a \n in between to get a "natural" line spacing:
      • str(f'{round((y.get_width()), 1)}\n{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天全站免登陆