2013-09-24 7 views
5

Ho dati per diversi mesi, ma mancano alcuni mesi. Questo sembra abbastanza strano se traccio l'intero set di dati in un grafico (un sacco di spazio vuoto in mezzo). Ho scritto il piccolo script di esempio per mostrare come funziona (basato su: Python/Matplotlib - Is there a way to make a discontinuous axis?)Timeseries discontinua trama con date sull'asse x

Il problema: non riesco a ottenere l'asse x utilizzare la stessa formattazione di data! O l'ascia o l'ascia 2 è corretta, ma mai entrambe. Hai qualche idea?

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') 

Risultato: Result

+3

Si prega di non crollare 'for' loop per una linea, è cattivo stile e può confondere i tuoi lettori (come me) – tacaswell

risposta

5

Hai trovato un dettaglio interessante circa la struttura interna di matplotlib. L'oggetto localizzatore che si passa a set_major_locatorè l'oggetto utilizzato dagli assi per capire dove collocare i segni di spunta entrambi axes utilizzavano lo stesso oggetto locatore. Come parte del sorteggio, il localizzatore genera un elenco di dove le zecche dovrebbero basarsi sui limiti degli assi che, quando viene eseguito per i secondi assi, significa che non sono visibili zecche nei primi assi. Hai solo bisogno di passare in oggetti distinti (distinti istanzianti) locator, fatto qui con 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

+0

Works, grazie! – HyperCube

Problemi correlati