I often have to make graphs with time series, with each point being
the start of a week. Below is the result I wish:![]() However, in order to make the secondary x axis the the month labels, I need something like 40 lines of code. My strategy consists in first drawing the rates in the normal way and using matplotlib's dateFormatter to set the week numbers. That part is easy. In order to draw the x axis below to show when the weeks occur, I draw two more lines, and makes these lines invisible. The first line has as the x points the start of each month, and the y values as the corresponding rate. The second line has as its x value the middle of each month, with the corresponding y value. Below is my code. I have to use such a graph quite often--so often, in fact, that if I don't find an easier way to make the secondary x axis, I will store the code in my own library for re-use. Does anyone know of a simpler, more elegant way? Thanks! Paul import matplotlib import matplotlib.pyplot as plt import numpy as np import matplotlib.dates from datetime import datetime from datetime import timedelta def unique_months(dates, rates): """ returns two lists, one of the first time a month occurs, the second, the rates representing that month """ y = [rates[0]] temp = dates[0] - timedelta(days=dates[0].day) months = [temp] found = [dates[0].month] counter = 0 for d in dates: month = d.month if month not in found: new_date = d - timedelta(days=d.day) months.append(new_date) y.append(rates[counter]) found.append(month) counter += 1 return (months, y) def half_months(dates, defects): """ returns two lists, one the middle of the month occurs, the second, the rates representing that month """ months, y = unique_months(dates, defects) new_months =[] new_y = [] counter = 0 for m in months: new_date = m - timedelta(days=m.day) + timedelta(days=15) if new_date <= months[-1]: new_months.append(new_date) new_y.append(y[counter]) counter += 1 return new_months, new_y dates = [datetime(2012,8,19), datetime(2012,8,26),datetime(2012, 9, 3), datetime(2012,9,10), datetime(2012,9,17), datetime(2012,9,24), datetime(2012,10,1), datetime(2012,10,8)] rates = [2,3,4,2,5,3,7,2] fig = plt.figure() fig.set_size_inches(3,3) x1, y1 = unique_months(dates, rates) ax = fig.add_subplot(1,1,1) ax.yaxis.grid(True, linestyle='-', which='major', color='lightgrey', alpha=0.5) ax.set_axisbelow(True) fig.subplots_adjust(bottom=0.2, right=0.85, wspace=.8, hspace=.8) # plot dates and rates ax.plot(dates, rates) ax.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%W')) # start with bottom axis x2, y2 = half_months(dates, rates) # add tick marks for start of month # x1 starts at first of each mont; y1 doesn't matter newax = fig.add_axes(ax.get_position()) newax.spines['bottom'].set_position(('outward', 25)) newax.patch.set_visible(False) newax.yaxis.set_visible(False) newax.plot_date(x1, y1, visible=False) newax.xaxis.set_major_locator( matplotlib.dates.MonthLocator()) newax.set_xticklabels([]) # set labels for months, inbetween tick marsk # x2 is 15th of each month axmlab = fig.add_axes(ax.get_position()) axmlab.spines['bottom'].set_position(('outward', 25)) axmlab.patch.set_visible(False) axmlab.yaxis.set_visible(False) axmlab.plot_date(x2, y2, visible=False) axmlab.xaxis.set_major_formatter( matplotlib.dates.DateFormatter('%b')) axmlab.xaxis.set_major_locator(matplotlib.dates.DayLocator(bymonthday=1)) # get rid of tick marks for this axis for i, line in enumerate(axmlab.get_xticklines() + newax.get_yticklines()): line.set_visible(False) axmlab.plot_date(x2, y2, visible=False) axmlab.xaxis.set_major_locator( matplotlib.dates.MonthLocator()) plt.xlabel('Week in Year') ax.set_ylabel('Rates') plt.savefig('temp.png', dpi=100) |
------------------------------------------------------------------------------ Don't let slow site performance ruin your business. Deploy New Relic APM Deploy New Relic app performance management and know exactly what is happening inside your Ruby, Python, PHP, Java, and .NET app Try New Relic at no cost today and get our sweet Data Nerd shirt too! http://p.sf.net/sfu/newrelic-dev2dev
_______________________________________________ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users