Matplotlib x-axis ticks date and location format

I tried to duplicate plotted graphs created using flotr2 to output PDF using matplotlib. I have to say that flotr is easier to use ... but it is aloof - im currently stuck when trying to format dates / times on the x axis to the desired format, which is hours: minutes with an interval every 2 hours if the period is on the x axis is less than one day and year-month-day format if the period is more than 1 day with an interval of one day.

I read numerous examples and tried to copy them, but the result remains the same as the hours: minutes: seconds with an interval of 1 to 3 hours, based on how long the period is. enter image description here

My code is:

colorMap = { 'speed': '#3388ff', 'fuel': '#ffaa33', 'din1': '#3bb200', 'din2': '#ff3333', 'satellites': '#bfbfff' } otherColors = ['#00A8F0','#C0D800','#CB4B4B','#4DA74D','#9440ED','#800080','#737CA1','#E4317F','#7D0541','#4EE2EC','#6698FF','#437C17','#7FE817','#FBB117'] plotMap = {} import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import matplotlib.dates as dates fig = plt.figure(figsize=(22, 5), dpi = 300, edgecolor='k') ax1 = fig.add_subplot(111) realdata = data['data'] keys = realdata.keys() if 'speed' in keys: speed_index = keys.index('speed') keys.pop(speed_index) keys.insert(0, 'speed') i = 0 for key in keys: if key not in colorMap.keys(): color = otherColors[i] otherColors.pop(i) colorMap[key] = color i += 1 label = u'%s' % realdata[keys[0]]['name'] ax1.set_ylabel(label) plotMap[keys[0]] = {} plotMap[keys[0]]['label'] = label first_dates = [ r[0] for r in realdata[keys[0]]['data']] date_range = first_dates[-1] - first_dates[0] ax1.xaxis.reset_ticks() if date_range > datetime.timedelta(days = 1): ax1.xaxis.set_major_locator(dates.WeekdayLocator(byweekday = 1, interval=1)) ax1.xaxis.set_major_formatter(dates.DateFormatter('%Y-%m-%d')) else: ax1.xaxis.set_major_locator(dates.HourLocator(byhour=range(24), interval=2)) ax1.xaxis.set_major_formatter(dates.DateFormatter('%H:%M')) ax1.xaxis.grid(True) plotMap[keys[0]]['plot'] = ax1.plot_date( dates.date2num(first_dates), [r[1] for r in realdata[keys[0]]['data']], colorMap[keys[0]], xdate=True) if len(keys) > 1: first = True for key in keys[1:]: if first: ax2 = ax1.twinx() ax2.set_ylabel(u'%s' % realdata[key]['name']) first = False plotMap[key] = {} plotMap[key]['label'] = u'%s' % realdata[key]['name'] plotMap[key]['plot'] = ax2.plot_date( dates.date2num([ r[0] for r in realdata[key]['data']]), [r[1] for r in realdata[key]['data']], colorMap[key], xdate=True) plt.legend([value['plot'] for key, value in plotMap.iteritems()], [value['label'] for key, value in plotMap.iteritems()], loc = 2) plt.savefig(path +"node.png", dpi = 300, bbox_inches='tight') 

Can someone please indicate why I am not getting the desired results, please?

Edit1:

I moved the formatting block after plotting and it seems to have gotten better results. However, they are still desirable results. If the period is less than a day, I get ticks every 2 hours (interval = 2), but I would like these ticks to be in even hours, and not in unequal hours. Is it possible?

 if date_range > datetime.timedelta(days = 1): xax.set_major_locator(dates.DayLocator(bymonthday=range(1,32), interval=1)) xax.set_major_formatter(dates.DateFormatter('%Y-%m-%d')) else: xax.set_major_locator(dates.HourLocator(byhour=range(24), interval=2)) xax.set_major_formatter(dates.DateFormatter('%H:%M')) 

Edit2: This seemed to give me what I wanted:

 if date_range > datetime.timedelta(days = 1): xax.set_major_locator(dates.DayLocator(bymonthday=range(1,32), interval=1)) xax.set_major_formatter(dates.DateFormatter('%Y-%m-%d')) else: xax.set_major_locator(dates.HourLocator(byhour=range(0,24,2))) xax.set_major_formatter(dates.DateFormatter('%H:%M')) 

Alan

+4
source share
2 answers

I achieved what I wanted:

 if date_range > datetime.timedelta(days = 1): xax.set_major_locator(dates.DayLocator(bymonthday=range(1,32), interval=1)) xax.set_major_formatter(dates.DateFormatter('%Y-%m-%d')) else: xax.set_major_locator(dates.HourLocator(byhour=range(0,24,2))) xax.set_major_formatter(dates.DateFormatter('%H:%M')) 
+7
source

You make this path more difficult for yourself than you need. matplotlib can directly refer to datetime objects. I suspect your problem is that you set up the locators and then draw, and plotting replaces your locators / formatter with default auto-sorters. Try moving this logic block relative to the locators below the build cycle.

I think this can replace a fair piece of your code:

 d = datetime.timedelta(minutes=2) now = datetime.datetime.now() times = [now + d * j for j in range(500)] ax = plt.gca() # get the current axes ax.plot(times, range(500)) xax = ax.get_xaxis() # get the x-axis adf = xax.get_major_formatter() # the the auto-formatter adf.scaled[1./24] = '%H:%M' # set the < 1d scale to H:M adf.scaled[1.0] = '%Y-%m-%d' # set the > 1d < 1m scale to Ymd adf.scaled[30.] = '%Y-%m' # set the > 1m < 1Y scale to Ym adf.scaled[365.] = '%Y' # set the > 1y scale to Y plt.draw() 

doc for AutoDateFormatter

+9
source

All Articles