lo tolmencre
lo tolmencre

Reputation: 3934

Histogram Bars not Centred over xticks in pyplot.hist

I guess I just didn't use the right keywords, because this probably has been asked before, but I didn't find a solution. Anyway, I have a problem where the the bars of a histogram do not line up with the xticks. I want the bars to be centred over the xticks they correspond to, but they get placed between ticks to fill the space in-between evenly.

enter image description here

import matplotlib.pyplot as plt  

data = [1, 1, 1, 1.5, 2, 4, 4, 4, 4, 4.5, 5, 6, 6.5, 7, 9,9, 9.5]

bins = [x+n for n in range(1, 10) for x in [0.0, 0.5]]+[10.0]

plt.hist(data, bins, rwidth = .3)
plt.xticks(bins)
plt.show()

Upvotes: 2

Views: 8233

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339280

Note that what you are plotting here is not a histogram. A histogram would be

import matplotlib.pyplot as plt  

data = [1, 1, 1, 1.5, 2, 4, 4, 4, 4, 4.5, 5, 6, 6.5, 7, 9,9, 9.5]

bins = [x+n for n in range(1, 10) for x in [0.0, 0.5]]+[10.0]

plt.hist(data, bins, edgecolor="k", alpha=1)
plt.xticks(bins)
plt.show()

enter image description here

Here, the bars range between the bins as expected. E.g. you have 3 values in the interval 1 <= x < 1.5.

Conceptually what you want to do here is get a bar plot of the counts of data values. This would not require any bins at all and could be done as follows:

import numpy as np
import matplotlib.pyplot as plt  

data = [1, 1, 1, 1.5, 2, 4, 4, 4, 4, 4.5, 5, 6, 6.5, 7, 9,9, 9.5]

u, inv = np.unique(data, return_inverse=True)
counts = np.bincount(inv)

plt.bar(u, counts, width=0.3)

plt.xticks(np.arange(1,10,0.5))
plt.show()

enter image description here

Of course you can "misuse" a histogram plot to get a similar result. This would require to move the center of the bar to the left bin edge, plt.hist(.., align="left").

import matplotlib.pyplot as plt  

data = [1, 1, 1, 1.5, 2, 4, 4, 4, 4, 4.5, 5, 6, 6.5, 7, 9,9, 9.5]

bins = [x+n for n in range(1, 10) for x in [0.0, 0.5]]+[10.0]

plt.hist(data, bins, align="left", rwidth = .6)
plt.xticks(bins)
plt.show()

This results in the same plot as above.

Upvotes: 6

Related Questions