2013-09-24 13 views
5

Mam dane przez kilka miesięcy, ale w międzyczasie brakuje kilku miesięcy. Wydaje się to dość dziwne, jeśli wykreślę cały zbiór danych w jednym wykresie (wiele pustych przestrzeni pomiędzy). Napisałem mały skrypt przykładowy, aby pokazać, jak to działa (na podstawie: Python/Matplotlib - Is there a way to make a discontinuous axis?)Nieciągła działka czasowa z datami na osi X

Problem: Nie mogę uzyskać osi X używać tego samego formatu daty! Albo topór, albo topór2 jest poprawny, ale nigdy oba. Masz jakiś pomysł?

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

Wynik: Result

+3

Proszę nie zawali 'for' pętle do jednej linii, to jest zły styl i może zmylić czytelników (jak ja) – tacaswell

Odpowiedz

5

Znalazłeś ciekawy szczegółów na temat budowy wewnętrznej matplotlib. Obiekt lokalizatora, który przekazujesz do obiektu używanego przez osie, aby dowiedzieć się, gdzie umieścić tiknięcia, użył tego samego obiektu lokalizatora. W ramach losowania lokalizator generuje listę miejsc, w których kleszcze powinny opierać się na granicach osi, które, gdy zostanie zrobione dla drugiej osi, oznaczają, że w pierwszych osiach nie są widoczne żadne znaczniki. Musisz tylko przekazać osobne (oddzielne instancje) obiekty lokalizatora, wykonane tutaj z 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, dziękuję! – HyperCube