Annotate Bars in Barplot with Matplotlib in Python?

Annotate Bars in Barplot with Matplotlib in Python?

Annotation means adding notes to a diagram stating what values do it represents. It often gets tiresome for the user to read the values from the graph when the graph is scaled down in size or is overly populated. 

In this article, we will discuss how to annotate the bar plots created in python and Matplotlib library.

Following are examples of annotated and non-annotated bar plots:

Let's first plot simple graphs from a Pandas dataframe.

# Importing libraries for dataframe creation
# and graph plotting
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# Creating our own dataframe
data={"Name": ["Alex","Bob","Clarein","Dexter"],

# Now convert this dictionary type data into a pandas dataframe
# specifying what are the column names
df=pd.DataFrame(data, columns = ['Name','Marks'])

Let's now start plotting the dataframe using the seaborn library.

# Defining the plotsize
plt.figure(figsize=(8, 6))
# Defining the x-axis, the y-axis and the data
# from where the values are to be taken
# Setting the x-acis label and its size
plt.xlabel("Students", size=15)
# Setting the y-axis label and its size
plt.ylabel("Marks Secured", size=15)
# Finallt plotting the graph

We get the following results. But it is not quite visible that what are the actual values in the bar plots. This condition can also arise when the values of neighboring plots are quite close to each other.

Adding the annotations:

Our strategy here will be to iterate all over the bars and put a text over all of them that will point out the values of that particular bar.

Here we will use the Matplpotlib's function called annotate(). We can find various uses of this function in various scenarios, currently, we will be just showing the value of the respective bars at their top.

Our steps will be:

  • Iterate over the bars
  • Get the x-axis position(x) and the width(w) of the bar this will help us to get the x coordinate of the text i.e. get_x()+get_width()/2.
  • The y-coordinate(y) of the text can be found using the height of the bar i.e. get_height()
  • So we have the coordinates of the annotation value i.e. (get_x()+get_width()/2, get_height())
  • But this will print the annotation exactly on the boundary of the bar so to get a more pleasing annotated plot we use the parameter xyplot=(0, 8). Here 8 denotes the pixels that will be left from the top of the bar. Therefore to go below the barline we can use xy=(0,-8).

So we execute the following code to get the annotated graph:

# Defining the plot size
plt.figure(figsize=(8, 8))
# Defining the values for x-axis, y-axis
# and from which datafarme the values are to be picked
# Iterrating over the bars one-by-one
for bar in plots.patches:
# Using Matplotlib's annotate function and passing the coordinates where the annotation shall be done
# x-coordinate: bar.get_x() + bar.get_width() / 2
# y-coordinate: bar.get_height()
# free space to be left to make graph pleasing: (0, 8)
# ha and va stand for the horizontal and vertical alignment
plots.annotate(format(bar.get_height(), '.2f'), (bar.get_x() + bar.get_width() / 2, bar.get_height()), ha = 'center', va = 'center',
size=15,xytext = (0, 8),
textcoords = 'offset points')
# Setting the label for x-axis
plt.xlabel("Students", size=14)
# Setting the label for y-axis
plt.ylabel("Marks Secured", size=14)
# Setting the title for the graph
plt.title("This is an annotated barplot")
# Fianlly showing the plot

On executing the above program we get the following output:

Bar plot annotated with the bar values