es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

La creación de un gráfico pd df con un índice de fecha y hora en Matplotlib produce un ValueError debido a una incorrecta interpretación de los valores de fecha y hora.

Estoy tratando de trazar un pandas.DataFrame, pero obtengo un ValueError inexplicable. Aquí está el código de muestra que causa el problema:

import pandas as pd
import matplotlib.pyplot as plt
from io import StringIO
import matplotlib.dates as mdates

weekday_fmt = mdates.DateFormatter('%a %H:%M')
test_csv = 'datetime,x1,x2,x3,x4,x5,x6\n' \
           '2021-12-06 00:00:00,8,42,14,23,12,2\n' \
           '2021-12-06 00:15:00,17,86,68,86,92,45\n' \
           '2021-12-06 00:30:00,44,49,81,26,2,95\n' \
           '2021-12-06 00:45:00,35,78,33,18,80,67'
test_df = pd.read_csv(StringIO(test_csv), index_col=0)
test_df.index = pd.to_datetime(test_df.index)
plt.figure()
ax = test_df.plot()
ax.set_xlabel(f'Aggregación semanal')
ax.set_ylabel('etiqueta-y')
fig = plt.gcf()
fig.set_size_inches(12.15, 5)
ax.get_legend().remove()
ax.xaxis.set_major_formatter(weekday_fmt)  # Esta y la siguiente línea son las que causan los problemas
ax.xaxis.set_minor_formatter(weekday_fmt)
plt.show()

Si se eliminan las dos líneas de formateo, el código se ejecuta sin problemas. Sin embargo, si las dejo, obtengo un ValueError: ValueError: Date ordinal 27312480 converts to 76749-01-12T00:00:00.000000 (using epoch 1970-01-01T00:00:00), but Matplotlib dates must be between year 0001 and 9999.

La razón parece ser que la conversión de fecha y hora en pandas y matplotlib es incompatible. Esto probablemente podría solucionarse evitando el uso de la función plot incorporada de pandas. ¿Existe otra forma? ¡Gracias!

Las versiones de mis paquetes son:

pandas                    1.3.4 
numpy                     1.19.5 
matplotlib                3.4.2 
python                    3.8.10
Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Parece que la conversión de las fechas y horas en pandas y matplotlib son incompatibles, lo cual causa un ValueError. Una forma de solucionar este problema sería no utilizar la función plot incorporada en pandas. En su lugar, podrías usar matplotlib directamente para crear el gráfico. Aquí tienes un ejemplo de cómo hacerlo utilizando tu código de muestra:

    import pandas as pd
    import matplotlib.pyplot as plt
    from io import StringIO
    import matplotlib.dates as mdates
    
    weekday_fmt = mdates.DateFormatter('%a %H:%M')
    test_csv = 'datetime,x1,x2,x3,x4,x5,x6\n' \
               '2021-12-06 00:00:00,8,42,14,23,12,2\n' \
               '2021-12-06 00:15:00,17,86,68,86,92,45\n' \
               '2021-12-06 00:30:00,44,49,81,26,2,95\n' \
               '2021-12-06 00:45:00,35,78,33,18,80,67'
    test_df = pd.read_csv(StringIO(test_csv), index_col=0)
    test_df.index = pd.to_datetime(test_df.index)
    
    fig, ax = plt.subplots()
    ax.plot(test_df.index, test_df['x1'], label='x1')
    ax.plot(test_df.index, test_df['x2'], label='x2')
    ax.plot(test_df.index, test_df['x3'], label='x3')
    ax.plot(test_df.index, test_df['x4'], label='x4')
    ax.plot(test_df.index, test_df['x5'], label='x5')
    ax.plot(test_df.index, test_df['x6'], label='x6')
    ax.set_xlabel('Aggregación semanal')
    ax.set_ylabel('Etiqueta y')
    ax.legend()
    ax.xaxis.set_major_formatter(weekday_fmt)
    ax.xaxis.set_minor_formatter(weekday_fmt)
    plt.show()
    

    Este código crea una nueva figura y eje utilizando plt.subplots(), y luego traza cada columna individual del DataFrame utilizando la función plot del objeto de eje (ax.plot()). El eje x se formatea como antes utilizando el objeto weekday_fmt. Ten en cuenta que la leyenda debe agregarse manualmente utilizando la función legend del objeto de eje (ax.legend()).

Comments are closed.