python pandas matplotlib plot

python - pandas 0.21.0 Problema de compatibilidad de marca de tiempo con matplotlib



(2)

Después de abrir un issue en pandas github, aprendí que este era realmente un problema conocido entre pandas y matplotlib con respecto al registro automático del convertidor de unidades. De hecho, figuraba en la page novedades que no había visto antes, junto con la forma correcta de registrar los convertidores:

from pandas.tseries import converter converter.register()

Esto también se realiza la primera vez que se llama a un método de diagrama de miembros en un Series o DataFrame que explica lo que observé anteriormente.

Parece que se hizo con la intención de que se suponga que matplotlib implementa algún soporte básico para los pandas datetime, pero de hecho, una advertencia de desaprobación de algún tipo podría ser útil para tal interrupción. Sin embargo, hasta que matplotlib realmente implemente dicho soporte (o algún tipo de mecanismo de registro diferido), prácticamente siempre pongo esas dos líneas en la importación de pandas. Entonces, no estoy seguro de por qué los pandas desearían deshabilitar el registro automático en la importación antes de que las cosas estén listas en el lado de matplotlib.

Acabo de actualizar pandas de 0.17.1 a 0.21.0 para aprovechar algunas funcionalidades nuevas, y encontré un problema de compatibilidad con matplotlib (que también actualicé a la última versión 2.1.0). En particular, el objeto Timestamp parece haber cambiado significativamente.

Tengo otra máquina que aún ejecuta las versiones anteriores de pandas (0.17.1) / matplotlib (1.5.1) que solía comparar las diferencias:

Ambas versiones muestran que mi índice DataFrame es dtype=''datetime64[ns]

DatetimeIndex([''2017-03-13'', ''2017-03-14'', ... ''2017-11-17''], type=''datetime64[ns]'', name=''dates'', length=170, freq=None)

Pero cuando se llama al type(df.index[0]) , 0.17.1 da pandas.tslib.Timestamp y 0.21.0 da pandas._libs.tslib.Timestamp .

Al trazar con df.index como eje x:

plt.plot(df.index, df[''data''])

matplotlibs por defecto formatea las etiquetas del eje x como fechas para pandas 0.17.1 pero no lo reconoce para pandas 0.21.0 y simplemente da el número sin procesar 1.5e18 (tiempo de época en nanosec).

También tengo un cursor personalizado que informa la ubicación en la que se hizo clic en el gráfico usando matplotlib.dates.DateFormatter en el valor x que falla para 0.21.0 con:

OverflowError: signed integer is greater than maximum

Puedo ver en la depuración que el valor x informado es de alrededor de 736500 (es decir, recuento de días desde el año 0) para 0.17.1, pero es de alrededor de 1.5e18 (es decir, tiempo de época nanosec) para 0.21.0.

Estoy sorprendido de esta ruptura de compatibilidad entre matplotlib y pandas, ya que obviamente la mayoría de las personas los usan juntos. ¿Me estoy perdiendo algo en la forma en que llamo a la función de trazado anterior para las versiones más recientes?

Actualice como mencioné anteriormente, prefiero llamar directamente a plot con un objeto de ejes dado, pero solo por el gusto de hacerlo, intenté llamar al método de trazado del DataFrame en sí mismo df.plot() . Tan pronto como se hace esto, todos los gráficos posteriores reconocen correctamente la marca de tiempo dentro de la misma sesión de Python . Es como si se estableciera una variable de entorno, porque puedo recargar otro DataFrame o crear otros ejes con subplots y en ningún lugar aparece el 1.5e18 . Esto realmente huele a error ya que el último documento de pandas dice pandas :

The plot method on Series and DataFrame is just a simple wrapper around plt.plot()

Pero claramente hace algo a la sesión de Python de tal manera que las parcelas posteriores se ocupan correctamente del índice Timestamp.

De hecho, simplemente ejecutando el ejemplo en el enlace de pandas anterior:

import pandas as pd import numpy as np import matplotlib.pyplot as plt ts = pd.Series(np.random.randn(1000), index=pd.date_range(''1/1/2000'', periods=1000))

Dependiendo de si se llama o no a ts.plot() , el siguiente diagrama formatea correctamente el eje x como fechas o no:

plt.plot(ts.index,ts) plt.show()

Una vez que se llama a un diagrama de miembro, al llamar posteriormente a plt.plot en una nueva serie o DataFrame se formateará correctamente sin necesidad de volver a llamar al método de diagrama de miembro.


Hay un problema con las fechas de los pandas y el matplotlib que proviene del lanzamiento reciente de pandas 0.21, que ya no registra sus convertidores en la importación. Una vez que use esos convertidores una vez (dentro de los pandas), también serán registrados y utilizados automáticamente por matplotlib.

Una solución alternativa sería registrarlos manualmente,

import pandas.plotting._converter as pandacnv pandacnv.register()

En cualquier caso, el problema es bien conocido tanto en pandas como en matplotlib, por lo que habrá algún tipo de solución para las próximas versiones. Pandas está pensando en leer el registro en un próximo lanzamiento. Por lo tanto, este problema puede estar allí solo temporalmente. Una opción también es volver a los pandas 0.20.x donde esto no debería ocurrir.

Actualización: esto ya no es un problema con las versiones actuales de matplotlib (2.2.2) / pandas (0.23.1), y probablemente muchas que se han lanzado desde aproximadamente diciembre de 2017, cuando esto se solucionó.