Cómo usar la escala logarítmica con diagramas de pandas

2 minutos de lectura

Avatar de usuario de TristanMatthews
TristanMatthews

Estoy haciendo un histograma bastante simple con pandas usando

results.val1.hist(bins=120)

que funciona bien, pero realmente quiero tener una escala logarítmica en el eje y, que normalmente (probablemente incorrectamente) hago así:

fig = plt.figure(figsize=(12,8))
ax = fig.add_subplot(111)
plt.plot(np.random.rand(100))
ax.set_yscale('log')
plt.show()

Si reemplazo el plt comando con el comando pandas, entonces tengo:

fig = plt.figure(figsize=(12,8))
ax = fig.add_subplot(111)
results.val1.hist(bins=120)
ax.set_yscale('log')
plt.show()

da como resultado muchas copias del mismo error:

Jan  9 15:53:07 BLARG.local python[6917] <Error>: CGContextClosePath: no current point.

Obtengo un histograma de escala logarítmica, pero solo tiene las líneas superiores de las barras, pero no tiene barras verticales ni colores. ¿Estoy haciendo algo terriblemente mal o esto simplemente no es compatible con los pandas?

Del código de Paul H agregué bottom=0.1 a hist call soluciona el problema, supongo que hay algún tipo de división por cero, o algo así.

Avatar de usuario de Jean Pouget-Abadie
Jean Pouget-Abadie

Yo recomendaría usar el log=True parámetro en la función pyplot hist:

Paso de configuración

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt  

df = pd.DataFrame({'column_name': np.random.normal(size=2000)})

Usando pyplot:

plt.hist(df['column_name'], log=True)

ingrese la descripción de la imagen aquí

O de manera equivalente, podrías usar el plot método de la columna del marco de datos (serie) directamente:

df["column_name"].plot(kind="hist", logy=True)

También hay logx para escalar logarítmicamente el eje x y loglog=True para escalar logarítmicamente en ambos ejes.

Difícil de diagnosticar sin ningún dato. Lo siguiente funciona para mí:

import numpy as np
import matplotlib.pyplot as plt
import pandas
series = pandas.Series(np.random.normal(size=2000))
fig, ax = plt.subplots()
series.hist(ax=ax, bins=100, bottom=0.1)
ax.set_yscale('log')

ingrese la descripción de la imagen aquí

La clave aquí es que pases ax a la función de histograma y se especifica el bottom ya que no hay valor cero en una escala logarítmica.

La solución de Jean PA es la más simple y correcta para esta pregunta. Escribo esto como respuesta ya que no tengo el representante para comentar.

Para construir un histograma directamente desde pandas, algunos de los argumentos se pasan al método matplotlib.hist de todos modos, así que:

results.val1.hist(bins = 120, log = True)

Produciría lo que necesita.

¿Ha sido útil esta solución?