El fill_between de matplotlib no funciona con plot_date, ¿alguna alternativa?

Quiero crear una ttwig como esta: Esto tiene valores enteros x

El código:

P.fill_between(DF.start.index, DF.lwr, DF.upr, facecolor='blue', alpha=.2) P.plot(DF.start.index, DF.Rt, '.') 

pero con fechas en el eje x, así (sin bandas): con plot_date

el código:

 P.plot_date(DF.start, DF.Rt, '.') 

el problema es que fill_between falla cuando los valores de x son objetos date_time.

¿Alguien sabe de alguna solución? DF es un dataframe de pandas.

Sería de ayuda si muestra cómo se define df . ¿Qué df.info() ? Esto nos mostrará los tipos de columnas.

Hay muchas formas en que se pueden representar las fechas: como cadenas, ints, flotantes, datetime.datetime, NumPy datetime64s, Pandas Timestamps o Pandas DatetimeIndex. La forma correcta de trazarlo depende de lo que tengas.

Aquí hay un ejemplo que muestra que su código funciona si df.index es un df.index y hora:

 import numpy as np import pandas as pd import matplotlib.pyplot as plt from scipy import stats index = pd.date_range(start='2000-1-1', end='2015-1-1', freq='M') N = len(index) poisson = (stats.poisson.rvs(1000, size=(N,3))/100.0) poisson.sort(axis=1) df = pd.DataFrame(poisson, columns=['lwr', 'Rt', 'upr'], index=index) plt.fill_between(df.index, df.lwr, df.upr, facecolor='blue', alpha=.2) plt.plot(df.index, df.Rt, '.') plt.show() 

introduzca la descripción de la imagen aquí


Si el índice tiene representaciones de cadena de fechas, entonces (con Matplotlib versión 1.4.2) obtendría un TypeError:

 import numpy as np import pandas as pd import matplotlib.pyplot as plt from scipy import stats index = pd.date_range(start='2000-1-1', end='2015-1-1', freq='M') N = len(index) poisson = (stats.poisson.rvs(1000, size=(N,3))/100.0) poisson.sort(axis=1) df = pd.DataFrame(poisson, columns=['lwr', 'Rt', 'upr']) index = [item.strftime('%Y-%m-%d') for item in index] plt.fill_between(index, df.lwr, df.upr, facecolor='blue', alpha=.2) plt.plot(index, df.Rt, '.') plt.show() 

rendimientos

  File "/home/unutbu/.virtualenvs/dev/local/lib/python2.7/site-packages/numpy/ma/core.py", line 2237, in masked_invalid condition = ~(np.isfinite(a)) TypeError: Not implemented for this type 

En este caso, la solución es convertir las cadenas en marcas de tiempo:

 index = pd.to_datetime(index) 

Respecto al error reportado por el chilliq:

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

Esto se puede producir si las columnas DataFrame tienen el tipo de “objeto” cuando se usa fill_between. Cambiar los tipos de columnas de ejemplo y luego tratar de trazar, de la siguiente manera, da como resultado el error anterior:

 import numpy as np import pandas as pd import matplotlib.pyplot as plt from scipy import stats index = pd.date_range(start='2000-1-1', end='2015-1-1', freq='M') N = len(index) poisson = (stats.poisson.rvs(1000, size=(N,3))/100.0) poisson.sort(axis=1) df = pd.DataFrame(poisson, columns=['lwr', 'Rt', 'upr'], index=index) dfo = df.astype(object) plt.fill_between(df0.index, df0.lwr, df0.upr, facecolor='blue', alpha=.2) plt.show() 

Desde dfo.info () vemos que los tipos de columna son “objeto”:

  DatetimeIndex: 180 entries, 2000-01-31 to 2014-12-31 Freq: M Data columns (total 3 columns): lwr 180 non-null object Rt 180 non-null object upr 180 non-null object dtypes: object(3) memory usage: 5.6+ KB 

Asegurarse de que el DataFrame tenga columnas numéricas resolverá el problema. Para hacer esto podemos usar pandas.to_numeric para convertir, de la siguiente manera:

 dfn = dfo.apply(pd.to_numeric, errors='ignore') plt.fill_between(dfn.index, dfn.lwr, dfn.upr, facecolor='blue', alpha=.2) plt.show()