xticks xtick ticks python pandas matplotlib

xtick - plot python 3



Matplotlib que muestra las etiquetas x-tick superpuestas a pesar de los mejores esfuerzos (2)

Debido a la forma en que se maneja la representación del texto en matplotlib, la detección automática de texto superpuesto realmente ralentiza las cosas. (El espacio que ocupa el texto no puede calcularse con precisión hasta que se haya dibujado). Por esa razón, matplotlib no intenta hacerlo automáticamente.

Por lo tanto, es mejor rotar las etiquetas largas. Debido a que las fechas suelen tener este problema, hay un método de figura fig.autofmt_xdate() que (entre otras cosas) rotará las etiquetas de tic para que sean un poco más legibles. (Nota: si está utilizando un método de plot pandas, devuelve un objeto de ejes, por lo que deberá usar ax.figure.autofmt_xdate() .

Como un ejemplo rápido:

import numpy as np import pandas as pd import matplotlib.pyplot as plt time = pd.date_range(''01/01/2014'', ''4/01/2014'', freq=''H'') values = np.random.normal(0, 1, time.size).cumsum() fig, ax = plt.subplots() ax.plot_date(time, values, marker='''', linestyle=''-'') fig.autofmt_xdate() plt.show()

Si tuviéramos que dejar fig.autofmt_xdate() out:

Y si usamos fig.autofmt_xdate() :

Echa un vistazo a la gráfica de abajo:

Es un argumento secundario de esta figura más grande:

Veo dos problemas con ello. Primero, las etiquetas del eje x se superponen unas con otras (este es mi principal problema). Segundo. la ubicación de las líneas de cuadrícula menores del eje x parece un poco torpe. A la izquierda del gráfico, se ven correctamente espaciados. Pero a la derecha, parecen estar atestando las principales líneas de cuadrícula ... como si las principales ubicaciones de la línea de cuadrícula no fueran múltiplos adecuados de las ubicaciones menores de tick.

Mi configuración es que tengo un DataFrame llamado df que tiene un Indice de fecha y hora en las filas y una columna llamada value que contiene flotantes. Puedo proporcionar un ejemplo de los contenidos df en un gist si es necesario. Una docena o más de líneas de df están al final de esta publicación para referencia.

Aquí está el código que produce la figura:

now = dt.datetime.now() fig, axes = plt.subplots(2, 2, figsize=(15, 8), dpi=200) for i, d in enumerate([360, 30, 7, 1]): ax = axes.flatten()[i] earlycut = now - relativedelta(days=d) data = df.loc[df.index>=earlycut, :] ax.plot(data.index, data[''value'']) ax.xaxis_date() ax.get_xaxis().set_minor_locator(mpl.ticker.AutoMinorLocator()) ax.get_yaxis().set_minor_locator(mpl.ticker.AutoMinorLocator()) ax.grid(b=True, which=''major'', color=''w'', linewidth=1.5) ax.grid(b=True, which=''minor'', color=''w'', linewidth=0.75)

¿Cuál es mi mejor opción aquí para que las etiquetas del eje x dejen de superponerse entre sí (en cada una de las cuatro subparcelas)? Además, por separado (pero con menos urgencia), ¿qué pasa con el problema de la marca menor en la subparcela superior izquierda?

Estoy en Pandas 0.13.1, numpy 1.8.0 y matplotlib 1.4.x.

Aquí hay un pequeño fragmento de df para referencia:

id scale tempseries_id value timestamp 2014-11-02 14:45:10.302204+00:00 7564 F 1 68.0000 2014-11-02 14:25:13.532391+00:00 7563 F 1 68.5616 2014-11-02 14:15:12.102229+00:00 7562 F 1 68.9000 2014-11-02 14:05:13.252371+00:00 7561 F 1 69.0116 2014-11-02 13:55:11.792191+00:00 7560 F 1 68.7866 2014-11-02 13:45:10.782227+00:00 7559 F 1 68.6750 2014-11-02 13:35:10.972248+00:00 7558 F 1 68.4500 2014-11-02 13:25:10.362213+00:00 7557 F 1 68.1116 2014-11-02 13:15:10.822247+00:00 7556 F 1 68.2250 2014-11-02 13:05:10.102200+00:00 7555 F 1 68.5616 2014-11-02 12:55:10.292217+00:00 7554 F 1 69.0116 2014-11-02 12:45:10.382226+00:00 7553 F 1 69.3500 2014-11-02 12:35:10.642245+00:00 7552 F 1 69.2366 2014-11-02 12:25:12.642255+00:00 7551 F 1 69.1250 2014-11-02 12:15:11.122382+00:00 7550 F 1 68.7866 2014-11-02 12:05:11.332224+00:00 7549 F 1 68.5616 2014-11-02 11:55:11.662311+00:00 7548 F 1 68.2250 2014-11-02 11:45:11.122193+00:00 7547 F 1 68.4500 2014-11-02 11:35:11.162271+00:00 7546 F 1 68.7866 2014-11-02 11:25:12.102211+00:00 7545 F 1 69.2366 2014-11-02 11:15:10.422226+00:00 7544 F 1 69.4616 2014-11-02 11:05:11.412216+00:00 7543 F 1 69.3500 2014-11-02 10:55:10.772212+00:00 7542 F 1 69.1250 2014-11-02 10:45:11.332220+00:00 7541 F 1 68.7866 2014-11-02 10:35:11.332232+00:00 7540 F 1 68.5616 2014-11-02 10:25:11.202411+00:00 7539 F 1 68.2250 2014-11-02 10:15:11.932326+00:00 7538 F 1 68.5616 2014-11-02 10:05:10.922229+00:00 7537 F 1 68.9000 2014-11-02 09:55:11.602357+00:00 7536 F 1 69.3500

Edit: Trying fig.autofmt_xdate() : No creo que esto vaya a hacer el truco. Esto parece utilizar las mismas etiquetas de marca x para ambos gráficos de la izquierda y también para los dos gráficos de la derecha. Lo cual no es correcto dados mis datos. Por favor vea la salida problemática a continuación:


Ok, finalmente lo tengo funcionando. El truco fue usar plt.setp para rotar manualmente las etiquetas de tick. El uso de fig.autofmt_xdate() no funcionó, ya que hace algunas cosas inesperadas cuando tienes varias subparcelas en tu figura. Aquí está el código de trabajo con su salida:

for i, d in enumerate([360, 30, 7, 1]): ax = axes.flatten()[i] earlycut = now - relativedelta(days=d) data = df.loc[df.index>=earlycut, :] ax.plot(data.index, data[''value'']) ax.get_xaxis().set_minor_locator(mpl.ticker.AutoMinorLocator()) ax.get_yaxis().set_minor_locator(mpl.ticker.AutoMinorLocator()) ax.grid(b=True, which=''major'', color=''w'', linewidth=1.5) ax.grid(b=True, which=''minor'', color=''w'', linewidth=0.75) plt.setp(ax.get_xticklabels(), rotation=30, horizontalalignment=''right'') fig.tight_layout()

Por cierto, el comentario anterior sobre algunas cosas de matplotlib que tardan una eternidad es muy interesante aquí. Estoy usando una pi de frambuesa para actuar como una estación meteorológica en una ubicación remota. Es recoger los datos y servir los resultados a través de la web. Y chico, oh chico, es realmente sibilancias tratar de poner estos gráficos.