Trazar el tiempo en el eje independiente

6 minutos de lectura

avatar de usuario de randomThought
pensamiento aleatorio

Tengo una matriz de marcas de tiempo en el formato (HH:MM:SS.mmmmmm) y otra matriz de números de punto flotante, cada uno correspondiente a un valor en la matriz de marcas de tiempo.

¿Puedo trazar el tiempo en el eje x y los números en el eje y usando Matplotlib?

Estaba tratando de hacerlo, pero de alguna manera solo aceptaba matrices de flotadores. ¿Cómo puedo hacer que marque el tiempo? ¿Tengo que modificar el formato de alguna manera?

avatar de usuario de codeape
código

Actualizar:

Esta respuesta está desactualizada. desde matplotlib versión 3.5. El plot La función ahora maneja los datos de fecha y hora directamente. Ver https://matplotlib.org/3.5.1/api/_as_gen/matplotlib.pyplot.plot_date.html

Se desaconseja el uso de plot_date. Este método existe por razones históricas y puede quedar obsoleto en el futuro.

Los datos similares a fecha y hora deben trazarse directamente usando plot.

Si necesita trazar datos numéricos simples como formato de fecha de Matplotlib o necesita establecer una zona horaria, llame a ax.xaxis.axis_date / ax.yaxis.axis_date antes de trazar. Consulte Axis.axis_date.


Respuesta antigua y desactualizada:

Primero debe convertir sus marcas de tiempo a Python datetime objetos (uso datetime.strptime). Entonces usa date2num para convertir las fechas al formato matplotlib.

Trazar las fechas y los valores usando plot_date:

import matplotlib.pyplot as plt
import matplotlib.dates

from datetime import datetime

x_values = [datetime(2021, 11, 18, 12), datetime(2021, 11, 18, 14), datetime(2021, 11, 18, 16)]
y_values = [1.0, 3.0, 2.0]

dates = matplotlib.dates.date2num(x_values)
plt.plot_date(dates, y_values)

ingrese la descripción de la imagen aquí

avatar de usuario de moooeeeep
moooeeeeep

También puede trazar la marca de tiempo, los pares de valores usando pyplot.plot (después de analizarlos desde su representación de cadena). (Probado con matplotlib versiones 1.2.0 y 1.3.1.)

Ejemplo:

import datetime
import random
import matplotlib.pyplot as plt

# make up some data
x = [datetime.datetime.now() + datetime.timedelta(hours=i) for i in range(12)]
y = [i+random.gauss(0,1) for i,_ in enumerate(x)]

# plot
plt.plot(x,y)
# beautify the x-labels
plt.gcf().autofmt_xdate()

plt.show()

Imagen resultante:

Gráfico de línea


Esto es lo mismo que un diagrama de dispersión:

import datetime
import random
import matplotlib.pyplot as plt

# make up some data
x = [datetime.datetime.now() + datetime.timedelta(hours=i) for i in range(12)]
y = [i+random.gauss(0,1) for i,_ in enumerate(x)]

# plot
plt.scatter(x,y)
# beautify the x-labels
plt.gcf().autofmt_xdate()

plt.show()

Produce una imagen similar a esta:

Gráfico de dispersión

7 años después y este código me ha ayudado. Sin embargo, mis tiempos aún no se mostraban correctamente.

ingrese la descripción de la imagen aquí

Usando Matplotlib 2.0.0 y tuve que agregar el siguiente código de Edición del formato de fecha de las etiquetas de marca del eje x en matplotlib por Paul H.

import matplotlib.dates as mdates
myFmt = mdates.DateFormatter('%d')
ax.xaxis.set_major_formatter(myFmt)

Cambié el formato a (%H:%M) y la hora se mostró correctamente.
ingrese la descripción de la imagen aquí

Todo gracias a la comunidad.

Avatar de usuario de Kirk
Iglesia

Tuve problemas con esto usando la versión de matplotlib: 2.0.2. Al ejecutar el ejemplo de arriba, obtuve un conjunto de burbujas apiladas centradas.

gráfico con pila centrada de burbujas

“Solucioné” el problema agregando otra línea:

plt.plot([],[])

El fragmento de código completo se convierte en:

import datetime
import random
import matplotlib.pyplot as plt
import matplotlib.dates as mdates


# make up some data
x = [datetime.datetime.now() + datetime.timedelta(minutes=i) for i in range(12)]
y = [i+random.gauss(0,1) for i,_ in enumerate(x)]

# plot
plt.plot([],[])
plt.scatter(x,y)

# beautify the x-labels
plt.gcf().autofmt_xdate()
myFmt = mdates.DateFormatter('%H:%M')
plt.gca().xaxis.set_major_formatter(myFmt)

plt.show()
plt.close()

Esto produce una imagen con las burbujas distribuidas como se desee.

gráfico con burbujas distribuidas en el tiempo

Los marcos de datos de Pandas aún no se han mencionado. Quería mostrar cómo estos resolvieron mi problema de fecha y hora. Tengo fecha y hora al milisegundo 2021-04-01 16:05:37. Estoy extrayendo el rendimiento de linux/haproxy de /proc para que realmente pueda formatearlo como quiera. Esto es bueno para introducir datos en una animación gráfica en vivo.

Aquí hay un vistazo al csv. (Ignore los paquetes por segunda columna que estoy usando en otro gráfico)

head -2 ~/data
date,mbps,pps
2021-04-01 16:05:37,113,9342.00
...

Mediante el uso print(dataframe.dtype) Puedo ver cómo se leyeron los datos en:

(base) ➜  graphs ./throughput.py
date      object
mbps      int64
pps       float64
dtype:    object

Pandas extrae la cadena de fecha como “objeto”, que es solo tipo char. Usando esto tal como está en un script:

import matplotlib.pyplot as plt
import pandas as pd

dataframe = pd.read_csv("~/data")

dates = dataframe["date"]
mbps = dataframe["mbps"]

plt.plot(dates, mbps, label="mbps")
plt.title("throughput")
plt.xlabel("time")
plt.ylabel("mbps")
plt.legend()
plt.xticks(rotation=45)

plt.show()

ingrese la descripción de la imagen aquí

Matplotlib representa todos los datos de tiempo en milisegundos. he añadido plt.xticks(rotation=45) inclinar las fechas pero no es lo que quiero. Puedo convertir la fecha “objeto” a una fecha y hora64[ns]. Que matplotlib sabe cómo renderizar.

dataframe["date"] = pd.to_datetime(dataframe["date"]) 

Esta vez mi fecha es tipo datetime64[ns]

(base) ➜  graphs ./throughput.py
date    datetime64[ns]
mbps             int64
pps            float64
dtype:          object

Mismo guión con 1 línea de diferencia.

#!/usr/bin/env python
import matplotlib.pyplot as plt
import pandas as pd

dataframe = pd.read_csv("~/data")

# convert object to datetime64[ns]
dataframe["date"] = pd.to_datetime(dataframe["date"]) 

dates = dataframe["date"]
mbps = dataframe["mbps"]

plt.plot(dates, mbps, label="mbps")
plt.title("throughput")
plt.xlabel("time")
plt.ylabel("mbps")
plt.legend()
plt.xticks(rotation=45)

plt.show()

Es posible que esto no haya sido ideal para su caso de uso, pero podría ayudar a otra persona.

ingrese la descripción de la imagen aquí

  • Esto me ahorró un montón de tiempo y frustración, ¡gracias por compartir! ¿Alguna idea de cómo hacer que las fechas de la etiqueta x se muestren en formato día-mes-año-hora-min?

    – Rubén

    29 de agosto de 2021 a las 8:31

  • ¡Fresco! Sí, cree una subparcela para acceder al atributo xaxis. Este es un comentario tan difícil de mostrar, pero de mi ejemplo anterior, agregue fig,ax = plt.subplots() y añadir date_form = DateFormatter("%d-%m-%Y-%H-%M") y ax.xaxis.set_major_formatter(date_form) antes .show()

    – b0bu

    30 de agosto de 2021 a las 10:13


  • Esto me ahorró un montón de tiempo y frustración, ¡gracias por compartir! ¿Alguna idea de cómo hacer que las fechas de la etiqueta x se muestren en formato día-mes-año-hora-min?

    – Rubén

    29 de agosto de 2021 a las 8:31

  • ¡Fresco! Sí, cree una subparcela para acceder al atributo xaxis. Este es un comentario tan difícil de mostrar, pero de mi ejemplo anterior, agregue fig,ax = plt.subplots() y añadir date_form = DateFormatter("%d-%m-%Y-%H-%M") y ax.xaxis.set_major_formatter(date_form) antes .show()

    – b0bu

    30 de agosto de 2021 a las 10:13


¿Ha sido útil esta solución?