2017-08-01 77 views
2

這裏是產生填充區域的兩行的曲線圖之間的小片的代碼:MatPlotLib,日期時間,和類型錯誤:ufunc「ISFINITE」不支持輸入類型...

import matplotlib.pyplot as plt 
import numpy as np 

x = np.arange(0.0, 2, 0.01) 
y1 = np.sin(2 * np.pi * x) 
y2 = 1.2 * np.sin(4 * np.pi * x) 

fig, ax1 = plt.subplots(1, 1, sharex=True) 

# Test support for masked arrays. 
ax1.fill_between(x, 0, y1) 
ax1.set_ylabel('between y1 and 0') 
y2 = np.ma.masked_greater(y2, 1.0) 
ax1.plot(x, y1, x, y2, color='black') 
ax1.fill_between(
    x, y1, y2, where=y2 >= y1, 
    facecolor='green', 
    interpolate=True) 
ax1.fill_between(x, y1, y2, where=y2 <= y1, facecolor='red', interpolate=True) 
ax1.set_title('Now regions with y2>1 are masked') 

# Show the plot. 
plt.show() 

它看起來像這樣:

Plot generated by the code

現在,改變開始讓x現在的日期倍集合對象,像這樣:

import datetime 

x1 = np.arange(0.0, 2, 0.01) 
now = np.datetime64(datetime.datetime.now()) 
x = np.array([now - np.timedelta64(datetime.timedelta(seconds=i)) for i in range(200)]) 
y1 = np.sin(2 * np.pi * x1) 
y2 = 1.2 * np.sin(4 * np.pi * x1) 

產量:

Traceback (most recent call last):            File "fill_between_demo.py", line 21, in <module>        
    ax1.fill_between(x, 0, y1)             
    File "/home/usr/.virtualenvs/raiju/lib/python3.6/site-packages/matplotlib/__init__.py", line 1898, in inner             
    return func(ax, *args, **kwargs)            
    File "/home/usr/.virtualenvs/raiju/lib/python3.6/site-packages/matplotlib/axes/_axes.py", line 4778, in fill_between           
    x = ma.masked_invalid(self.convert_xunits(x))        
    File "/home/usr/.virtualenvs/raiju/lib/python3.6/site-packages/numpy/ma/core.py", line 2388, in masked_invalid            
    condition = ~(np.isfinite(a))            
TypeError: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''  

這是爲什麼發生,如何解決呢?

請注意,繪製數據(又名不使用fill*)工作得很好。

回答

5

問題是,numpy ufunc isfinite沒有爲numpy.datetime64 dtype定義。儘管如此,仍有努力改變這一點。這issue on numpy's github正在這pull-request正在工作,但只要這還沒有完成併合並,您將無法在該dtype上使用isfinite。這是一個問題,因爲matplotlib.pyplot.fill_between在調用numpy.ma.masked_invalid來隱藏輸入數組的所有無效條目時隱式使用此函數。

雖然有一個解決辦法。正如在answer中指出類似的問題,有關fill_between類似的問題,datetime64類型的熊貓Series的繪圖,pandas註冊一個自定義轉換器(其中包括)datetime64 dtype與matplotlib的numpy數組。要使用它,你只需要導入熊貓:

import numpy as np 
import matplotlib.pyplot as plt 
import datetime 
# import pandas for its converter that is then used in pyplot! 
import pandas 

x1 = np.arange(0.0, 2, 0.01) 
now = np.datetime64(datetime.datetime.now()) 
x = np.array([now - np.timedelta64(datetime.timedelta(seconds=i)) 
       for i in range(200)]) 
y1 = np.sin(2 * np.pi * x1) 
y2 = 1.2 * np.sin(4 * np.pi * x1) 

fig, ax1 = plt.subplots(1, 1, sharex=True) 

# Test support for masked arrays. 
ax1.fill_between(x, 0, y1) 
ax1.set_ylabel('between y1 and 0') 
y2 = np.ma.masked_greater(y2, 1.0) 
ax1.plot(x, y1, x, y2, color='black') 
ax1.fill_between(
    x, y1, y2, where=y2 >= y1, 
    facecolor='green', 
    interpolate=True) 
ax1.fill_between(x, y1, y2, where=y2 <= y1, facecolor='red', interpolate=True) 
ax1.set_title('Now regions with y2>1 are masked') 

# Show the plot. 
plt.show() 

會工作,並給你所需的輸出:

enter image description here

相關問題