# Using matplotlib to plot a distribution of time occurrences. I would like the x axis to have hours (12:00 PM) rather than integers (12)

Here's my plot, which is generated using the following code:

``````bins = np.linspace(0,24,25)
plt.hist(hours,bins, edgecolor='black', linewidth = 1.2, color = 'red')
``````

I would like the x axis to show 24 entries, from 12:00AM to 11:00 PM ideally rotated left 90 degrees.

I see two paths: convert the actual data to time values so the histogram reads in time values or simply add a custom x axis with 12:00AM, 1:00 AM, etc. What's the easiest / cleanest approach here? I'm not familiar with how to do either. For reference, "hours" is a int64 array.

Here's a working example:

``````import numpy as np
import matplotlib.pyplot as plt

bins = np.arange(0,25)
hours = np.random.rand(50)*25

fig, ax = plt.subplots()

labels = []
for i in bins:
if i<12:
labels.append("{}:00AM".format(i))
elif i == 12:
labels.append("12:00PM")
else:
labels.append("{}:00PM".format(i-12))

ax.hist(hours, bins)
ax.set_xticks(bins + 0.5) # 0.5 is half of the "1" auto width
ax.set_xticklabels(labels, rotation='vertical')
fig.subplots_adjust(bottom = 0.2) # makes space for the vertical
#labels.
plt.show()
``````

which gives: I've changed the linspace to arange as it returns integers

To get a nice time format on the xaxis, the idea could be to calculate the histogram in terms of numbers which can be interpreted as datetimes.
In case you only have times, you would not mind too much about the actual date. So dividing the data by 24 gives fraction of a day. Since matplotlib interpretes numbers as days since 0001-01-01 UTC, plus 1, one then needs to add some whole number >=2 not to run into trouble with negative dates.

Then usual `matplotlib.dates` locators and formatters can be used to get nice ticklabels. `"%I:%M %p"` would give the time representation in hours by 12 with am/pm appendix.

``````import numpy as np; np.random.seed(3)
import matplotlib.pyplot as plt
import matplotlib.dates

data = np.random.normal(12,7, size=200)
data = data[(data >=0) & (data <24)]

f = lambda x: 2+x/24.
bins=np.arange(25)
plt.hist(f(data), bins=f(bins))

plt.gca().xaxis.set_major_locator(matplotlib.dates.HourLocator())
plt.gca().xaxis.set_major_formatter(matplotlib.dates.DateFormatter("%I:%M %p"))
plt.setp(plt.gca().get_xticklabels(),rotation=90)
plt.tight_layout()
plt.show()
``````

(This would hence be the histogram of datetimes of the 2nd of january 0001.)