1

I would like to add a custom label above certain bars within this chart. How would I add labels to only bar 4 and bar 8 in this example:

import pandas as pd
import matplotlib.pyplot as plt

# Bring some raw data.
frequencies = [6, 16, 75, 160, 244, 260, 145, 73, 16, 4, 1]
# In my original code I create a series and run on that, 
# so for consistency I create a series from the list.
freq_series = pd.Series.from_array(frequencies)

x_labels = [108300.0, 110540.0, 112780.0, 115020.0, 117260.0, 119500.0,
            121740.0, 123980.0, 126220.0, 128460.0, 130700.0]

# Plot the figure.
plt.figure(figsize=(12, 8))
ax = freq_series.plot(kind='bar')
ax.set_title('Amount Frequency')
ax.set_xlabel('Amount ($)')
ax.set_ylabel('Frequency')
ax.set_xticklabels(x_labels)

rects = ax.patches

# Make some labels.
labels = ["label%d" % i for i in xrange(len(rects))]

for rect, label in zip(rects, labels):
    height = rect.get_height()
    ax.text(rect.get_x() + rect.get_width() / 2, height + 5, label,
            ha='center', va='bottom')

With this code I get a label above each bar. But I only want labels (with value 34 and 55, for example) above the fourth and eighth bar.

What is the best way to accomplish this?

Here is where I found this example: Adding value labels on a matplotlib bar chart

Jeff Coldplume
  • 343
  • 1
  • 13

1 Answers1

3

That code was written for Python 2 and a much earlier version of pandas; I have touched it up a little to work for Python 3.

There are other ways to do this, but without changing the structure of the code too much, what you can do is specify indices of the bar labels you want to plot, shown below as which, and plot them only if they correspond:

import pandas as pd
import matplotlib.pyplot as plt

# Bring some raw data.
frequencies = [6, 16, 75, 160, 244, 260, 145, 73, 16, 4, 1]
# In my original code I create a series and run on that, 
# so for consistency I create a series from the list.
freq_series = pd.Series(frequencies)

x_labels = [108300.0, 110540.0, 112780.0, 115020.0, 117260.0, 119500.0,
            121740.0, 123980.0, 126220.0, 128460.0, 130700.0]

# Plot the figure.
fig, ax = plt.subplots(figsize=(12, 8))
freq_series.plot(kind='bar', ax=ax)
ax.set_title('Amount Frequency')
ax.set_xlabel('Amount ($)')
ax.set_ylabel('Frequency')
ax.set_xticklabels(x_labels)

rects = ax.patches

# Make some labels.
labels = [f'label{i}' for i in range(len(rects))]

which = [3, 7]

for index, rect in enumerate(rects):
    if index in which:
        height = rect.get_height()
        ax.text(rect.get_x() + rect.get_width() / 2, height + 5, height,
                ha='center', va='bottom')

enter image description here

gmds
  • 19,325
  • 4
  • 32
  • 58
  • 1
    Oh ok, I was trying to write a for loop that went through and found when the fourth element was true (i.e. num %4==0) but I was only able to get the values on the first three bars. This is much more intuitive to me, thank you for the help! – Jeff Coldplume Apr 15 '19 at 04:43