3

I want to add frequency labels to the histogram generated using plt.hist.

Here is the data :

np.random.seed(30)
d = np.random.randint(1, 101, size = 25)
print(sorted(d))

I looked up other questions on stackoverflow like : Adding value labels on a matplotlib bar chart and their answers, but apparantly, the objects returnded by plt.plot(kind='bar') are different than than those returned by plt.hist, and I got errors while using the 'get_height' or 'get width' functions, as suggested in some of the answers for bar plot.

Similarly, couldn't find the solution by going through the matplotlib documentation on histograms. got this error

  • What is the question? Welcome to SO. This isn't a discussion forum or tutorial. Please take the [tour] and take the time to read [ask] and the other links found on that page. – wwii Aug 01 '20 at 00:29
  • This link is for a 'bar' chart and didn't work for 'histogram': [Adding value labels on a matplotlib bar chart](https://stackoverflow.com/questions/28931224/adding-value-labels-on-a-matplotlib-bar-chart) –  Aug 01 '20 at 00:57

1 Answers1

6

Here is how I managed it. If anyone has some suggestions to improve my answer, (specifically the for loop and using n=0, n=n+1, I think there must be a better way to write the for loop without having to use n in this manner), I'd welcome it.

# import base packages
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# generate data
np.random.seed(30)
d = np.random.randint(1, 101, size = 25)
print(sorted(d))

enter image description here

# generate histogram

# a histogram returns 3 objects : n (i.e. frequncies), bins, patches
freq, bins, patches = plt.hist(d, edgecolor='white', label='d', bins=range(1,101,10))

# x coordinate for labels
bin_centers = np.diff(bins)*0.5 + bins[:-1]

n = 0
for fr, x, patch in zip(freq, bin_centers, patches):
  height = int(freq[n])
  plt.annotate("{}".format(height),
               xy = (x, height),             # top left corner of the histogram bar
               xytext = (0,0.2),             # offsetting label position above its bar
               textcoords = "offset points", # Offset (in points) from the *xy* value
               ha = 'center', va = 'bottom'
               )
  n = n+1

plt.legend()
plt.show;

enter image description here

  • 1
    Use `enumerate()` in the loop like so: `for n, (fr, x, patch) in enumerate(zip(freq, bin_centers, patches)):` and get rid of `n = 0` and `n = n +1`. – Basil Aug 01 '20 at 01:27
  • Thanks. It worked. Are there any advantages in using enumerate instead of what I used? –  Aug 01 '20 at 04:02
  • It just provides a convenient automatically incremented loop counter in addition to the iterable's items. It's not always absolutely necessary, but helps to simplify the syntax in cases like this. – Basil Aug 01 '20 at 04:41