Pandas: Bar-Plot con dos barras y dos ejes y

Tengo un DataFrame con este aspecto:

amount price age A 40929 4066443 B 93904 9611272 C 188349 19360005 D 248438 24335536 E 205622 18888604 F 140173 12580900 G 76243 6751731 H 36859 3418329 I 29304 2758928 J 39768 3201269 K 30350 2867059 

Ahora me gustaría trazar un diagtwig de barras con la edad en el eje x como tags. Para cada x-tick debe haber dos barras, una barra para la cantidad y una para el precio. Puedo hacer que esto funcione simplemente usando:

 df.plot(kind='bar') 

El problema es la escalada. Los precios son mucho más altos que realmente no puedo identificar la cantidad en ese gráfico, consulte:

introduzca la descripción de la imagen aquí

Así me gustaría un segundo eje y. Lo probé usando:

 df.loc[:,'amount'].plot(kind='bar') df.loc[:,'price'].plot(kind='bar',secondary_y=True) 

pero esto solo sobrescribe las barras y NO las coloca lado a lado. ¿Hay alguna forma de hacer esto sin tener que acceder a matplotlib de nivel inferior (lo cual sería posible, obviamente, colocando las barras lado a lado manualmente)?

Por ahora, estoy usando dos gráficas individuales dentro de las subplots:

 df.plot(kind='bar',grid=True,subplots=True,sharex=True); 

Resultando en:

introduzca la descripción de la imagen aquí

Usando la nueva versión de pandas (0.14.0 o posterior), funcionará el siguiente código. Para crear los dos ejes, he creado manualmente dos objetos de ejes de matplotlib ( ax y ax2 ) que servirán para ambos gráficos de barras.

Al trazar un Dataframe, puede elegir el objeto de los ejes utilizando ax=... También para evitar que las dos gráficas se superpongan, he modificado el lugar donde se alinean con el argumento de la palabra clave de position , este valor predeterminado es 0.5 pero eso significaría que las dos gráficas de barra se superponen.

 import matplotlib.pyplot as plt import numpy as np import pandas as pd from io import StringIO s = StringIO(""" amount price A 40929 4066443 B 93904 9611272 C 188349 19360005 D 248438 24335536 E 205622 18888604 F 140173 12580900 G 76243 6751731 H 36859 3418329 I 29304 2758928 J 39768 3201269 K 30350 2867059""") df = pd.read_csv(s, index_col=0, delimiter=' ', skipinitialspace=True) fig = plt.figure() # Create matplotlib figure ax = fig.add_subplot(111) # Create matplotlib axes ax2 = ax.twinx() # Create another axes that shares the same x-axis as ax. width = 0.4 df.amount.plot(kind='bar', color='red', ax=ax, width=width, position=1) df.price.plot(kind='bar', color='blue', ax=ax2, width=width, position=0) ax.set_ylabel('Amount') ax2.set_ylabel('Price') plt.show() 

Trama

Solo necesita escribir: df.plot (kind = ‘bar’ , secondary_y = ‘amount’ )

 import matplotlib.pyplot as plt import numpy as np import pandas as pd from io import StringIO s = StringIO(""" amount price A 40929 4066443 B 93904 9611272 C 188349 19360005 D 248438 24335536 E 205622 18888604 F 140173 12580900 G 76243 6751731 H 36859 3418329 I 29304 2758928 J 39768 3201269 K 30350 2867059""") df = pd.read_csv(s, index_col=0, delimiter=' ', skipinitialspace=True) _ = df.plot( kind= 'bar' , secondary_y= 'amount' , rot= 0 ) plt.show() 

Secondary_Y_axis

Aquí hay otro método:

  • Crea todas las barras en los ejes izquierdos.
  • mueva algunas barras a los ejes de la derecha cambiando su atributo de transform

Aquí está el código:

 import pylab as pl df = pd.DataFrame(np.random.rand(10, 2), columns=["left", "right"]) df["left"] *= 100 ax = df.plot(kind="bar") ax2 = ax.twinx() for r in ax.patches[len(df):]: r.set_transform(ax2.transData) ax2.set_ylim(0, 2); 

Aquí está la salida:

introduzca la descripción de la imagen aquí