2017-08-15 79 views
6

Plamkuję dane z pliku csv z wartościami na osi Y i datą na osi X. Mój zestaw danych zawiera tylko dane z czerwca, lipca i sierpnia w ciągu 15 lat. Jednak, gdy próbuję wykreślić te dane, wszystkie dane na osi X są drukowane w całym okresie, a nie tylko w miesiącach letnich w pliku csv. Poniżej jest to, co moja działka obecnie wyglądaJak nanieść dane równomiernie wzdłuż osi X?

enter image description here

Oto kod, który produkowany ten obraz:

infile = r'data.csv' 

with open(infile,'r') as f: 
    data = list(reader(f)) 

date = [parser.parse(i[10]) for i in data[1:]] #3 
date = mdates.date2num(date) 
date = mdates.num2date(date) 

value = [i[16] for i in data[1:]] 

fig = plt.figure() 
plt.plot(date, value, '.r') 

Zasadniczo, staram się dostać tę samą działkę bez wszystkich przestrzeniach pomiędzy dane z każdego roku.

Oto, jak wygląda snajper moich danych (z lat 2002-2016). Kolumna daty (kolumna L) składa się z ciągów. Te dane pochodzą z pliku CSV wyświetlanego w Excelu. enter image description here

+1

Można ustawić 'xticks' ale myślę, że fabuła stanie się bezsensowne? Mielibyśmy masę punktów na całym wykresie i nierównomierne skoki wszędzie wzdłuż osi X. Wizualnie to byłoby dla mnie bez znaczenia w porównaniu z twoim aktualnym wykresem. – roganjosh

+1

Z * przepraszam, a twoje pytanie stwierdza "równomiernie wzdłuż osi x", co jest dokładnie tym, co już masz. Wydaje się, że twoim pragnieniem jest posiadanie _nejwymiarowej osi X i jeśli nie planujesz zrobić czegoś więcej w tym spisku, to byłby to jeden z najbardziej mylących wykresów, jakie kiedykolwiek widziałem. Czy na pewno tego chcesz? – roganjosh

+0

Widzę, gdzie leży twoje zamieszanie. Wszystkie moje dane pochodzą z tych samych trzech miesięcy każdego roku, więc najlepiej byłoby, gdyby oś X brzmiała bardziej: 06/2013, 07/2013, 08/2013, 06/2014, 07/2014, 08 /2014,...etc. Trudno jest dostrzec cokolwiek w fabule, jaka jest, a myślenie, że oś X składa się tylko z tych trzech miesięcy, sprawi, że będzie ona bardziej użyteczna wizualnie. – glayne

Odpowiedz

3

Mogłabym sobie wyobrazić, że używanie wielu obszarów pomocniczych, ponieważ istnieją zakresy dat, może być opcją. Dla uproszczenia możesz nanieść wszystkie dane na wszystkie wątki, ale ograniczyć każdy z wątków do jednego zakresu dat.

import numpy as np; np.random.seed(24191) 
import datetime 
import matplotlib.pyplot as plt 
import matplotlib.dates 

## generate some data x and y 
n= 1000 
year = np.random.randint(2000,2009, size=n) 
month = np.random.randint(6,9, size=n) 
day = np.random.randint(1,32, size=n) 
x = [datetime.date(y,m,d) for y,m,d in zip(year,month,day)] 
y = np.abs(np.random.randn(n)) 

## define the ranges for the dates 
drange = [[datetime.date(i,6,1),datetime.date(i,8,31)] for i in range(2000,2009)] 

## create as many subplots as there are date ranges 
fig, axes= plt.subplots(ncols=len(drange), sharey=True) 
fig.subplots_adjust(bottom=0.3,wspace=0) 

ymax = 1.1*y.max() 
## loop over subplots and limit each to one date range 
for i, ax in enumerate(axes): 
    ax.set_xlim(drange[i][0],drange[i][1]) 
    ax.set_ylim(0,ymax) 
    ax.scatter(x,y, s=4) 
    loc = matplotlib.dates.MonthLocator([6,7,8]) 
    fmt = matplotlib.dates.DateFormatter("%Y-%b") 
    ax.xaxis.set_major_locator(loc) 
    ax.xaxis.set_major_formatter(fmt) 
    plt.setp(ax.get_xticklabels(), rotation=90) 
    if i!=0: 
     ax.tick_params(axis="y", which="both", length=0) 

plt.show() 

enter image description here

+0

Tak więc ta odpowiedź to, czego chcesz? Jeśli nie, prawdopodobnie chciałbyś powiedzieć, jak daleko nie pomaga i co jeszcze chciałbyś osiągnąć. Po prostu patrząc na nowo dodane dane w pytaniu, wydaje się to dość proste do wdrożenia w powyższym kodzie. – ImportanceOfBeingErnest

+0

Dodawanie pionowych linii jest integralną częścią tego wykresu. Nigdy nie wyobrażałam sobie, że to ma sens, ale myślę, że to możliwe dzięki tej prostej modyfikacji. – roganjosh

+0

@roganjosh Co masz na myśli? Czy chciałbyś mieć fabułę bez pionowych linii? (Przyjeżdżają tutaj za darmo i są bardzo przydatni, ponieważ dzielą fabułę, tak że czytelnik nie jest zdezorientowany przez zepsutą oś danych.) – ImportanceOfBeingErnest

1

Brzmi jak chcesz po prostu wykreślić dane przed jednolitej tablicy, a następnie ustawić kleszczy do dat,

import datetime as dt 
import matplotlib.pyplot as plt 
import numpy as np 

dates = ['06/2015','07/2015','08/2015', '06/2016','07/2016','08/2016'] 
x = [dt.datetime.strptime(d,'%m/%Y').date() for d in dates] 
y = range(len(x)) + np.random.random(len(x)) 

#Plot vs dates 
fig, ax = plt.subplots(2,1) 
ax[0].plot(x,y,'r.') 

#Plot vs number and label 
ax[1].plot(y,'r.') 
ax[1].set_xticks(range(len(y))) 
ax[1].set_xticklabels(dates) 
plt.show() 

Która wygląda tak,

enter image description here

+0

Ponieważ OP nie określił danych (jeszcze), jest to z pewnością poprawna odpowiedź. Jest to łatwe rozwiązanie w przypadku szczególnego przypadku, gdy masz dokładnie jeden punkt danych na miesiąc. Obecnie nie jestem pewien, jak rozszerzyć go do ogólnego przypadku, w którym można mieć arbitralne punkty danych (jak w danych z [moja odpowiedź] (https://stackoverflow.com/a/45716573/4124317)). – ImportanceOfBeingErnest

+0

@ImportanceOfBeingErnest Dodałem zrzut ekranu przedstawiający moje dane w OP. – glayne

+0

Ah Widzę @ImportanceOfBeingErnest, myślę, że możesz dodać pominięcie na etykietach "set_xticklabels (date [:: 10])", aby zapobiec przepełnieniu, ale zgadzam się, że to nie jest najlepsze rozwiązanie dla ogólnego przypadku. Przegrałem twoją odpowiedź :) –

Powiązane problemy