HOWTO · Matplotlib

Como plotar eixos logarítmicos em Matplotlib

Trace eixos logarítmicos no Matplotlib usando set_yscale(), semilogy() ou loglog().

Nesta página

Use set_xscale() ou set_yscale() para escolher a escala de cada eixo de forma independente. Para usar uma escala logarítmica nos dois eixos, use loglog(). Os auxiliares semilogx() e semilogy() aplicam uma escala logarítmica ao eixo x ou ao eixo y, respectivamente. Um eixo logarítmico espaça suas marcações em potências de dez, de modo que dados que abrangem várias ordens de grandeza permanecem legíveis, em vez de se aglomerarem na década mais baixa de um eixo linear.
Todos os exemplos de código abaixo foram executados com sucesso.

Funções set_xscale() ou set_yscale()

Chame set_xscale("log") para aplicar uma escala logarítmica ao eixo x e set_yscale("log") para aplicá-la ao eixo y; use ambos para escalar os dois eixos. Como as duas chamadas são independentes, você pode converter exatamente um eixo e deixar o outro linear.

Para tornar apenas o eixo x logarítmico, represente os dados normalmente e depois chame set_xscale("log") nos eixos:

import matplotlib.pyplot as plt

x = [1, 10, 100, 1000]
y = [2, 5, 20, 80]

fig, ax = plt.subplots()
ax.plot(x, y, marker="o")
ax.set_xscale("log")
ax.set_xlabel("x")
ax.set_ylabel("y")
print(f"x-axis: {ax.get_xscale()}, y-axis: {ax.get_yscale()}")
plt.close(fig)

O resultado impresso confirma que apenas o eixo x mudou: x-axis: log, y-axis: linear. As marcações de década em 1, 10, 100 e 1000 estão espaçadas uniformemente, embora os próprios valores cresçam por um fator de dez.

Gráfico de linhas com um eixo x logarítmico e um eixo y linear, criado com set_xscale

Para tornar apenas o eixo y logarítmico, chame set_yscale("log") e deixe o eixo x sem alterações:

import matplotlib.pyplot as plt

x = [1, 10, 100, 1000]
y = [2, 5, 20, 80]

fig, ax = plt.subplots()
ax.plot(x, y, marker="o")
ax.set_yscale("log")
ax.set_xlabel("x")
ax.set_ylabel("y")
print(f"x-axis: {ax.get_xscale()}, y-axis: {ax.get_yscale()}")
plt.close(fig)

Desta vez, a saída é x-axis: linear, y-axis: log, e é o eixo y que recebe as marcações de década uniformemente espaçadas.

Gráfico de linhas com um eixo x linear e um eixo y logarítmico, criado com set_yscale

A interface de máquina de estados do pyplot oferece a mesma alteração por meio das funções de nível superior plt.xscale() e plt.yscale(), que atuam nos eixos atuais. A variante com yscale() do mesmo gráfico é a seguinte:

import matplotlib.pyplot as plt

x = [1, 10, 100, 1000]
y = [2, 5, 20, 80]

plt.plot(x, y, marker="o")
plt.yscale("log")
plt.xlabel("x")
plt.ylabel("y")
ax = plt.gca()
print(f"x-axis: {ax.get_xscale()}, y-axis: {ax.get_yscale()}")
plt.close()

O resultado é o mesmo eixo y logarítmico; os métodos do objeto de eixos costumam ser mais claros em programas que mantêm uma referência ax explícita, porque os eixos de destino são nomeados na chamada, em vez de serem implícitos a partir da figura atual.

Gráfico de linhas com um eixo y logarítmico, criado com a função yscale do pyplot

Este exemplo completo representa dados numéricos positivos e define escalas logarítmicas para os dois eixos.

import matplotlib.pyplot as plt

x = [1, 10, 100, 1000]
y = [2, 5, 20, 80]

fig, ax = plt.subplots()
ax.plot(x, y, marker="o")
ax.set_xscale("log")
ax.set_yscale("log")
ax.set_xlabel("x")
ax.set_ylabel("y")
print(f"x-axis: {ax.get_xscale()}, y-axis: {ax.get_yscale()}")
plt.close(fig)

Agora a saída indica x-axis: log, y-axis: log, e proporções iguais ocupam distâncias iguais nos dois eixos.

Gráfico de linhas com escalas logarítmicas nos dois eixos, criado com set_xscale e set_yscale

Uma escala log padrão representa valores positivos. Se os seus dados incluírem valores com sinais diferentes, use symlog no eixo correspondente, por exemplo, ax.set_yscale("symlog"); ela pode exibir valores dos dois lados de zero. A última seção retoma esse caso com um exemplo verificado.

Funções semilogx() ou semilogy()

Use semilogx() quando quiser uma escala logarítmica no eixo x e uma escala linear no eixo y. Use semilogy() para aplicar uma escala logarítmica ao eixo y e manter o eixo x linear. Ambos os auxiliares recebem os dados de x e y como argumentos, deixando explícita a escala escolhida na chamada de plotagem. Se quiser uma escala logarítmica nos dois eixos, use loglog() ou combine semilogx() e semilogy() nos mesmos eixos.

A chamada semilogx() abaixo representa os dados e define o eixo x logarítmico em uma única etapa:

import matplotlib.pyplot as plt

x = [1, 10, 100, 1000]
y = [2, 5, 20, 80]

fig, ax = plt.subplots()
ax.semilogx(x, y, marker="o", label="logarithmic x")
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.legend()
print(f"x-axis: {ax.get_xscale()}, y-axis: {ax.get_yscale()}")
plt.close(fig)

O auxiliar retorna a linha representada, e os eixos indicam depois x-axis: log, y-axis: linear, exatamente como na chamada explícita set_xscale("log") da primeira seção.

Gráfico de linhas com um eixo x logarítmico e um eixo y linear, criado com semilogx

Combinar os dois auxiliares nos mesmos eixos produz uma escala logarítmica nos dois eixos. Lembre-se de que uma escala pertence aos eixos, e não a uma única linha representada: assim que semilogy() define o eixo y, essa escala se aplica a todas as séries contidas nos eixos, inclusive à desenhada antes por semilogx().

import matplotlib.pyplot as plt

x = [1, 10, 100, 1000]
y = [2, 5, 20, 80]
y2 = [3, 8, 30, 120]

fig, ax = plt.subplots()
ax.semilogx(x, y, marker="o", label="first series")
ax.semilogy(x, y2, marker="s", label="second series")
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.legend()
print(f"x-axis: {ax.get_xscale()}, y-axis: {ax.get_yscale()}")
plt.close(fig)

As duas séries terminam em eixos x e y logarítmicos, e a saída confirma o estado final: x-axis: log, y-axis: log.

Duas séries de linhas compartilhando eixos x e y logarítmicos, criadas combinando semilogx e semilogy

Função loglog()

Use loglog() quando precisar de escalas logarítmicas nos dois eixos. A função representa os dados de x e y fornecidos e define a escala logarítmica padrão para ambos os eixos. Veja um exemplo completo com valores numéricos positivos:

import matplotlib.pyplot as plt

x = [1, 10, 100, 1000]
y = [2, 5, 20, 80]

fig, ax = plt.subplots()
ax.loglog(x, y, marker="o")
ax.set_xlabel("x")
ax.set_ylabel("y")
print(f"x-axis: {ax.get_xscale()}, y-axis: {ax.get_yscale()}")
plt.close(fig)

O resultado renderizado corresponde à combinação de set_xscale("log") com set_yscale("log") da primeira seção; loglog() simplesmente incorpora a escolha da escala à própria chamada de plotagem.

Gráfico de linhas com escalas logarítmicas nos dois eixos, criado com loglog

Valores não positivos e nomes de escala inválidos

Duas coisas surpreendem regularmente quem usa eixos logarítmicos, e vale a pena conhecer ambas antes de depurar um gráfico com aparência errada. Primeiro, o nome da escala é validado imediatamente: um erro de digitação como ax.set_yscale("logg") levanta ValueError: 'logg' is not a valid value for scale. Did you mean one of: 'log', 'logit', 'symlog'? (mensagem capturada literalmente no Matplotlib 3.11). O erro indica os valores aceitos, de modo que um erro de digitação falha de imediato, em vez de produzir silenciosamente um eixo linear.

Segundo, uma escala logarítmica não pode representar zero nem valores negativos, e esse caso não levanta erro algum. O Matplotlib descarta silenciosamente os pontos não positivos: eles são mascarados para fora do desenho, os segmentos de linha que passariam por eles desaparecem, e os limites do eixo cobrem apenas os valores positivos. O exemplo abaixo representa y = [2, 0, -5, 80] em um eixo y logarítmico:

import matplotlib.pyplot as plt

x = [1, 10, 100, 1000]
y = [2, 0, -5, 80]

fig, ax = plt.subplots()
ax.plot(x, y, marker="o")
ax.set_yscale("log")
ax.set_xlabel("x")
ax.set_ylabel("y")
print(f"x-axis: {ax.get_xscale()}, y-axis: {ax.get_yscale()}")
plt.close(fig)

A chamada é concluída normalmente e indica y-axis: log, mas apenas os pontos em y = 2 e y = 80 podem aparecer; na execução verificada, os limites resultantes do eixo y foram de aproximadamente 1,66 a 96,2, abrangendo apenas os dados positivos. Se uma série parecer perder pontos depois que você muda um eixo para log, verifique se há zeros e valores negativos nos dados antes de suspeitar do código de plotagem.

Quando os dados realmente contêm valores com sinais, a escala symlog (logaritmo simétrico) é a alternativa adequada: ela aplica uma escala logarítmica longe de zero e uma escala linear em uma pequena região ao redor de zero, de modo que todos os pontos permanecem visíveis.

import matplotlib.pyplot as plt

x = [1, 10, 100, 1000]
y = [2, 0, -5, 80]

fig, ax = plt.subplots()
ax.plot(x, y, marker="o")
ax.set_yscale("symlog")
ax.set_xlabel("x")
ax.set_ylabel("y")
print(f"x-axis: {ax.get_xscale()}, y-axis: {ax.get_yscale()}")
plt.close(fig)

Todos os quatro pontos, incluindo 0 e -5, são representados no eixo y symlog. Use-a sempre que o sinal dos valores carregar informação; mantenha a escala log simples para dados positivos por natureza, como contagens, tamanhos e medições físicas.