theDreamer911
theDreamer911

Reputation: 123

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

Upvotes: 2

Views: 6626

Answers (2)

Henry Ecker
Henry Ecker

Reputation: 35636

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

Upvotes: 4

Cameron Riddell
Cameron Riddell

Reputation: 13407

imo that tutorial is making plotting more confusing than it needs to be. You seldom need to fetch coordinates from the artists on the plot. Just use your data directly:

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_values = np.arange(len(years))
fig, ax = plt.subplots(figsize=(12, 4))

ax.bar(x_values, population, width=.35, label='population')
for x, y in zip(x_values, population):    
    ax.annotate(
        str(y),        # label is our y-value as a string
        xy=(x, y),
        xytext=(0, 3), # 3 points vertical offset
        textcoords="offset points",
        ha='center', 
        va='bottom'
    )
    
    
ax.set_xticks(x_values)
ax.set_xticklabels(years)
ax.set_ylim(0, 1200)

plt.show()

enter image description here

Upvotes: 1

Related Questions