HOWTO · Matplotlib

Como traçar linhas horizontais e verticais em Matplotlib

Este tutorial apresenta como traçar linhas horizontais e verticais no Matplotlib com axhline e axvline, hlines e vlines, e as funções de sombreamento axhspan e axvspan.

Nesta página

Para traçar linhas de referência horizontais e verticais no Matplotlib, escolha axhline e axvline quando a linha deve abranger uma fração dos eixos, ou hlines e vlines quando seus extremos devem ser fixados em valores de dados. Quando o objetivo é destacar uma faixa inteira em vez de um único valor, axhspan e axvspan sombreiam a região entre duas posições. Cada exemplo salva sua figura em um arquivo PNG temporário e imprime as coordenadas do objeto que cria, para que você possa confirmar exatamente onde o Matplotlib colocou a linha ou a faixa.

axhline e axvline para traçar linhas horizontais e verticais no Matplotlib

axhline para traçar uma linha horizontal

axhline(y=...) posiciona uma linha horizontal em y nas coordenadas de dados. Seus argumentos xmin e xmax definem os extremos esquerdo e direito como frações da largura dos eixos, normalmente de 0 a 1; eles não são valores de dados de x. Por exemplo, xmin=0.1 e xmax=0.9 deixam uma margem igual a 10 % da largura dos eixos em cada extremo.

import tempfile
from pathlib import Path

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot([0, 2, 4], [1, 3, 2], marker="o")
line = ax.axhline(y=2, xmin=0.1, xmax=0.9, color="tab:red")
ax.set(xlim=(0, 4), ylim=(0, 4), xlabel="x", ylabel="y")
ax.grid(True)
print("x extent (axes fraction):", line.get_xdata())
print("y position (data):", line.get_ydata())
with tempfile.TemporaryDirectory() as directory:
    fig.savefig(Path(directory) / "plot.png")
plt.close(fig)

Saída:

x extent (axes fraction): [0.1, 0.9]
y position (data): [2, 2]

Os valores impressos confirmam a divisão: a posição é o valor de dados 2, enquanto a extensão é armazenada como as frações dos eixos 0.1 e 0.9.

Gráfico do Matplotlib com uma linha horizontal vermelha em y = 2 que abrange de 10 % a 90 % da largura dos eixos

A linha permanece no valor de dados y=2. Se você alterar os limites de x, seus extremos ainda abrangem de 10 % a 90 % da largura dos eixos, portanto o segmento se ajusta ao intervalo exibido.

axvline para traçar uma linha vertical

axvline(x=...) posiciona uma linha vertical em x nas coordenadas de dados. Seus argumentos ymin e ymax definem os extremos inferior e superior como frações da altura dos eixos, normalmente de 0 a 1. Por exemplo, ymin=0.1 e ymax=0.9 deixam uma margem igual a 10 % da altura dos eixos em cada extremo.

import tempfile
from pathlib import Path

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot([0, 2, 4], [1, 3, 2], marker="o")
line = ax.axvline(x=2, ymin=0.1, ymax=0.9, color="tab:green")
ax.set(xlim=(0, 4), ylim=(0, 4), xlabel="x", ylabel="y")
ax.grid(True)
print("x position (data):", line.get_xdata())
print("y extent (axes fraction):", line.get_ydata())
with tempfile.TemporaryDirectory() as directory:
    fig.savefig(Path(directory) / "plot.png")
plt.close(fig)

Saída:

x position (data): [2, 2]
y extent (axes fraction): [0.1, 0.9]

Aqui os valores armazenados são espelhados: a posição é o valor de dados 2, e a extensão é o par de frações dos eixos.

Gráfico do Matplotlib com uma linha vertical verde em x = 2 que abrange de 10 % a 90 % da altura dos eixos

A linha permanece no valor de dados x=2. Se você alterar os limites de y, seus extremos ainda abrangem de 10 % a 90 % da altura dos eixos. Assim, cada função ax*line combina uma posição em coordenadas de dados com uma extensão medida como fração dos eixos.

hlines e vlines para traçar linhas horizontais e verticais no Matplotlib

Use hlines e vlines quando a posição da linha e ambos os extremos devem usar coordenadas de dados. Para hlines, y fornece a altura e xmin e xmax fornecem os valores x dos extremos. Para vlines, x fornece a posição e ymin e ymax fornecem os valores y dos extremos. Alterar os limites do gráfico muda quais porções ficam visíveis, enquanto a posição e os extremos da linha em coordenadas de dados permanecem fixos. Ambas as funções retornam uma LineCollection e aceitam os argumentos de estilo usuais, portanto este exemplo também define estilos tracejado e pontilhado e adiciona uma legenda por meio do argumento label.

import tempfile
from pathlib import Path

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot([0, 2, 4], [1, 3, 2], marker="o")
horizontal = ax.hlines(y=2, xmin=1, xmax=3, color="tab:red", linestyles="--",
                       linewidth=2, label="horizontal segment")
vertical = ax.vlines(x=2, ymin=1, ymax=3, color="tab:green", linestyles=":",
                     linewidth=2, label="vertical segment")
ax.set(xlim=(0, 4), ylim=(0, 4), xlabel="x", ylabel="y")
ax.grid(True)
ax.legend(loc="upper left")
print("horizontal segment endpoints:", horizontal.get_segments()[0].tolist())
print("vertical segment endpoints:", vertical.get_segments()[0].tolist())
with tempfile.TemporaryDirectory() as directory:
    fig.savefig(Path(directory) / "plot.png")
plt.close(fig)

Saída:

horizontal segment endpoints: [[1.0, 2.0], [3.0, 2.0]]
vertical segment endpoints: [[2.0, 1.0], [2.0, 3.0]]

Os extremos impressos são coordenadas de dados puras: o segmento horizontal vai de (1, 2) a (3, 2), e o segmento vertical vai de (2, 1) a (2, 3).

Gráfico do Matplotlib com um segmento horizontal vermelho tracejado em y = 2 de x = 1 a x = 3 e um segmento vertical verde pontilhado em x = 2 de y = 1 a y = 3, identificados por uma legenda

Como todos os quatro extremos usam coordenadas de dados, aplicar zoom ou alterar os limites muda a porção visível de cada segmento em vez de redimensionar seus extremos para corresponder a uma fração dos eixos.

axhspan e axvspan para sombrear uma região no Matplotlib

Quando uma única linha não é suficiente, sombreie a região entre dois valores. axhspan(ymin, ymax) preenche uma faixa horizontal entre dois valores de dados de y em toda a largura dos eixos, e axvspan(xmin, xmax) preenche uma faixa vertical entre dois valores de dados de x em toda a altura. Use-as para marcar um intervalo aceitável, uma zona-alvo ou um período de interesse atrás dos seus dados. Ambas as funções retornam um patch Rectangle.

import tempfile
from pathlib import Path

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot([0, 2, 4], [1, 3, 2], marker="o")
band_y = ax.axhspan(ymin=1.5, ymax=2.5, color="tab:orange", alpha=0.3,
                    label="y between 1.5 and 2.5")
band_x = ax.axvspan(xmin=1.5, xmax=2.5, color="tab:blue", alpha=0.15,
                    label="x between 1.5 and 2.5")
ax.set(xlim=(0, 4), ylim=(0, 4), xlabel="x", ylabel="y")
ax.grid(True)
ax.legend(loc="upper left")
print("horizontal band y range:", band_y.get_y(), "to", band_y.get_y() + band_y.get_height())
print("vertical band x range:", band_x.get_x(), "to", band_x.get_x() + band_x.get_width())
with tempfile.TemporaryDirectory() as directory:
    fig.savefig(Path(directory) / "plot.png")
plt.close(fig)

Saída:

horizontal band y range: 1.5 to 2.5
vertical band x range: 1.5 to 2.5

Gráfico do Matplotlib com uma faixa horizontal laranja entre y = 1,5 e y = 2,5 e uma faixa vertical azul entre x = 1,5 e x = 2,5, identificadas por uma legenda

As bordas da faixa sempre usam coordenadas de dados. Como axhline, as funções de span também aceitam argumentos de fração para a direção transversal — axhspan aceita xmin e xmax como frações dos eixos para limitar a largura da faixa, e axvspan aceita ymin e ymax — mas uma faixa desenhada dessa forma ainda começa e termina em valores de dados.

Por que uma linha horizontal ou vertical pode não aparecer no Matplotlib

Duas verificações explicam quase todos os relatos de linhas ausentes. A primeira é um erro de tipo: os argumentos de fração de axhline e axvline devem ser números. Passá-los como strings — um acidente comum quando os valores vêm de um formulário, um arquivo CSV ou uma entrada de configuração — gera um ValueError antes que qualquer coisa seja desenhada:

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot([0, 2, 4], [1, 3, 2], marker="o")
ax.axhline(y=2, xmin="0.1", xmax="0.9", color="tab:red")
plt.close(fig)

Saída:

ValueError: xmin must be a single scalar value, but got 0.1

Converta primeiro os valores para números, por exemplo com float(...), e a mesma chamada funciona: o primeiro exemplo deste artigo é exatamente essa chamada com frações numéricas.

A segunda verificação é o intervalo visível. Uma linha é criada em coordenadas de dados mesmo quando sua posição está fora dos limites atuais dos eixos, portanto ela existe na figura, mas fica recortada da vista:

import tempfile
from pathlib import Path

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot([0, 2, 4], [1, 3, 2], marker="o")
line = ax.axhline(y=20, color="tab:red")
ax.set(xlim=(0, 4), ylim=(0, 4), xlabel="x", ylabel="y")
ax.grid(True)
print("line y position:", line.get_ydata())
print("axes y limits:", tuple(float(v) for v in ax.get_ylim()))
with tempfile.TemporaryDirectory() as directory:
    fig.savefig(Path(directory) / "plot.png")
plt.close(fig)

Saída:

line y position: [20, 20]
axes y limits: (0.0, 4.0)

A linha está em y=20 enquanto os eixos param em 4.0. Estenda os limites para incluir a posição — ou corrija o valor se 20 foi um erro — e a linha aparece. A mesma verificação se aplica aos extremos de hlines e vlines e às bordas de span que caem fora dos limites.

Conclusão sobre como traçar linhas horizontais e verticais no Matplotlib

Escolha axhline ou axvline quando a posição for um valor de dados, mas a extensão da linha deve acompanhar uma fração dos eixos. Escolha hlines ou vlines quando a posição e ambos os extremos devem permanecer em valores de dados, e use axhspan ou axvspan quando uma faixa inteira entre dois valores precisa de destaque em vez de uma única linha. Essa escolha de coordenadas determina quanto de uma linha fica visível depois que você altera os limites do gráfico — e comparar as coordenadas armazenadas com os limites dos eixos explica qualquer linha que pareça estar faltando.