How to display the value of the bar on each bar with pyplot.barh()?












47















I generated a bar plot, how can I display the value of the bar on each bar?



Current plot:



enter image description here



What I am trying to get:



enter image description here



My code:



import os
import numpy as np
import matplotlib.pyplot as plt

x = [u'INFO', u'CUISINE', u'TYPE_OF_PLACE', u'DRINK', u'PLACE', u'MEAL_TIME', u'DISH', u'NEIGHBOURHOOD']
y = [160, 167, 137, 18, 120, 36, 155, 130]

fig, ax = plt.subplots()
width = 0.75 # the width of the bars
ind = np.arange(len(y)) # the x locations for the groups
ax.barh(ind, y, width, color="blue")
ax.set_yticks(ind+width/2)
ax.set_yticklabels(x, minor=False)
plt.title('title')
plt.xlabel('x')
plt.ylabel('y')
#plt.show()
plt.savefig(os.path.join('test.png'), dpi=300, format='png', bbox_inches='tight') # use format='svg' or 'pdf' for vectorial pictures









share|improve this question



























    47















    I generated a bar plot, how can I display the value of the bar on each bar?



    Current plot:



    enter image description here



    What I am trying to get:



    enter image description here



    My code:



    import os
    import numpy as np
    import matplotlib.pyplot as plt

    x = [u'INFO', u'CUISINE', u'TYPE_OF_PLACE', u'DRINK', u'PLACE', u'MEAL_TIME', u'DISH', u'NEIGHBOURHOOD']
    y = [160, 167, 137, 18, 120, 36, 155, 130]

    fig, ax = plt.subplots()
    width = 0.75 # the width of the bars
    ind = np.arange(len(y)) # the x locations for the groups
    ax.barh(ind, y, width, color="blue")
    ax.set_yticks(ind+width/2)
    ax.set_yticklabels(x, minor=False)
    plt.title('title')
    plt.xlabel('x')
    plt.ylabel('y')
    #plt.show()
    plt.savefig(os.path.join('test.png'), dpi=300, format='png', bbox_inches='tight') # use format='svg' or 'pdf' for vectorial pictures









    share|improve this question

























      47












      47








      47


      29






      I generated a bar plot, how can I display the value of the bar on each bar?



      Current plot:



      enter image description here



      What I am trying to get:



      enter image description here



      My code:



      import os
      import numpy as np
      import matplotlib.pyplot as plt

      x = [u'INFO', u'CUISINE', u'TYPE_OF_PLACE', u'DRINK', u'PLACE', u'MEAL_TIME', u'DISH', u'NEIGHBOURHOOD']
      y = [160, 167, 137, 18, 120, 36, 155, 130]

      fig, ax = plt.subplots()
      width = 0.75 # the width of the bars
      ind = np.arange(len(y)) # the x locations for the groups
      ax.barh(ind, y, width, color="blue")
      ax.set_yticks(ind+width/2)
      ax.set_yticklabels(x, minor=False)
      plt.title('title')
      plt.xlabel('x')
      plt.ylabel('y')
      #plt.show()
      plt.savefig(os.path.join('test.png'), dpi=300, format='png', bbox_inches='tight') # use format='svg' or 'pdf' for vectorial pictures









      share|improve this question














      I generated a bar plot, how can I display the value of the bar on each bar?



      Current plot:



      enter image description here



      What I am trying to get:



      enter image description here



      My code:



      import os
      import numpy as np
      import matplotlib.pyplot as plt

      x = [u'INFO', u'CUISINE', u'TYPE_OF_PLACE', u'DRINK', u'PLACE', u'MEAL_TIME', u'DISH', u'NEIGHBOURHOOD']
      y = [160, 167, 137, 18, 120, 36, 155, 130]

      fig, ax = plt.subplots()
      width = 0.75 # the width of the bars
      ind = np.arange(len(y)) # the x locations for the groups
      ax.barh(ind, y, width, color="blue")
      ax.set_yticks(ind+width/2)
      ax.set_yticklabels(x, minor=False)
      plt.title('title')
      plt.xlabel('x')
      plt.ylabel('y')
      #plt.show()
      plt.savefig(os.path.join('test.png'), dpi=300, format='png', bbox_inches='tight') # use format='svg' or 'pdf' for vectorial pictures






      python matplotlib bar-chart






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked May 14 '15 at 1:55









      Franck DernoncourtFranck Dernoncourt

      37.8k32196344




      37.8k32196344
























          6 Answers
          6






          active

          oldest

          votes


















          90














          Add:



          for i, v in enumerate(y):
          ax.text(v + 3, i + .25, str(v), color='blue', fontweight='bold')


          result:



          enter image description here



          The y-values v are both the x-location and the string values for ax.text, and conveniently the barplot has a metric of 1 for each bar, so the enumeration i is the y-location.






          share|improve this answer





















          • 6





            maybe replace use va='center', instead of "i + .25" for the horizontal alignment

            – mathause
            Sep 26 '17 at 16:40






          • 4





            plt.text(v, i, " "+str(v), color='blue', va='center', fontweight='bold')

            – João Cartucho
            Apr 18 '18 at 11:41





















          17














          I have noticed api example code contains an example of barchart with the value of the bar displayed on each bar:



          """
          ========
          Barchart
          ========

          A bar plot with errorbars and height labels on individual bars
          """
          import numpy as np
          import matplotlib.pyplot as plt

          N = 5
          men_means = (20, 35, 30, 35, 27)
          men_std = (2, 3, 4, 1, 2)

          ind = np.arange(N) # the x locations for the groups
          width = 0.35 # the width of the bars

          fig, ax = plt.subplots()
          rects1 = ax.bar(ind, men_means, width, color='r', yerr=men_std)

          women_means = (25, 32, 34, 20, 25)
          women_std = (3, 5, 2, 3, 3)
          rects2 = ax.bar(ind + width, women_means, width, color='y', yerr=women_std)

          # add some text for labels, title and axes ticks
          ax.set_ylabel('Scores')
          ax.set_title('Scores by group and gender')
          ax.set_xticks(ind + width / 2)
          ax.set_xticklabels(('G1', 'G2', 'G3', 'G4', 'G5'))

          ax.legend((rects1[0], rects2[0]), ('Men', 'Women'))


          def autolabel(rects):
          """
          Attach a text label above each bar displaying its height
          """
          for rect in rects:
          height = rect.get_height()
          ax.text(rect.get_x() + rect.get_width()/2., 1.05*height,
          '%d' % int(height),
          ha='center', va='bottom')

          autolabel(rects1)
          autolabel(rects2)

          plt.show()


          output:



          enter image description here



          FYI What is the unit of height variable in "barh" of matplotlib? (as of now, there is no easy way to set a fixed height for each bar)






          share|improve this answer





















          • 1





            It seems like get_x() rounds the number up even if the original x has decimal places. How do you get more decimal places to display?

            – ru111
            Jan 10 '18 at 16:16






          • 1





            late to the party but for anyone else using this using height+0.1 instead of 1.05*height in the autolabel function creates a consistent gap between the bar and text

            – jnPy
            Mar 14 '18 at 10:11





















          7














          I know it's an old thread, but I landed here several times via Google and think no given answer is really satisfying yet. Try using one of the following functions:



          EDIT: As I'm getting some likes on this old thread, I wanna share an updated solution as well (basically putting my two previous functions together and automatically deciding whether it's a bar or hbar plot):



          def label_bars(ax, bars, text_format, **kwargs):
          """
          Attaches a label on every bar of a regular or horizontal bar chart
          """
          ys = [bar.get_y() for bar in bars]
          y_is_constant = all(y == ys[0] for y in ys) # -> regular bar chart, since all all bars start on the same y level (0)

          if y_is_constant:
          _label_bar(ax, bars, text_format, **kwargs)
          else:
          _label_barh(ax, bars, text_format, **kwargs)


          def _label_bar(ax, bars, text_format, **kwargs):
          """
          Attach a text label to each bar displaying its y value
          """
          max_y_value = ax.get_ylim()[1]
          inside_distance = max_y_value * 0.05
          outside_distance = max_y_value * 0.01

          for bar in bars:
          text = text_format.format(bar.get_height())
          text_x = bar.get_x() + bar.get_width() / 2

          is_inside = bar.get_height() >= max_y_value * 0.15
          if is_inside:
          color = "white"
          text_y = bar.get_height() - inside_distance
          else:
          color = "black"
          text_y = bar.get_height() + outside_distance

          ax.text(text_x, text_y, text, ha='center', va='bottom', color=color, **kwargs)


          def _label_barh(ax, bars, text_format, **kwargs):
          """
          Attach a text label to each bar displaying its y value
          Note: label always outside. otherwise it's too hard to control as numbers can be very long
          """
          max_x_value = ax.get_xlim()[1]
          distance = max_x_value * 0.0025

          for bar in bars:
          text = text_format.format(bar.get_width())

          text_x = bar.get_width() + distance
          text_y = bar.get_y() + bar.get_height() / 2

          ax.text(text_x, text_y, text, va='center', **kwargs)


          Now you can use them for regular bar plots:



          fig, ax = plt.subplots((5, 5))
          bars = ax.bar(x_pos, values, width=0.5, align="center")
          value_format = "{:.1%}" # displaying values as percentage with one fractional digit
          label_bars(ax, bars, value_format)


          or for horizontal bar plots:



          fig, ax = plt.subplots((5, 5))
          horizontal_bars = ax.barh(y_pos, values, width=0.5, align="center")
          value_format = "{:.1%}" # displaying values as percentage with one fractional digit
          label_bars(ax, horizontal_bars, value_format)





          share|improve this answer

































            5














            For anyone wanting to have their label at the base of their bars just divide v by the value of the label like this:



            for i, v in enumerate(labels):
            axes.text(i-.25,
            v/labels[i]+100,
            labels[i],
            fontsize=18,
            color=label_color_list[i])


            (note: I added 100 so it wasn't absolutely at the bottom)



            To get a result like this:
            enter image description here






            share|improve this answer































              1














              For pandas people :



              ax = s.plot(kind='barh') # s is a Series (float) in [0,1]
              [ax.text(v, i, '{:.2f}%'.format(100*v)) for i, v in enumerate(s)];


              That's it.
              Alternatively, for those who prefer apply over looping with enumerate:



              it = iter(range(len(s)))
              s.apply(lambda x: ax.text(x, next(it),'{:.2f}%'.format(100*x)));


              Also, ax.patches will give you the bars that you would get with ax.bar(...). In case you want to apply the functions of @SaturnFromTitan or techniques of others.






              share|improve this answer































                0














                I needed the bar labels too, note that my y-axis is having a zoomed view using limits on y axis. The default calculations for putting the labels on top of the bar still works using height (use_global_coordinate=False in the example). But I wanted to show that the labels can be put in the bottom of the graph too in zoomed view using global coordinates in matplotlib 3.0.2. Hope it help someone.



                def autolabel(rects,data):
                """
                Attach a text label above each bar displaying its height
                """
                c = 0
                initial = 0.091
                offset = 0.205
                use_global_coordinate = True

                if use_global_coordinate:
                for i in data:
                ax.text(initial+offset*c, 0.05, str(i), horizontalalignment='center',
                verticalalignment='center', transform=ax.transAxes,fontsize=8)
                c=c+1
                else:
                for rect,i in zip(rects,data):
                height = rect.get_height()
                ax.text(rect.get_x() + rect.get_width()/2., height,str(i),ha='center', va='bottom')


                Example output






                share|improve this answer























                  Your Answer






                  StackExchange.ifUsing("editor", function () {
                  StackExchange.using("externalEditor", function () {
                  StackExchange.using("snippets", function () {
                  StackExchange.snippets.init();
                  });
                  });
                  }, "code-snippets");

                  StackExchange.ready(function() {
                  var channelOptions = {
                  tags: "".split(" "),
                  id: "1"
                  };
                  initTagRenderer("".split(" "), "".split(" "), channelOptions);

                  StackExchange.using("externalEditor", function() {
                  // Have to fire editor after snippets, if snippets enabled
                  if (StackExchange.settings.snippets.snippetsEnabled) {
                  StackExchange.using("snippets", function() {
                  createEditor();
                  });
                  }
                  else {
                  createEditor();
                  }
                  });

                  function createEditor() {
                  StackExchange.prepareEditor({
                  heartbeatType: 'answer',
                  autoActivateHeartbeat: false,
                  convertImagesToLinks: true,
                  noModals: true,
                  showLowRepImageUploadWarning: true,
                  reputationToPostImages: 10,
                  bindNavPrevention: true,
                  postfix: "",
                  imageUploader: {
                  brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                  contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                  allowUrls: true
                  },
                  onDemand: true,
                  discardSelector: ".discard-answer"
                  ,immediatelyShowMarkdownHelp:true
                  });


                  }
                  });














                  draft saved

                  draft discarded


















                  StackExchange.ready(
                  function () {
                  StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f30228069%2fhow-to-display-the-value-of-the-bar-on-each-bar-with-pyplot-barh%23new-answer', 'question_page');
                  }
                  );

                  Post as a guest















                  Required, but never shown

























                  6 Answers
                  6






                  active

                  oldest

                  votes








                  6 Answers
                  6






                  active

                  oldest

                  votes









                  active

                  oldest

                  votes






                  active

                  oldest

                  votes









                  90














                  Add:



                  for i, v in enumerate(y):
                  ax.text(v + 3, i + .25, str(v), color='blue', fontweight='bold')


                  result:



                  enter image description here



                  The y-values v are both the x-location and the string values for ax.text, and conveniently the barplot has a metric of 1 for each bar, so the enumeration i is the y-location.






                  share|improve this answer





















                  • 6





                    maybe replace use va='center', instead of "i + .25" for the horizontal alignment

                    – mathause
                    Sep 26 '17 at 16:40






                  • 4





                    plt.text(v, i, " "+str(v), color='blue', va='center', fontweight='bold')

                    – João Cartucho
                    Apr 18 '18 at 11:41


















                  90














                  Add:



                  for i, v in enumerate(y):
                  ax.text(v + 3, i + .25, str(v), color='blue', fontweight='bold')


                  result:



                  enter image description here



                  The y-values v are both the x-location and the string values for ax.text, and conveniently the barplot has a metric of 1 for each bar, so the enumeration i is the y-location.






                  share|improve this answer





















                  • 6





                    maybe replace use va='center', instead of "i + .25" for the horizontal alignment

                    – mathause
                    Sep 26 '17 at 16:40






                  • 4





                    plt.text(v, i, " "+str(v), color='blue', va='center', fontweight='bold')

                    – João Cartucho
                    Apr 18 '18 at 11:41
















                  90












                  90








                  90







                  Add:



                  for i, v in enumerate(y):
                  ax.text(v + 3, i + .25, str(v), color='blue', fontweight='bold')


                  result:



                  enter image description here



                  The y-values v are both the x-location and the string values for ax.text, and conveniently the barplot has a metric of 1 for each bar, so the enumeration i is the y-location.






                  share|improve this answer















                  Add:



                  for i, v in enumerate(y):
                  ax.text(v + 3, i + .25, str(v), color='blue', fontweight='bold')


                  result:



                  enter image description here



                  The y-values v are both the x-location and the string values for ax.text, and conveniently the barplot has a metric of 1 for each bar, so the enumeration i is the y-location.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited May 23 '17 at 18:30

























                  answered May 14 '15 at 4:07









                  cphlewiscphlewis

                  8,59723143




                  8,59723143








                  • 6





                    maybe replace use va='center', instead of "i + .25" for the horizontal alignment

                    – mathause
                    Sep 26 '17 at 16:40






                  • 4





                    plt.text(v, i, " "+str(v), color='blue', va='center', fontweight='bold')

                    – João Cartucho
                    Apr 18 '18 at 11:41
















                  • 6





                    maybe replace use va='center', instead of "i + .25" for the horizontal alignment

                    – mathause
                    Sep 26 '17 at 16:40






                  • 4





                    plt.text(v, i, " "+str(v), color='blue', va='center', fontweight='bold')

                    – João Cartucho
                    Apr 18 '18 at 11:41










                  6




                  6





                  maybe replace use va='center', instead of "i + .25" for the horizontal alignment

                  – mathause
                  Sep 26 '17 at 16:40





                  maybe replace use va='center', instead of "i + .25" for the horizontal alignment

                  – mathause
                  Sep 26 '17 at 16:40




                  4




                  4





                  plt.text(v, i, " "+str(v), color='blue', va='center', fontweight='bold')

                  – João Cartucho
                  Apr 18 '18 at 11:41







                  plt.text(v, i, " "+str(v), color='blue', va='center', fontweight='bold')

                  – João Cartucho
                  Apr 18 '18 at 11:41















                  17














                  I have noticed api example code contains an example of barchart with the value of the bar displayed on each bar:



                  """
                  ========
                  Barchart
                  ========

                  A bar plot with errorbars and height labels on individual bars
                  """
                  import numpy as np
                  import matplotlib.pyplot as plt

                  N = 5
                  men_means = (20, 35, 30, 35, 27)
                  men_std = (2, 3, 4, 1, 2)

                  ind = np.arange(N) # the x locations for the groups
                  width = 0.35 # the width of the bars

                  fig, ax = plt.subplots()
                  rects1 = ax.bar(ind, men_means, width, color='r', yerr=men_std)

                  women_means = (25, 32, 34, 20, 25)
                  women_std = (3, 5, 2, 3, 3)
                  rects2 = ax.bar(ind + width, women_means, width, color='y', yerr=women_std)

                  # add some text for labels, title and axes ticks
                  ax.set_ylabel('Scores')
                  ax.set_title('Scores by group and gender')
                  ax.set_xticks(ind + width / 2)
                  ax.set_xticklabels(('G1', 'G2', 'G3', 'G4', 'G5'))

                  ax.legend((rects1[0], rects2[0]), ('Men', 'Women'))


                  def autolabel(rects):
                  """
                  Attach a text label above each bar displaying its height
                  """
                  for rect in rects:
                  height = rect.get_height()
                  ax.text(rect.get_x() + rect.get_width()/2., 1.05*height,
                  '%d' % int(height),
                  ha='center', va='bottom')

                  autolabel(rects1)
                  autolabel(rects2)

                  plt.show()


                  output:



                  enter image description here



                  FYI What is the unit of height variable in "barh" of matplotlib? (as of now, there is no easy way to set a fixed height for each bar)






                  share|improve this answer





















                  • 1





                    It seems like get_x() rounds the number up even if the original x has decimal places. How do you get more decimal places to display?

                    – ru111
                    Jan 10 '18 at 16:16






                  • 1





                    late to the party but for anyone else using this using height+0.1 instead of 1.05*height in the autolabel function creates a consistent gap between the bar and text

                    – jnPy
                    Mar 14 '18 at 10:11


















                  17














                  I have noticed api example code contains an example of barchart with the value of the bar displayed on each bar:



                  """
                  ========
                  Barchart
                  ========

                  A bar plot with errorbars and height labels on individual bars
                  """
                  import numpy as np
                  import matplotlib.pyplot as plt

                  N = 5
                  men_means = (20, 35, 30, 35, 27)
                  men_std = (2, 3, 4, 1, 2)

                  ind = np.arange(N) # the x locations for the groups
                  width = 0.35 # the width of the bars

                  fig, ax = plt.subplots()
                  rects1 = ax.bar(ind, men_means, width, color='r', yerr=men_std)

                  women_means = (25, 32, 34, 20, 25)
                  women_std = (3, 5, 2, 3, 3)
                  rects2 = ax.bar(ind + width, women_means, width, color='y', yerr=women_std)

                  # add some text for labels, title and axes ticks
                  ax.set_ylabel('Scores')
                  ax.set_title('Scores by group and gender')
                  ax.set_xticks(ind + width / 2)
                  ax.set_xticklabels(('G1', 'G2', 'G3', 'G4', 'G5'))

                  ax.legend((rects1[0], rects2[0]), ('Men', 'Women'))


                  def autolabel(rects):
                  """
                  Attach a text label above each bar displaying its height
                  """
                  for rect in rects:
                  height = rect.get_height()
                  ax.text(rect.get_x() + rect.get_width()/2., 1.05*height,
                  '%d' % int(height),
                  ha='center', va='bottom')

                  autolabel(rects1)
                  autolabel(rects2)

                  plt.show()


                  output:



                  enter image description here



                  FYI What is the unit of height variable in "barh" of matplotlib? (as of now, there is no easy way to set a fixed height for each bar)






                  share|improve this answer





















                  • 1





                    It seems like get_x() rounds the number up even if the original x has decimal places. How do you get more decimal places to display?

                    – ru111
                    Jan 10 '18 at 16:16






                  • 1





                    late to the party but for anyone else using this using height+0.1 instead of 1.05*height in the autolabel function creates a consistent gap between the bar and text

                    – jnPy
                    Mar 14 '18 at 10:11
















                  17












                  17








                  17







                  I have noticed api example code contains an example of barchart with the value of the bar displayed on each bar:



                  """
                  ========
                  Barchart
                  ========

                  A bar plot with errorbars and height labels on individual bars
                  """
                  import numpy as np
                  import matplotlib.pyplot as plt

                  N = 5
                  men_means = (20, 35, 30, 35, 27)
                  men_std = (2, 3, 4, 1, 2)

                  ind = np.arange(N) # the x locations for the groups
                  width = 0.35 # the width of the bars

                  fig, ax = plt.subplots()
                  rects1 = ax.bar(ind, men_means, width, color='r', yerr=men_std)

                  women_means = (25, 32, 34, 20, 25)
                  women_std = (3, 5, 2, 3, 3)
                  rects2 = ax.bar(ind + width, women_means, width, color='y', yerr=women_std)

                  # add some text for labels, title and axes ticks
                  ax.set_ylabel('Scores')
                  ax.set_title('Scores by group and gender')
                  ax.set_xticks(ind + width / 2)
                  ax.set_xticklabels(('G1', 'G2', 'G3', 'G4', 'G5'))

                  ax.legend((rects1[0], rects2[0]), ('Men', 'Women'))


                  def autolabel(rects):
                  """
                  Attach a text label above each bar displaying its height
                  """
                  for rect in rects:
                  height = rect.get_height()
                  ax.text(rect.get_x() + rect.get_width()/2., 1.05*height,
                  '%d' % int(height),
                  ha='center', va='bottom')

                  autolabel(rects1)
                  autolabel(rects2)

                  plt.show()


                  output:



                  enter image description here



                  FYI What is the unit of height variable in "barh" of matplotlib? (as of now, there is no easy way to set a fixed height for each bar)






                  share|improve this answer















                  I have noticed api example code contains an example of barchart with the value of the bar displayed on each bar:



                  """
                  ========
                  Barchart
                  ========

                  A bar plot with errorbars and height labels on individual bars
                  """
                  import numpy as np
                  import matplotlib.pyplot as plt

                  N = 5
                  men_means = (20, 35, 30, 35, 27)
                  men_std = (2, 3, 4, 1, 2)

                  ind = np.arange(N) # the x locations for the groups
                  width = 0.35 # the width of the bars

                  fig, ax = plt.subplots()
                  rects1 = ax.bar(ind, men_means, width, color='r', yerr=men_std)

                  women_means = (25, 32, 34, 20, 25)
                  women_std = (3, 5, 2, 3, 3)
                  rects2 = ax.bar(ind + width, women_means, width, color='y', yerr=women_std)

                  # add some text for labels, title and axes ticks
                  ax.set_ylabel('Scores')
                  ax.set_title('Scores by group and gender')
                  ax.set_xticks(ind + width / 2)
                  ax.set_xticklabels(('G1', 'G2', 'G3', 'G4', 'G5'))

                  ax.legend((rects1[0], rects2[0]), ('Men', 'Women'))


                  def autolabel(rects):
                  """
                  Attach a text label above each bar displaying its height
                  """
                  for rect in rects:
                  height = rect.get_height()
                  ax.text(rect.get_x() + rect.get_width()/2., 1.05*height,
                  '%d' % int(height),
                  ha='center', va='bottom')

                  autolabel(rects1)
                  autolabel(rects2)

                  plt.show()


                  output:



                  enter image description here



                  FYI What is the unit of height variable in "barh" of matplotlib? (as of now, there is no easy way to set a fixed height for each bar)







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited May 23 '17 at 12:34









                  Community

                  11




                  11










                  answered Feb 28 '17 at 1:41









                  Franck DernoncourtFranck Dernoncourt

                  37.8k32196344




                  37.8k32196344








                  • 1





                    It seems like get_x() rounds the number up even if the original x has decimal places. How do you get more decimal places to display?

                    – ru111
                    Jan 10 '18 at 16:16






                  • 1





                    late to the party but for anyone else using this using height+0.1 instead of 1.05*height in the autolabel function creates a consistent gap between the bar and text

                    – jnPy
                    Mar 14 '18 at 10:11
















                  • 1





                    It seems like get_x() rounds the number up even if the original x has decimal places. How do you get more decimal places to display?

                    – ru111
                    Jan 10 '18 at 16:16






                  • 1





                    late to the party but for anyone else using this using height+0.1 instead of 1.05*height in the autolabel function creates a consistent gap between the bar and text

                    – jnPy
                    Mar 14 '18 at 10:11










                  1




                  1





                  It seems like get_x() rounds the number up even if the original x has decimal places. How do you get more decimal places to display?

                  – ru111
                  Jan 10 '18 at 16:16





                  It seems like get_x() rounds the number up even if the original x has decimal places. How do you get more decimal places to display?

                  – ru111
                  Jan 10 '18 at 16:16




                  1




                  1





                  late to the party but for anyone else using this using height+0.1 instead of 1.05*height in the autolabel function creates a consistent gap between the bar and text

                  – jnPy
                  Mar 14 '18 at 10:11







                  late to the party but for anyone else using this using height+0.1 instead of 1.05*height in the autolabel function creates a consistent gap between the bar and text

                  – jnPy
                  Mar 14 '18 at 10:11













                  7














                  I know it's an old thread, but I landed here several times via Google and think no given answer is really satisfying yet. Try using one of the following functions:



                  EDIT: As I'm getting some likes on this old thread, I wanna share an updated solution as well (basically putting my two previous functions together and automatically deciding whether it's a bar or hbar plot):



                  def label_bars(ax, bars, text_format, **kwargs):
                  """
                  Attaches a label on every bar of a regular or horizontal bar chart
                  """
                  ys = [bar.get_y() for bar in bars]
                  y_is_constant = all(y == ys[0] for y in ys) # -> regular bar chart, since all all bars start on the same y level (0)

                  if y_is_constant:
                  _label_bar(ax, bars, text_format, **kwargs)
                  else:
                  _label_barh(ax, bars, text_format, **kwargs)


                  def _label_bar(ax, bars, text_format, **kwargs):
                  """
                  Attach a text label to each bar displaying its y value
                  """
                  max_y_value = ax.get_ylim()[1]
                  inside_distance = max_y_value * 0.05
                  outside_distance = max_y_value * 0.01

                  for bar in bars:
                  text = text_format.format(bar.get_height())
                  text_x = bar.get_x() + bar.get_width() / 2

                  is_inside = bar.get_height() >= max_y_value * 0.15
                  if is_inside:
                  color = "white"
                  text_y = bar.get_height() - inside_distance
                  else:
                  color = "black"
                  text_y = bar.get_height() + outside_distance

                  ax.text(text_x, text_y, text, ha='center', va='bottom', color=color, **kwargs)


                  def _label_barh(ax, bars, text_format, **kwargs):
                  """
                  Attach a text label to each bar displaying its y value
                  Note: label always outside. otherwise it's too hard to control as numbers can be very long
                  """
                  max_x_value = ax.get_xlim()[1]
                  distance = max_x_value * 0.0025

                  for bar in bars:
                  text = text_format.format(bar.get_width())

                  text_x = bar.get_width() + distance
                  text_y = bar.get_y() + bar.get_height() / 2

                  ax.text(text_x, text_y, text, va='center', **kwargs)


                  Now you can use them for regular bar plots:



                  fig, ax = plt.subplots((5, 5))
                  bars = ax.bar(x_pos, values, width=0.5, align="center")
                  value_format = "{:.1%}" # displaying values as percentage with one fractional digit
                  label_bars(ax, bars, value_format)


                  or for horizontal bar plots:



                  fig, ax = plt.subplots((5, 5))
                  horizontal_bars = ax.barh(y_pos, values, width=0.5, align="center")
                  value_format = "{:.1%}" # displaying values as percentage with one fractional digit
                  label_bars(ax, horizontal_bars, value_format)





                  share|improve this answer






























                    7














                    I know it's an old thread, but I landed here several times via Google and think no given answer is really satisfying yet. Try using one of the following functions:



                    EDIT: As I'm getting some likes on this old thread, I wanna share an updated solution as well (basically putting my two previous functions together and automatically deciding whether it's a bar or hbar plot):



                    def label_bars(ax, bars, text_format, **kwargs):
                    """
                    Attaches a label on every bar of a regular or horizontal bar chart
                    """
                    ys = [bar.get_y() for bar in bars]
                    y_is_constant = all(y == ys[0] for y in ys) # -> regular bar chart, since all all bars start on the same y level (0)

                    if y_is_constant:
                    _label_bar(ax, bars, text_format, **kwargs)
                    else:
                    _label_barh(ax, bars, text_format, **kwargs)


                    def _label_bar(ax, bars, text_format, **kwargs):
                    """
                    Attach a text label to each bar displaying its y value
                    """
                    max_y_value = ax.get_ylim()[1]
                    inside_distance = max_y_value * 0.05
                    outside_distance = max_y_value * 0.01

                    for bar in bars:
                    text = text_format.format(bar.get_height())
                    text_x = bar.get_x() + bar.get_width() / 2

                    is_inside = bar.get_height() >= max_y_value * 0.15
                    if is_inside:
                    color = "white"
                    text_y = bar.get_height() - inside_distance
                    else:
                    color = "black"
                    text_y = bar.get_height() + outside_distance

                    ax.text(text_x, text_y, text, ha='center', va='bottom', color=color, **kwargs)


                    def _label_barh(ax, bars, text_format, **kwargs):
                    """
                    Attach a text label to each bar displaying its y value
                    Note: label always outside. otherwise it's too hard to control as numbers can be very long
                    """
                    max_x_value = ax.get_xlim()[1]
                    distance = max_x_value * 0.0025

                    for bar in bars:
                    text = text_format.format(bar.get_width())

                    text_x = bar.get_width() + distance
                    text_y = bar.get_y() + bar.get_height() / 2

                    ax.text(text_x, text_y, text, va='center', **kwargs)


                    Now you can use them for regular bar plots:



                    fig, ax = plt.subplots((5, 5))
                    bars = ax.bar(x_pos, values, width=0.5, align="center")
                    value_format = "{:.1%}" # displaying values as percentage with one fractional digit
                    label_bars(ax, bars, value_format)


                    or for horizontal bar plots:



                    fig, ax = plt.subplots((5, 5))
                    horizontal_bars = ax.barh(y_pos, values, width=0.5, align="center")
                    value_format = "{:.1%}" # displaying values as percentage with one fractional digit
                    label_bars(ax, horizontal_bars, value_format)





                    share|improve this answer




























                      7












                      7








                      7







                      I know it's an old thread, but I landed here several times via Google and think no given answer is really satisfying yet. Try using one of the following functions:



                      EDIT: As I'm getting some likes on this old thread, I wanna share an updated solution as well (basically putting my two previous functions together and automatically deciding whether it's a bar or hbar plot):



                      def label_bars(ax, bars, text_format, **kwargs):
                      """
                      Attaches a label on every bar of a regular or horizontal bar chart
                      """
                      ys = [bar.get_y() for bar in bars]
                      y_is_constant = all(y == ys[0] for y in ys) # -> regular bar chart, since all all bars start on the same y level (0)

                      if y_is_constant:
                      _label_bar(ax, bars, text_format, **kwargs)
                      else:
                      _label_barh(ax, bars, text_format, **kwargs)


                      def _label_bar(ax, bars, text_format, **kwargs):
                      """
                      Attach a text label to each bar displaying its y value
                      """
                      max_y_value = ax.get_ylim()[1]
                      inside_distance = max_y_value * 0.05
                      outside_distance = max_y_value * 0.01

                      for bar in bars:
                      text = text_format.format(bar.get_height())
                      text_x = bar.get_x() + bar.get_width() / 2

                      is_inside = bar.get_height() >= max_y_value * 0.15
                      if is_inside:
                      color = "white"
                      text_y = bar.get_height() - inside_distance
                      else:
                      color = "black"
                      text_y = bar.get_height() + outside_distance

                      ax.text(text_x, text_y, text, ha='center', va='bottom', color=color, **kwargs)


                      def _label_barh(ax, bars, text_format, **kwargs):
                      """
                      Attach a text label to each bar displaying its y value
                      Note: label always outside. otherwise it's too hard to control as numbers can be very long
                      """
                      max_x_value = ax.get_xlim()[1]
                      distance = max_x_value * 0.0025

                      for bar in bars:
                      text = text_format.format(bar.get_width())

                      text_x = bar.get_width() + distance
                      text_y = bar.get_y() + bar.get_height() / 2

                      ax.text(text_x, text_y, text, va='center', **kwargs)


                      Now you can use them for regular bar plots:



                      fig, ax = plt.subplots((5, 5))
                      bars = ax.bar(x_pos, values, width=0.5, align="center")
                      value_format = "{:.1%}" # displaying values as percentage with one fractional digit
                      label_bars(ax, bars, value_format)


                      or for horizontal bar plots:



                      fig, ax = plt.subplots((5, 5))
                      horizontal_bars = ax.barh(y_pos, values, width=0.5, align="center")
                      value_format = "{:.1%}" # displaying values as percentage with one fractional digit
                      label_bars(ax, horizontal_bars, value_format)





                      share|improve this answer















                      I know it's an old thread, but I landed here several times via Google and think no given answer is really satisfying yet. Try using one of the following functions:



                      EDIT: As I'm getting some likes on this old thread, I wanna share an updated solution as well (basically putting my two previous functions together and automatically deciding whether it's a bar or hbar plot):



                      def label_bars(ax, bars, text_format, **kwargs):
                      """
                      Attaches a label on every bar of a regular or horizontal bar chart
                      """
                      ys = [bar.get_y() for bar in bars]
                      y_is_constant = all(y == ys[0] for y in ys) # -> regular bar chart, since all all bars start on the same y level (0)

                      if y_is_constant:
                      _label_bar(ax, bars, text_format, **kwargs)
                      else:
                      _label_barh(ax, bars, text_format, **kwargs)


                      def _label_bar(ax, bars, text_format, **kwargs):
                      """
                      Attach a text label to each bar displaying its y value
                      """
                      max_y_value = ax.get_ylim()[1]
                      inside_distance = max_y_value * 0.05
                      outside_distance = max_y_value * 0.01

                      for bar in bars:
                      text = text_format.format(bar.get_height())
                      text_x = bar.get_x() + bar.get_width() / 2

                      is_inside = bar.get_height() >= max_y_value * 0.15
                      if is_inside:
                      color = "white"
                      text_y = bar.get_height() - inside_distance
                      else:
                      color = "black"
                      text_y = bar.get_height() + outside_distance

                      ax.text(text_x, text_y, text, ha='center', va='bottom', color=color, **kwargs)


                      def _label_barh(ax, bars, text_format, **kwargs):
                      """
                      Attach a text label to each bar displaying its y value
                      Note: label always outside. otherwise it's too hard to control as numbers can be very long
                      """
                      max_x_value = ax.get_xlim()[1]
                      distance = max_x_value * 0.0025

                      for bar in bars:
                      text = text_format.format(bar.get_width())

                      text_x = bar.get_width() + distance
                      text_y = bar.get_y() + bar.get_height() / 2

                      ax.text(text_x, text_y, text, va='center', **kwargs)


                      Now you can use them for regular bar plots:



                      fig, ax = plt.subplots((5, 5))
                      bars = ax.bar(x_pos, values, width=0.5, align="center")
                      value_format = "{:.1%}" # displaying values as percentage with one fractional digit
                      label_bars(ax, bars, value_format)


                      or for horizontal bar plots:



                      fig, ax = plt.subplots((5, 5))
                      horizontal_bars = ax.barh(y_pos, values, width=0.5, align="center")
                      value_format = "{:.1%}" # displaying values as percentage with one fractional digit
                      label_bars(ax, horizontal_bars, value_format)






                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Jan 7 at 23:28

























                      answered May 15 '18 at 15:35









                      SaturnFromTitanSaturnFromTitan

                      14018




                      14018























                          5














                          For anyone wanting to have their label at the base of their bars just divide v by the value of the label like this:



                          for i, v in enumerate(labels):
                          axes.text(i-.25,
                          v/labels[i]+100,
                          labels[i],
                          fontsize=18,
                          color=label_color_list[i])


                          (note: I added 100 so it wasn't absolutely at the bottom)



                          To get a result like this:
                          enter image description here






                          share|improve this answer




























                            5














                            For anyone wanting to have their label at the base of their bars just divide v by the value of the label like this:



                            for i, v in enumerate(labels):
                            axes.text(i-.25,
                            v/labels[i]+100,
                            labels[i],
                            fontsize=18,
                            color=label_color_list[i])


                            (note: I added 100 so it wasn't absolutely at the bottom)



                            To get a result like this:
                            enter image description here






                            share|improve this answer


























                              5












                              5








                              5







                              For anyone wanting to have their label at the base of their bars just divide v by the value of the label like this:



                              for i, v in enumerate(labels):
                              axes.text(i-.25,
                              v/labels[i]+100,
                              labels[i],
                              fontsize=18,
                              color=label_color_list[i])


                              (note: I added 100 so it wasn't absolutely at the bottom)



                              To get a result like this:
                              enter image description here






                              share|improve this answer













                              For anyone wanting to have their label at the base of their bars just divide v by the value of the label like this:



                              for i, v in enumerate(labels):
                              axes.text(i-.25,
                              v/labels[i]+100,
                              labels[i],
                              fontsize=18,
                              color=label_color_list[i])


                              (note: I added 100 so it wasn't absolutely at the bottom)



                              To get a result like this:
                              enter image description here







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Nov 23 '18 at 20:48









                              SkromakSkromak

                              9317




                              9317























                                  1














                                  For pandas people :



                                  ax = s.plot(kind='barh') # s is a Series (float) in [0,1]
                                  [ax.text(v, i, '{:.2f}%'.format(100*v)) for i, v in enumerate(s)];


                                  That's it.
                                  Alternatively, for those who prefer apply over looping with enumerate:



                                  it = iter(range(len(s)))
                                  s.apply(lambda x: ax.text(x, next(it),'{:.2f}%'.format(100*x)));


                                  Also, ax.patches will give you the bars that you would get with ax.bar(...). In case you want to apply the functions of @SaturnFromTitan or techniques of others.






                                  share|improve this answer




























                                    1














                                    For pandas people :



                                    ax = s.plot(kind='barh') # s is a Series (float) in [0,1]
                                    [ax.text(v, i, '{:.2f}%'.format(100*v)) for i, v in enumerate(s)];


                                    That's it.
                                    Alternatively, for those who prefer apply over looping with enumerate:



                                    it = iter(range(len(s)))
                                    s.apply(lambda x: ax.text(x, next(it),'{:.2f}%'.format(100*x)));


                                    Also, ax.patches will give you the bars that you would get with ax.bar(...). In case you want to apply the functions of @SaturnFromTitan or techniques of others.






                                    share|improve this answer


























                                      1












                                      1








                                      1







                                      For pandas people :



                                      ax = s.plot(kind='barh') # s is a Series (float) in [0,1]
                                      [ax.text(v, i, '{:.2f}%'.format(100*v)) for i, v in enumerate(s)];


                                      That's it.
                                      Alternatively, for those who prefer apply over looping with enumerate:



                                      it = iter(range(len(s)))
                                      s.apply(lambda x: ax.text(x, next(it),'{:.2f}%'.format(100*x)));


                                      Also, ax.patches will give you the bars that you would get with ax.bar(...). In case you want to apply the functions of @SaturnFromTitan or techniques of others.






                                      share|improve this answer













                                      For pandas people :



                                      ax = s.plot(kind='barh') # s is a Series (float) in [0,1]
                                      [ax.text(v, i, '{:.2f}%'.format(100*v)) for i, v in enumerate(s)];


                                      That's it.
                                      Alternatively, for those who prefer apply over looping with enumerate:



                                      it = iter(range(len(s)))
                                      s.apply(lambda x: ax.text(x, next(it),'{:.2f}%'.format(100*x)));


                                      Also, ax.patches will give you the bars that you would get with ax.bar(...). In case you want to apply the functions of @SaturnFromTitan or techniques of others.







                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered Nov 14 '18 at 19:54









                                      tozCSStozCSS

                                      1,1681018




                                      1,1681018























                                          0














                                          I needed the bar labels too, note that my y-axis is having a zoomed view using limits on y axis. The default calculations for putting the labels on top of the bar still works using height (use_global_coordinate=False in the example). But I wanted to show that the labels can be put in the bottom of the graph too in zoomed view using global coordinates in matplotlib 3.0.2. Hope it help someone.



                                          def autolabel(rects,data):
                                          """
                                          Attach a text label above each bar displaying its height
                                          """
                                          c = 0
                                          initial = 0.091
                                          offset = 0.205
                                          use_global_coordinate = True

                                          if use_global_coordinate:
                                          for i in data:
                                          ax.text(initial+offset*c, 0.05, str(i), horizontalalignment='center',
                                          verticalalignment='center', transform=ax.transAxes,fontsize=8)
                                          c=c+1
                                          else:
                                          for rect,i in zip(rects,data):
                                          height = rect.get_height()
                                          ax.text(rect.get_x() + rect.get_width()/2., height,str(i),ha='center', va='bottom')


                                          Example output






                                          share|improve this answer




























                                            0














                                            I needed the bar labels too, note that my y-axis is having a zoomed view using limits on y axis. The default calculations for putting the labels on top of the bar still works using height (use_global_coordinate=False in the example). But I wanted to show that the labels can be put in the bottom of the graph too in zoomed view using global coordinates in matplotlib 3.0.2. Hope it help someone.



                                            def autolabel(rects,data):
                                            """
                                            Attach a text label above each bar displaying its height
                                            """
                                            c = 0
                                            initial = 0.091
                                            offset = 0.205
                                            use_global_coordinate = True

                                            if use_global_coordinate:
                                            for i in data:
                                            ax.text(initial+offset*c, 0.05, str(i), horizontalalignment='center',
                                            verticalalignment='center', transform=ax.transAxes,fontsize=8)
                                            c=c+1
                                            else:
                                            for rect,i in zip(rects,data):
                                            height = rect.get_height()
                                            ax.text(rect.get_x() + rect.get_width()/2., height,str(i),ha='center', va='bottom')


                                            Example output






                                            share|improve this answer


























                                              0












                                              0








                                              0







                                              I needed the bar labels too, note that my y-axis is having a zoomed view using limits on y axis. The default calculations for putting the labels on top of the bar still works using height (use_global_coordinate=False in the example). But I wanted to show that the labels can be put in the bottom of the graph too in zoomed view using global coordinates in matplotlib 3.0.2. Hope it help someone.



                                              def autolabel(rects,data):
                                              """
                                              Attach a text label above each bar displaying its height
                                              """
                                              c = 0
                                              initial = 0.091
                                              offset = 0.205
                                              use_global_coordinate = True

                                              if use_global_coordinate:
                                              for i in data:
                                              ax.text(initial+offset*c, 0.05, str(i), horizontalalignment='center',
                                              verticalalignment='center', transform=ax.transAxes,fontsize=8)
                                              c=c+1
                                              else:
                                              for rect,i in zip(rects,data):
                                              height = rect.get_height()
                                              ax.text(rect.get_x() + rect.get_width()/2., height,str(i),ha='center', va='bottom')


                                              Example output






                                              share|improve this answer













                                              I needed the bar labels too, note that my y-axis is having a zoomed view using limits on y axis. The default calculations for putting the labels on top of the bar still works using height (use_global_coordinate=False in the example). But I wanted to show that the labels can be put in the bottom of the graph too in zoomed view using global coordinates in matplotlib 3.0.2. Hope it help someone.



                                              def autolabel(rects,data):
                                              """
                                              Attach a text label above each bar displaying its height
                                              """
                                              c = 0
                                              initial = 0.091
                                              offset = 0.205
                                              use_global_coordinate = True

                                              if use_global_coordinate:
                                              for i in data:
                                              ax.text(initial+offset*c, 0.05, str(i), horizontalalignment='center',
                                              verticalalignment='center', transform=ax.transAxes,fontsize=8)
                                              c=c+1
                                              else:
                                              for rect,i in zip(rects,data):
                                              height = rect.get_height()
                                              ax.text(rect.get_x() + rect.get_width()/2., height,str(i),ha='center', va='bottom')


                                              Example output







                                              share|improve this answer












                                              share|improve this answer



                                              share|improve this answer










                                              answered Nov 27 '18 at 12:35









                                              HaramozHaramoz

                                              413317




                                              413317






























                                                  draft saved

                                                  draft discarded




















































                                                  Thanks for contributing an answer to Stack Overflow!


                                                  • Please be sure to answer the question. Provide details and share your research!

                                                  But avoid



                                                  • Asking for help, clarification, or responding to other answers.

                                                  • Making statements based on opinion; back them up with references or personal experience.


                                                  To learn more, see our tips on writing great answers.




                                                  draft saved


                                                  draft discarded














                                                  StackExchange.ready(
                                                  function () {
                                                  StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f30228069%2fhow-to-display-the-value-of-the-bar-on-each-bar-with-pyplot-barh%23new-answer', 'question_page');
                                                  }
                                                  );

                                                  Post as a guest















                                                  Required, but never shown





















































                                                  Required, but never shown














                                                  Required, but never shown












                                                  Required, but never shown







                                                  Required, but never shown

































                                                  Required, but never shown














                                                  Required, but never shown












                                                  Required, but never shown







                                                  Required, but never shown







                                                  Popular posts from this blog

                                                  Florida Star v. B. J. F.

                                                  Error while running script in elastic search , gateway timeout

                                                  Adding quotations to stringified JSON object values