dispersión de pandas trazando fecha y hora

Tengo un dataframe con dos columnas de datetime.time. Me gustaría dispersarlos. También me gustaría que los ejes muestren los tiempos, idealmente. Pero

df.plot(kind='scatter', x='T1', y='T2') 

vuelca un montón de errores de trazado internos que terminan con un KeyError en ‘T1’.

Por otra parte, bash

 plt.plot_date(x=df.loc[:,'T1'], y=df.loc[:,'T2']) plt.show() 

y obtengo ‘Exception in Tkinter callback’ con un rastreo de stack largo que termina en

 return _from_ordinalf(x, tz) File "/usr/lib/python3/dist-packages/matplotlib/dates.py", line 224, in _from_ordinalf microsecond, tzinfo=UTC).astimezone(tz) TypeError: tzinfo argument must be None or of a tzinfo subclass, not type 'str' 

Cualquier punteros?

No es una respuesta real, pero una solución alternativa, como lo sugiere Tom Augspurger, es que puede usar el tipo de trazado de línea de trabajo y especificar puntos en lugar de líneas:

 df.plot(x='x', y='y', style=".") 

No es una respuesta, pero no puedo editar la pregunta o poner esto en un comentario, creo.

Aquí hay un ejemplo reproducible:

 from datetime import datetime import pandas as pd df = pd.DataFrame({'x': [datetime.now() for _ in range(10)], 'y': range(10)}) df.plot(x='x', y='y', kind='scatter') 

Esto le da a KeyError: 'x' .

Curiosamente, obtienes un gráfico con solo df.plot(x='x', y='y') ; elige mal para el rango predeterminado x porque los tiempos están separados por nanosegundos, lo cual es extraño, pero ese es un problema aparte. Parece que si puedes hacer un gráfico de líneas, también deberías poder hacer un diagtwig de dispersión.

Hay un problema de pandas github sobre este problema, pero se cerró por alguna razón. Voy a ir a comentar allí para ver si podemos reiniciar esa conversación.

¿Hay alguna solución inteligente para esto? ¿Entonces qué?

basándose en la respuesta de Mike N … convierta al tiempo de Unix para dispersarse correctamente, luego transforme las tags de sus ejes de vuelta de int64s a cadenas:

 type(df.ts1[0]) 

pandas.tslib.Timestamp

 df['t1'] = df.ts1.astype(np.int64) df['t2'] = df.ts2.astype(np.int64) fig, ax = plt.subplots(figsize=(10,6)) df.plot(x='t1', y='t2', kind='scatter', ax=ax) ax.set_xticklabels([datetime.fromtimestamp(ts / 1e9).strftime('%H:%M:%S') for ts in ax.get_xticks()]) ax.set_yticklabels([datetime.fromtimestamp(ts / 1e9).strftime('%H:%M:%S') for ts in ax.get_yticks()]) plt.show() 

introduzca la descripción de la imagen aquí

Aquí hay un trabajo básico para comenzar.

 import matplotlib, datetime import matplotlib.pyplot as plt def scatter_date(df, x, y, datetimeformat): if not isinstance(y, list): y = [y] for yi in y: plt.plot_date(df[x].apply( lambda z: matplotlib.dates.date2num( datetime.datetime.strptime(z, datetimeformat))), df[yi], label=yi) plt.legend() plt.xlabel(x) # Example Usage scatter_date(data, x='date', y=['col1', 'col2'], datetimeformat='%Y-%m-%d') 

No es bonito, pero como un truco rápido puedes convertir tu DateTime en una marca de tiempo usando .timestamp() antes de cargar Pandas y las dispersiones funcionarán bien (aunque sea un eje X completamente inutilizable).