Trazar ejes logarítmicos con matplotlib en python

369

Quiero trazar un gráfico con un eje logarítmico usando matplotlib.

He estado leyendo los documentos, pero no puedo entender la sintaxis. Sé que probablemente sea algo simple como 'scale=linear'en los argumentos de la trama, pero parece que no puedo hacerlo bien

Programa de muestra:

import pylab
import matplotlib.pyplot as plt
a = [pow(10, i) for i in range(10)]
fig = plt.figure()
ax = fig.add_subplot(2, 1, 1)

line, = ax.plot(a, color='blue', lw=2)
pylab.show()
Max Ghenis
fuente

Respuestas:

384

Puedes usar el Axes.set_yscalemétodo. Eso le permite cambiar la escala después de Axescrear el objeto. Eso también le permitiría crear un control para permitir al usuario elegir la escala si fuera necesario.

La línea relevante para agregar es:

ax.set_yscale('log')

Puede usar 'linear'para volver a una escala lineal. Así es como se vería su código:

import pylab
import matplotlib.pyplot as plt
a = [pow(10, i) for i in range(10)]
fig = plt.figure()
ax = fig.add_subplot(2, 1, 1)

line, = ax.plot(a, color='blue', lw=2)

ax.set_yscale('log')

pylab.show()

tabla de resultados

Mathieu
fuente
66
Este método es bueno ya que funciona con todo tipo de gráficos (por ejemplo, histogramas), no solo con "plot" (que es lo que hace semilogx / semilogy)
Tim Whitcomb
16
Vine aquí buscando cómo usar un eje para potencias de dos: pylab.gca (). Set_xscale ('log', basex = 2)
zje
53
Matplotlib tiene semilogy(). Además, es más fácil de usar directamente pyplot.yscale()que de usar ax.set_yscale('log'), ya que no es necesario obtener el axobjeto (que no siempre está disponible de inmediato).
Eric O Lebigot
55
Si desea escalas logarítmicas en ambos ejes, intente loglog()o solo en el eje x intentesemilogx()
drevicko
10
@EOL yo recomendaría lo contrario. Es mejor usar un axobjeto explícito que usar pyplotque solo podría aplicarse a los ejes que desea.
tacaswell
288

En primer lugar, no es muy ordenado mezclar pylaby pyplotcodificar. Además, se prefiere el estilo pyplot sobre el uso de pylab .

Aquí hay un código ligeramente limpio, que usa solo pyplotfunciones:

from matplotlib import pyplot

a = [ pow(10,i) for i in range(10) ]

pyplot.subplot(2,1,1)
pyplot.plot(a, color='blue', lw=2)
pyplot.yscale('log')
pyplot.show()

La función relevante es pyplot.yscale(). Si usa la versión orientada a objetos, reemplácela por el método Axes.set_yscale(). Recuerde que también puede cambiar la escala del eje X, usando pyplot.xscale()(o Axes.set_xscale()).

Verifique mi pregunta ¿Cuál es la diferencia entre 'log' y 'symlog'? para ver algunos ejemplos de las escalas gráficas que ofrece matplotlib.

Denilson Sá Maia
fuente
Tuve dificultades para tratar de descubrir cómo hacerlo. ¡Esta respuesta me salvó el día!
HWende
13
pyplot.semilogy()Es más directo.
Eric O Lebigot
64

Simplemente necesita usar la semilogía en lugar de la trama:

from pylab import *
import matplotlib.pyplot  as pyplot
a = [ pow(10,i) for i in range(10) ]
fig = pyplot.figure()
ax = fig.add_subplot(2,1,1)

line, = ax.semilogy(a, color='blue', lw=2)
show()
Scott McCammon
fuente
1
LOL, estaba tratando de iniciar sesión (FloatArray) para wholetime, gracias me salvaste el día
Pradeep
55
También hay semilogx . Si necesita iniciar sesión en ambos ejes, use loglog
drevicko
40

Si desea cambiar la base del logaritmo, simplemente agregue:

plt.yscale('log',basey=2) 
# where basex or basey are the bases of log
Dawid
fuente
8

Sé que esto está un poco fuera de tema, ya que algunos comentarios mencionaron ax.set_yscale('log')que es la solución "más agradable", pensé que podría deberse una refutación. No recomendaría usar ax.set_yscale('log')para histogramas y gráficos de barras. En mi versión (0.99.1.1) me encuentro con algunos problemas de representación, no estoy seguro de cuán general es este problema. Sin embargo, tanto bar como hist tienen argumentos opcionales para establecer que la escala y se registre, lo que funciona bien.

referencias: http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.bar

http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.hist

usuario3465408
fuente
5

Entonces, si simplemente está utilizando la API poco sofisticada, como lo hago a menudo (lo uso mucho en ipython), entonces esto es simplemente

yscale('log')
plot(...)

¡Espero que esto ayude a alguien que busca una respuesta simple! :).

crazy2be
fuente
-1

Puedes usar el siguiente código:

np.log(df['col_whose_log_you_need']).iplot(kind='histogram', bins=100,
                                   xTitle = 'log of col',yTitle ='Count corresponding to column',
                                   title='Distribution of log(col_whose_log_you_need)')
Shailaja Gupta Kapoor
fuente