2015-03-29 9 views
18

बनाम एक पांडा DataFrame है:पांडा और matplotlib - fill_between() datetime64

<class 'pandas.core.frame.DataFrame'> 
Int64Index: 300 entries, 5220 to 5519 
Data columns (total 3 columns): 
Date    300 non-null datetime64[ns] 
A    300 non-null float64 
B    300 non-null float64 
dtypes: datetime64[ns](1), float64(2) 
memory usage: 30.5 KB 

मैं साजिश बनाम तिथि ए और बी श्रृंखला चाहते हैं।

plt.fill_between(data['Date'], data['A'], data['B'], 
       where=data['A'] >= data['B'], 
       facecolor='green', alpha=0.2, interpolate=True) 

कौन सा आउटपुट:

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

matplotlib fill_between() समारोह में स्वीकार पांडा datetime64 वस्तु करता

plt.plot_date(data['Date'], data['A'], '-') 
plt.plot_date(data['Date'], data['B'], '-') 

तो मैं ए और बी श्रृंखला के बीच के क्षेत्र पर fill_between() लागू करना चाहते हैं? क्या मुझे इसे अलग-अलग दिनांक प्रकार में परिवर्तित करना चाहिए?

+0

इस तरीके को दोनों 'plt' के लिए काम करते हैं और' plt.fill_between (डेटा अक्ष चाहिए [ 'तिथि']। Dt.to_pydatetime(), डेटा [ 'ए'], ... । 'यह अजगर के datetime कि fill_between समझता को numpy datetime64 [एनएस] धर्मान्तरित – jedi

उत्तर

15

Pandas registers a convertermatplotlib.units.registry जो एक (जैसे पांडा DatetimeIndex के रूप में, और dtype datetime64 की NumPy सरणी) datetime प्रकार की संख्या datenums matplotlib में बदलता है, लेकिन यह dtype datetime64 साथ पांडा Series संभाल नहीं करता है। के लिए और

In [67]: import pandas.tseries.converter as converter 

In [68]: c = converter.DatetimeConverter() 

In [69]: type(c.convert(df['Date'].values, None, None)) 
Out[69]: numpy.ndarray    # converted (good) 

In [70]: type(c.convert(df['Date'], None, None)) 
Out[70]: pandas.core.series.Series # left unchanged 

fill_between चेकों एक कनवर्टर का उपयोग करता है यदि वह मौजूद डेटा को संभालने के लिए।

तो एक समाधान के रूप में, आप दिनांक datetime64 की की एक NumPy सरणी के लिए परिवर्तित कर सकते हैं:

d = data['Date'].values 
plt.fill_between(d, data['A'], data['B'], 
       where=data['A'] >= data['B'], 
       facecolor='green', alpha=0.2, interpolate=True) 

उदाहरण के लिए,

import numpy as np 
import matplotlib.pyplot as plt 
import pandas as pd 

N = 300 
dates = pd.date_range('2000-1-1', periods=N, freq='D') 
x = np.linspace(0, 2*np.pi, N) 
data = pd.DataFrame({'A': np.sin(x), 'B': np.cos(x), 
       'Date': dates}) 
plt.plot_date(data['Date'], data['A'], '-') 
plt.plot_date(data['Date'], data['B'], '-') 

d = data['Date'].values 
plt.fill_between(d, data['A'], data['B'], 
       where=data['A'] >= data['B'], 
       facecolor='green', alpha=0.2, interpolate=True) 
plt.xticks(rotation=25) 
plt.show() 

enter image description here

+0

वैकल्पिक हल पूरी तरह से काम करता है - बहुत बहुत धन्यवाद यह व्यवहार काफी अजीब है, क्या कारण हो सकता है यहाँ – chilliq

+3

@chilliq:। मेरा पहला सुझाव उपयोग करने के लिए किया गया था।? एक DatetimeIndex। ऐसा लगता है कि जरूरी नहीं है। यह जल्दी बस 'उपयोग करने के लिए डेटा [ 'तिथि'] है। values' पांडा सीरीज से अंतर्निहित NumPy सरणी को निकालने के लिए। – unutbu

+0

यह बहुत उपयोगी है, मैं के बारे में पता नहीं था उस। मैं belive कि इस छोटे चाल matplotlib साथ DataFrames की साजिश रचने के साथ मेरी कई समस्याओं का हल करने के लिए जा रहा है। – chilliq

3

मैं का सामना करना पड़ा पांडस 0.21 के उन्नयन के बाद यह मुद्दा। मेरा कोड पहले fill_between() के साथ ठीक चला गया लेकिन अपग्रेड के बाद तोड़ दिया।

ऐसा नहीं है कि यह सुधार @unutbu के जवाब में बताया गया है, जो है जो मैं वैसे भी पहले था, तभी काम करता है DatetimeIndex बजाय date वस्तुओं datetime वस्तुओं समय की जानकारी है कि शामिल है पता चला है।

ऊपर के उदाहरण को देखते हुए, मैं क्या ठीक करने के लिए यह fill_between() कॉल करने से पहले निम्न पंक्ति जोड़ने के लिए था:

d['Date'] = [z.date() for z in d['Date']] 
2

Willz के रूप में बताया, पांडा 0.21 unutbu के वैकल्पिक हल तोड़ दिया। डेटाटाइम्स को तारीखों में कनवर्ट करना, हालांकि, डेटा विश्लेषण पर महत्वपूर्ण नकारात्मक प्रभाव हो सकते हैं।यह समाधान वर्तमान में काम करता है और रहता है datetime:

import numpy as np 
import matplotlib.pyplot as plt 
import pandas as pd 

N = 300 
dates = pd.date_range('2000-1-1', periods=N, freq='ms') 
x = np.linspace(0, 2*np.pi, N) 
data = pd.DataFrame({'A': np.sin(x), 'B': np.cos(x), 
      'Date': dates}) 
d = data['Date'].dt.to_pydatetime() 
plt.plot_date(d, data['A'], '-') 
plt.plot_date(d, data['B'], '-') 


plt.fill_between(d, data['A'], data['B'], 
      where=data['A'] >= data['B'], 
      facecolor='green', alpha=0.2, interpolate=True) 
plt.xticks(rotation=25) 
plt.show() 

fill_between with datetime64 constraint

संपादित करें: प्रति जेडी की टिप्पणी के रूप में, मैं बाहर सेट नीचे तीन विकल्पों में से सबसे तेजी से दृष्टिकोण का निर्धारण करने के लिए:

  • Method1 = मूल उत्तर
  • method2 = जेडीआई की टिप्पणी + मूल उत्तर
  • method3 = जेडीआई की टिप्पणी

Method2 थोड़ा तेज है, लेकिन अधिक संगत था, और इस तरह मैं ऊपर जवाब संपादित किया है सबसे अच्छा तरीका प्रतिबिंबित करने के लिए।

import numpy as np 
import matplotlib.pyplot as plt 
import pandas as pd 
import time 


N = 300 
dates = pd.date_range('2000-1-1', periods=N, freq='ms') 
x = np.linspace(0, 2*np.pi, N) 
data = pd.DataFrame({'A': np.sin(x), 'B': np.cos(x), 
      'Date': dates}) 
time_data = pd.DataFrame(columns=['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']) 
method1 = [] 
method2 = [] 
method3 = [] 
for i in range(0, 10): 
    start = time.clock() 
    for i in range(0, 500): 
     d = [pd.Timestamp(x).to_pydatetime() for x in data['Date']] 
     #d = data['Date'].dt.to_pydatetime() 
     plt.plot_date(d, data['A'], '-') 
     plt.plot_date(d, data['B'], '-') 


     plt.fill_between(d, data['A'], data['B'], 
      where=data['A'] >= data['B'], 
      facecolor='green', alpha=0.2, interpolate=True) 
     plt.xticks(rotation=25) 
     plt.gcf().clear() 
    method1.append(time.clock() - start) 

for i in range(0, 10): 
    start = time.clock() 
    for i in range(0, 500): 
     #d = [pd.Timestamp(x).to_pydatetime() for x in data['Date']] 
     d = data['Date'].dt.to_pydatetime() 
     plt.plot_date(d, data['A'], '-') 
     plt.plot_date(d, data['B'], '-') 


     plt.fill_between(d, data['A'], data['B'], 
      where=data['A'] >= data['B'], 
      facecolor='green', alpha=0.2, interpolate=True) 
     plt.xticks(rotation=25) 
     plt.gcf().clear() 
    method2.append(time.clock() - start) 

for i in range(0, 10): 
    start = time.clock() 
    for i in range(0, 500): 
     #d = [pd.Timestamp(x).to_pydatetime() for x in data['Date']] 
     #d = data['Date'].dt.to_pydatetime() 
     plt.plot_date(data['Date'].dt.to_pydatetime(), data['A'], '-') 
     plt.plot_date(data['Date'].dt.to_pydatetime(), data['B'], '-') 


     plt.fill_between(data['Date'].dt.to_pydatetime(), data['A'], data['B'], 
      where=data['A'] >= data['B'], 
      facecolor='green', alpha=0.2, interpolate=True) 
     plt.xticks(rotation=25) 
     plt.gcf().clear() 
    method3.append(time.clock() - start) 

time_data.loc['method1'] = method1 
time_data.loc['method2'] = method2 
time_data.loc['method3'] = method3 
print(time_data) 
plt.errorbar(time_data.index, time_data.mean(axis=1), yerr=time_data.std(axis=1)) 

time test of 3 methods on converting time data for plotting a DataFrame

+0

यह एक तेज़ और सरल कामकाज है 'plt.fill_between (डेटा [' तिथि ']। Dt.to_pydatetime(), ...' यह 'axes.fill_between' के साथ भी काम करता है। – jedi

+0

@jedi अनुशंसा के लिए धन्यवाद। मैं अपनी टिप्पणी के जवाब में जवाब संपादित किया है। – TurnipEntropy

संबंधित मुद्दे