2017-07-12 67 views
0

我想繪製一些數據與python與matplotlib相應的時間戳。在「日期」實際上是datetime.time對象(所以沒有相應的日期,我不關心日期),它看起來像這樣:在matplotlib中繪製日期,一個陰謀工程其他不

In[6]: dates[1] 
Out[6]: datetime.time(12, 3, 1) 

我創建了一個簡單的代碼,這說明我想什麼做(和我的實際數據做什麼,但沒有工作因爲某種原因):

工作守則

import matplotlib.pyplot as plt 
import matplotlib.dates as pltdt 
import datetime as dt 

dates = [dt.time(12,3,i) for i in range(6)] 
time_to_datetime = [] 
for i in dates: 
    time_to_datetime.append(dt.datetime.combine(dt.date.min, i)) 
dates_as_num = pltdt.date2num(time_to_datetime) 
values = range(len(dates)) 

plt.plot_date(dates_as_num, values) 
plt.show() 

print ('Done!') 

將會產生以下情節:

Example of what I want

然而,當我做這個確切的過程與我的數據(當然,而不是6點我有萬〜30萬並有一些額外的處理髮生),我收到以下錯誤:

Traceback (most recent call last): 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\backends\backend_qt5agg.py", line 197, in __draw_idle_agg 
    FigureCanvasAgg.draw(self) 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\backends\backend_agg.py", line 464, in draw 
    self.figure.draw(self.renderer) 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\artist.py", line 63, in draw_wrapper 
    draw(artist, renderer, *args, **kwargs) 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\figure.py", line 1143, in draw 
    renderer, self, dsu, self.suppressComposite) 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\image.py", line 139, in _draw_list_compositing_images 
    a.draw(renderer) 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\artist.py", line 63, in draw_wrapper 
    draw(artist, renderer, *args, **kwargs) 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\axes\_base.py", line 2409, in draw 
    mimage._draw_list_compositing_images(renderer, self, dsu) 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\image.py", line 139, in _draw_list_compositing_images 
    a.draw(renderer) 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\artist.py", line 63, in draw_wrapper 
    draw(artist, renderer, *args, **kwargs) 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\axis.py", line 1136, in draw 
    ticks_to_draw = self._update_ticks(renderer) 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\axis.py", line 969, in _update_ticks 
    tick_tups = [t for t in self.iter_ticks()] 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\axis.py", line 969, in <listcomp> 
    tick_tups = [t for t in self.iter_ticks()] 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\axis.py", line 912, in iter_ticks 
    majorLocs = self.major.locator() 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\dates.py", line 983, in __call__ 
    self.refresh() 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\dates.py", line 1003, in refresh 
    dmin, dmax = self.viewlim_to_dt() 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\dates.py", line 760, in viewlim_to_dt 
    return num2date(vmin, self.tz), num2date(vmax, self.tz) 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\dates.py", line 401, in num2date 
    return _from_ordinalf(x, tz) 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\dates.py", line 254, in _from_ordinalf 
    dt = datetime.datetime.fromordinal(ix).replace(tzinfo=UTC) 
ValueError: ordinal must be >= 1 
Traceback (most recent call last): 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\backends\backend_qt5agg.py", line 197, in __draw_idle_agg 
    FigureCanvasAgg.draw(self) 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\backends\backend_agg.py", line 464, in draw 
    self.figure.draw(self.renderer) 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\artist.py", line 63, in draw_wrapper 
    draw(artist, renderer, *args, **kwargs) 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\figure.py", line 1143, in draw 
    renderer, self, dsu, self.suppressComposite) 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\image.py", line 139, in _draw_list_compositing_images 
    a.draw(renderer) 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\artist.py", line 63, in draw_wrapper 
    draw(artist, renderer, *args, **kwargs) 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\axes\_base.py", line 2409, in draw 
    mimage._draw_list_compositing_images(renderer, self, dsu) 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\image.py", line 139, in _draw_list_compositing_images 
    a.draw(renderer) 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\artist.py", line 63, in draw_wrapper 
    draw(artist, renderer, *args, **kwargs) 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\axis.py", line 1136, in draw 
    ticks_to_draw = self._update_ticks(renderer) 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\axis.py", line 969, in _update_ticks 
    tick_tups = [t for t in self.iter_ticks()] 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\axis.py", line 969, in <listcomp> 
    tick_tups = [t for t in self.iter_ticks()] 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\axis.py", line 912, in iter_ticks 
    majorLocs = self.major.locator() 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\dates.py", line 983, in __call__ 
    self.refresh() 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\dates.py", line 1003, in refresh 
    dmin, dmax = self.viewlim_to_dt() 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\dates.py", line 760, in viewlim_to_dt 
    return num2date(vmin, self.tz), num2date(vmax, self.tz) 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\dates.py", line 401, in num2date 
    return _from_ordinalf(x, tz) 
    File "C:\Users\Will Evonosky\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\dates.py", line 254, in _from_ordinalf 
    dt = datetime.datetime.fromordinal(ix).replace(tzinfo=UTC) 
ValueError: ordinal must be >= 1 
%run "c:\users\willev~1\appdata\local\temp\tmpjkubsr.py" 

我有盡我所能,讓這件事情沒有成功。我甚至嘗試將時間轉換爲字符串,並且只是手動設置x軸的刻度標籤,但遇到了一個問題,即x軸上顯示的內容不能精確地表示實際日期(應該有200分鐘以分鐘間隔顯示,即使y值跨越整個200點範圍,也總共顯示3分鐘)。謝謝你的幫助!

我修剪的代碼如下(抱歉它是凌亂):

import matplotlib.pyplot as plt 
import matplotlib.dates as pltdt 
import numpy as np 
import datetime as dt 
import math 

def plot_two_orbit(times, values): 
    fig2 = plt.figure(figsize = (14,8)) 
    ax2=plt.subplot(111) 
    ax2.plot_date(times, values, linewidth=4) 
    ax2.set_xticklabels([i.strftime('%H:%M') for i in two_orbit_times]) 
    ax2.yaxis.set_ticks_position("left") 
    ax2.xaxis.set_ticks_position("bottom") 
    ax2.spines['top'].set_color('None') 
    ax2.spines['right'].set_color('None') 
    ax2.spines['bottom'].set_color('black') 
    ax2.spines['left'].set_color('black') 
    ax2.tick_params(axis='x', colors='black', labelsize=20, pad=10) 
    ax2.tick_params(axis='y', colors='black', labelsize=20, pad=10) 
    ax2.yaxis.label.set_color('black') 
    ax2.xaxis.label.set_color('black') 
    ax2.set_ylabel(r'Ion Temp (K)', size=23) 
    ax2.set_xlabel(r'Local Time', size=23) 
    plt.show() 
    return None 

#model parameters 
modalt = np.arange(90, 1005, 5) #90km to 1000km in 5km increiments, 
modlat = np.arange(-90, 92, 2) #latitude from 0 to 355 in 5 degree incriments 
modlon = np.arange(0,356, 4) #longitude from -87.5 to 87.5 in 5 degree incriments 
modtime = np.arange(.25,24.25,.25) # time in 15 minute incriments 

#making the modtime array into a python datetime.time object 
times = [] 
for i in modtime: 
    strip = [math.modf(i)[1],math.modf(i)[0]*60 ] 
    if strip[0]==24: 
     times.append(dt.time(0, int(strip[1]),0)) 
    else: 
     times.append(dt.time(int(strip[0]), int(strip[1]),0)) 

#loading in the Model data 
mdatas =np.load('C:/Users/Will Evonosky/Dropbox/SOARS/SOARS 2017/Data/GIP_Feb5_ti.npy') 

#Function to find the index of the neasrest array point to a given value 
def find_nearest(array,value): 
    idx = (np.abs(array-value)).argmin() 
    return idx 

#load in the ephemeris data retrieved from STK 
ephem = np.genfromtxt('C:/Users/Will Evonosky/Dropbox/SOARS/SOARS 2017/Data/STK Data/Location for count and science/Times_Loc_Fix_7mon_500km.csv', skip_header=1, dtype=None, delimiter=',') 

#Pulling out the indivdual parameters from the STK data 
sattime = [dt.datetime.strptime(i[1].decode('ascii'), '%H:%M').time() for i in ephem] 
satlat = np.round([i[2] for i in ephem], decimals=2) 
satlon = np.round([i[3] for i in ephem], decimals=2) 
satalt = np.round([i[4] for i in ephem], decimals=2) 

#making the modeled satellite longitude match GIP (-180 to 180) to (0 to 360) 
satloncor = [] 
for i in satlon: 
    if i<0: 
     satloncor.append(round(i+360,2)) 
    else: 
     satloncor.append(round(i,2)) 

#Converting UT times for satellite data into local solar time 

localtimes = [] 
for (i,j) in zip(sattime, satloncor): 
    td = dt.datetime.combine(dt.datetime.min, i) - dt.datetime.min 
    seconds = td // dt.timedelta(seconds=1) 
    local = (seconds + (j/(360/86400)))/3600 
    if local>24: 
     local-=24 
    strip = [math.modf(local)[1],math.modf(local)[0]*60 ] 
    if strip[0]==24: 
     localtimes.append(dt.time(0, int(strip[1]),0)) 
    else: 
     localtimes.append(dt.time(int(strip[0]), int(strip[1]),0)) 

#Creating empty arrays to hold the resulting values 
grid_night_hour = np.zeros((24,len(modlat),len(modlon))) 
two_orbit_line = [] 
two_orbit_times=[] 

#Count determines how many orbits to sample. 1 orbit is ~ 90 data points 
count = 200 
night_hours = [20,21,22,23,0,1,2,3,4,5] 
#plucking out the model data which most closely match the lat, lon, time, and alt of STK sat data 
for (i,j,k,l,m) in zip(satlat, satloncor, sattime, satalt, localtimes): 
    mlat = find_nearest(modlat, i) 
    mlon = find_nearest(modlon, j) 
    malt = find_nearest(modalt, l) 
    mtime = times.index(min(times, key=lambda d: abs(dt.datetime.combine(dt.date.min,d) - dt.datetime.combine(dt.date.min,k)))) 
    if m.hour in night_hours: 
     grid_night_hour[m.hour, mlat, mlon] = mdatas[malt, mlat, mlon, mtime] 
    if count > 0: 
     two_orbit_line.append(mdatas[malt, mlat, mlon, mtime]) 
     two_orbit_times.append(pltdt.date2num(dt.datetime.combine(dt.date.min,m))) 
     count-=1 

#masking zero values so they wont plot 
grid_night_hour[grid_night_hour == 0.0] = np.nan 

grid_night_hour = grid_night_hour - np.nanmean(grid_night_hour) 

#Plotting the data 

plot_two_orbit(two_orbit_times, two_orbit_line) 

print ('Done!') 

回答

1

我想通了。儘管他們的表述不正確,但Y.Luo仍然走在正確的軌道上。我認爲python的日期時間庫所支持的最低年度對於matploltib所確認的日期來說太低,而對於最大年份來說也是一樣的。我手動插入日期(下面更改的代碼),情節突然工作。現在我遇到了另一個問題,但這將是另一個問題。

if count > 0: 
     two_orbit_line.append(mdatas[malt, mlat, mlon, mtime]) 
     two_orbit_times.append(pltdt.date2num(dt.datetime.combine(dt.date(2019,1,1),m))) 
     count-=1 
+0

很高興聽到你已經想通了。將刪除我的答案,以避免混淆。 –