I don't know what you have for data, but here's an mock example of how to make a histogram with months\days on x axis.
I can only assume that you start with a list of datetime objects, but I can't figure out what nc
is (is that matplotlib.date module?) or what kind of times can exactly be found in the unique times. So generally this is the approach.
These modules you will need and use.
import matplotlib as mpl
import matplotlib.pyplot as plt
import datetime
These are the mock dates I've used. for this example. There are only 11 months on there, so mostly all bins will be 1 in the end.
for i in range(1, 12):
dates.append(datetime.datetime(i*5+1960, i, i, i, i, i))
[datetime.datetime(1965, 1, 1, 1, 1, 1), datetime.datetime(1970, 2, 2, 2, 2, 2), datetime.datetime(1975, 3, 3, 3, 3, 3), datetime.datetime(1980, 4, 4, 4, 4, 4), datetime.datetime(1985, 5, 5, 5, 5, 5), datetime.datetime(1990, 6, 6, 6, 6, 6), datetime.datetime(1995, 7, 7, 7, 7, 7), datetime.datetime(2000, 8, 8, 8, 8, 8), datetime.datetime(2005, 9, 9, 9, 9, 9), datetime.datetime(2010, 10, 10, 10, 10, 10), datetime.datetime(2015, 11, 11, 11, 11, 11)]
If like in the above example you're dealing with different years, you're going to have to "stack" them yourself. Otherwise the date2num
function I'll use later will produce wildly different numbers. To "stack" them means convert them as if they all happened in the same year.
stacked_dates = []
for date in dates:
stacked_dates.append( date.replace(year=2000) )
>>> stacked_dates
[datetime.datetime(2000, 1, 1, 1, 1, 1), datetime.datetime(2000, 2, 2, 2, 2, 2), datetime.datetime(2000, 3, 3, 3, 3, 3), datetime.datetime(2000, 4, 4, 4, 4, 4), datetime.datetime(2000, 5, 5, 5, 5, 5), datetime.datetime(2000, 6, 6, 6, 6, 6), datetime.datetime(2000, 7, 7, 7, 7, 7), datetime.datetime(2000, 8, 8, 8, 8, 8), datetime.datetime(2000, 9, 9, 9, 9, 9), datetime.datetime(2000, 10, 10, 10, 10, 10), datetime.datetime(2000, 11, 11, 11, 11, 11)]
Ok. Now we can use the date2num
function to get something mpl
actually understands. (Btw, if you want to plot just this data you can with plt.plot_dates
function, that function understands datetime objects)
stacked_dates = mpl.dates.date2num(stacked_dates)
>>> stacked_dates
array([ 730120.04237269, 730152.08474537, 730182.12711806,
730214.16949074, 730245.21186343, 730277.25423611,
730308.2966088 , 730340.33898148, 730372.38135417,
730403.42372685, 730435.46609954])
Ok now for the plotting itself. mpl
can understand these numbers, but it will not automatically assume they are dates. It will treat them as normal numbers. That's why we've got to tell the x axis that they're actually dates. Do that with major_axis_formatter
and set_major_locator
fig = plt.figure()
ax = plt.subplot(111)
ax.xaxis.set_major_locator(mpl.dates.MonthLocator())
format = mpl.dates.DateFormatter('%m/%d') #explore other options of display
ax.xaxis.set_major_formatter(format)
ax.hist(stacked_dates) #plot the damned thing
plt.xticks(rotation='vertical') #avoid overlapping numbers
#make sure you do this AFTER .hist function
plt.show()
This code produces following graph:

Do note that there's a chance you won't be able to see dates on your original graph because they'll run off screen (formats like these can be long, and don't fit on the graph). In that case press the "configure subplots" button and adjust value for "bottom". In the script you can do that by plt.subplots_adjust(bottom=.3)
or some other value.
You should also take care to specify that there are 12 bins in ax.hist(stacked_dates, bins=12)
because default is 10, and will look funky like my graph.
Also there's a simpler, albeit less modifiable/personofiable etc... possibility by using a bar plot, instead of a histogram. Read about it HERE But it really depends on what kind of information you have. If it's a lot of dates, it's probably easier to let the hist
function calculate bin heights than doing it by yourself.
If it's some other info, it's worthwhile to consider using a bar plot.
Complete script would be something like:
import matplotlib as mpl
import matplotlib.pyplot as plt
import datetime
stacked_dates = []
for date in dates:
stacked_dates.append( date.replace(year=2000) )
stacked_dates = mpl.dates.date2num(stacked_dates)
fig = plt.figure()
ax = plt.subplot(111)
ax.xaxis.set_major_locator(mpl.dates.MonthLocator())
format = mpl.dates.DateFormatter('%m/%d')
ax.xaxis.set_major_formatter(format)
ax.hist(stacked_dates)
plt.xticks(rotation='vertical')
plt.show()