Continuous timeline with dates along the x axis

I received the data for several months, but between several months is not enough. It looks rather strange if I draw the entire data set in one plot (a lot of free space between them). I wrote a small script example to show how it works (based on: Python / Matplotlib - is there a way to make the dashed axis? )

Problem: I cannot force the x axis to use the same date formatting! Either the ax or ax2 is correct, but never both of them. Do you have any ideas?

import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt import datetime def getDates(startdate, enddate): days = (enddate + datetime.timedelta(days=1) - startdate).days dates = [ startdate + datetime.timedelta(days=x) for x in range(0,days) ] return dates dates1 = getDates(datetime.datetime(2013,1,1), datetime.datetime(2013,1,31)) dates2 = getDates(datetime.datetime(2013,3,1), datetime.datetime(2013,3,31)) dates = dates1+dates2 data = np.arange(len(dates)) Locator = mpl.dates.DayLocator(interval=5) Formatter = mpl.dates.DateFormatter('%d-%m-%y') fig,(ax,ax2) = plt.subplots(1,2,sharey=True) fig.subplots_adjust(wspace=0.05) fig.set_size_inches(10,3) ax.plot(dates, data) ax2.plot(dates, data) ax.legend(loc=1) ax.set_ylim( 0, 61 ) ax.set_xlim( datetime.datetime(2013,1,1), datetime.datetime(2013,1,31) ) ax2.set_xlim( datetime.datetime(2013,3,1), datetime.datetime(2013,3,31) ) labels = ax.get_xticklabels() for label in labels: label.set_rotation(30) labels = ax2.get_xticklabels() for label in labels: label.set_rotation(30) ax.spines['right'].set_visible(False) ax2.spines['left'].set_visible(False) ax.tick_params(right='off') ax2.tick_params(left='off') ax2.yaxis.tick_right() ax.xaxis.set_major_locator(Locator) ax.xaxis.set_major_formatter(Formatter) ax2.xaxis.set_major_locator(Locator) ax2.xaxis.set_major_formatter(Formatter) plt.savefig("test.png", bbox_inches='tight') 

Result: Result

+5
python numpy matplotlib
Sep 24 '13 at 13:04 on
source share
1 answer

You have found some interesting information about the internal elements of matplotlib . The locator object that you pass to set_major_locator is the object used by the axes to determine where to put it, and the axes tags used the same locator object. As part of a draw, the locator generates a list of where the ticks should be based on the boundaries of the axes, which, when done for the second axes, means that the ticks are not visible in the first axes. You just need to pass the individual objects (separate instances) of the locator made here using copy .

 import datetime import copy def getDates(startdate, enddate): days = (enddate + datetime.timedelta(days=1) - startdate).days dates = [ startdate + datetime.timedelta(days=x) for x in range(0, days) ] return dates dates1 = getDates(datetime.datetime(2013, 1, 1), datetime.datetime(2013, 1, 31)) dates2 = getDates(datetime.datetime(2013, 3, 1), datetime.datetime(2013, 3, 31)) dates = dates1+dates2 data = np.arange(len(dates)) Locator = mpl.dates.DayLocator(interval=5) Formatter = mpl.dates.DateFormatter('%d-%m-%y') fig, (ax, ax2) = plt.subplots(1, 2, sharey=True, tight_layout=True) fig.subplots_adjust(wspace=0.05) fig.set_size_inches(10, 3, forward=True) ax.plot(dates, data) ax2.plot(dates, data) ax.legend(loc=1) ax.set_ylim(0, 61) ax.set_xlim(datetime.datetime(2013, 1, 1), datetime.datetime(2013, 1, 31)) ax2.set_xlim(datetime.datetime(2013, 3, 1), datetime.datetime(2013, 3, 31)) labels = ax.get_xticklabels() for label in labels: label.set_rotation(30) labels = ax2.get_xticklabels() for label in labels: label.set_rotation(30) ax.spines['right'].set_visible(False) ax2.spines['left'].set_visible(False) ax.tick_params(right='off') ax2.tick_params(left='off') ax2.yaxis.tick_right() # note the copy here ax.xaxis.set_major_locator(copy.copy(Locator)) ax.xaxis.set_major_formatter(copy.copy(Formatter)) ax2.xaxis.set_major_locator(copy.copy(Locator)) ax2.xaxis.set_major_formatter(copy.copy(Formatter)) 

enter image description here

+5
Sep 24 '13 at 13:29
source share



All Articles