Search code examples
pythonmatplotlibbar-chartxticks

How to center the xticks from a bar chart


I was following this tutorial to add value in my bar chart link

The code that shown in the blog written like this

from matplotlib import pyplot as plt
import numpy as np

years = [1901, 1911, 1921, 1931, 1941, 1951, 1961, 1971, 1981, 1991, 2001, 2011]
population = [237.4, 238.4, 252.09, 251.31, 278.98, 318.66, 361.09, 439.23, 548.16, 683.33, 846.42, 1028.74]

x = np.arange(len(years)) # the label locations
width = 0.35 # the width of the bars

fig, ax = plt.subplots()

ax.set_ylabel('Population(in million)')
ax.set_title('Years')
ax.set_xticks(x)
ax.set_xticklabels(years)

pps = ax.bar(x - width/2, population, width, label='population')
for p in pps:
   height = p.get_height()
   ax.annotate('{}'.format(height),
      xy=(p.get_x() + p.get_width() / 2, height),
      xytext=(0, 3), # 3 points vertical offset
      textcoords="offset points",
      ha='center', va='bottom')

plt.show()

So, the output become like this

enter image description here

But, I just realized that the xticks from the bar chart is not centered

enter image description here

My question - Is anybody know how to center the xticks?

I was trying to find the solution, but not found yet


Solution

  • In matplotlib 3.4.0 or newer bar_label can be used instead of annotate:

    import numpy as np
    from matplotlib import pyplot as plt
    
    years = [1901, 1911, 1921, 1931, 1941, 1951, 1961, 1971, 1981, 1991, 2001, 2011]
    population = [237.4, 238.4, 252.09, 251.31, 278.98, 318.66, 361.09, 439.23,
                  548.16, 683.33, 846.42, 1028.74]
    
    # Create Tick Locations
    x = np.arange(len(years))
    # Plotting
    fig, ax = plt.subplots(figsize=(10, 6))
    # Do not offset the values of x to center labels (default)
    ax.bar(x, population, width=.35, label='population')
    
    # Labels, ticks, etc.
    ax.set_ylabel('Population(in million)')
    ax.set_title('Years')
    ax.set_xticks(x)
    ax.set_xticklabels(years)
    
    # Add Bar Labels
    for c in ax.containers:
        ax.bar_label(c)
    
    plt.show()
    

    plot