Ticks e formatters no Matplotlib: deixe os eixos legíveis
Updated on
Ticks apertados, datas sobrepostas e números sem arredondar criam ruído. Quando os ticks aparecem ao acaso, o contexto some. A solução é clara: definir locators (onde ficam os ticks) e formatters (como são mostrados) para que cada eixo conte a história sem distração.
Locator vs formatter em resumo
| Tarefa | Ferramenta | Exemplo |
|---|---|---|
| Espaço fixo por passo | MultipleLocator | A cada 5 unidades em x |
| Limitar quantidade | MaxNLocator | Até 6 ticks em y |
| Datas | AutoDateLocator | Meses/anos automáticos |
| Rótulos customizados | FuncFormatter | Acrescentar unidades/sufixos |
| Rotacionar rótulos | tick_params(rotation=...) | 45° em datas densas |
Eixos numéricos: espaçar e formatar
import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator, FuncFormatter
import numpy as np
x = np.linspace(0, 50, 200)
y = np.log1p(x) * 3.2
fig, ax = plt.subplots(figsize=(7, 4))
ax.plot(x, y, color="tab:blue")
# Ticks de 10 em 10 no x, de 1.5 em 1.5 no y
ax.xaxis.set_major_locator(MultipleLocator(10))
ax.yaxis.set_major_locator(MultipleLocator(1.5))
# Rótulo com unidade
ax.yaxis.set_major_formatter(FuncFormatter(lambda val, _: f"{val:.1f} dB"))
ax.set_xlabel("Samples")
ax.set_ylabel("Signal (dB)")
ax.grid(True, axis="both", linestyle="--", alpha=0.3)
plt.tight_layout()
plt.show()Dicas:
MaxNLocator(nbins=6)mantém o eixo limpo mesmo quando o range muda.- Formatter só altera o texto, não a posição dos ticks.
- Coloque a unidade no label ou no formatter, não nos dois.
Datas: evite sobreposição
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import pandas as pd
dates = pd.date_range("2024-01-01", periods=120, freq="D")
values = pd.Series(range(len(dates))).rolling(7, min_periods=1).mean()
fig, ax = plt.subplots(figsize=(8, 4))
ax.plot(dates, values, color="tab:green")
ax.xaxis.set_major_locator(mdates.MonthLocator(interval=1))
ax.xaxis.set_major_formatter(mdates.DateFormatter("%b %Y"))
ax.xaxis.set_minor_locator(mdates.WeekdayLocator(byweekday=mdates.MO, interval=2))
plt.setp(ax.get_xticklabels(), rotation=30, ha="right")
ax.set_ylabel("Média 7 dias")
ax.grid(True, which="both", axis="x", linestyle=":", alpha=0.4)
plt.tight_layout()
plt.show()Dicas:
- Minor locators (ex.: semanal) dão contexto sem poluir os rótulos.
- Rode datas 30–45° com
ha="right"para evitar sobreposição. - Se o intervalo muda muito,
AutoDateLocator+ConciseDateFormatterse ajustam sozinhos.
Eixos duplos: alinhe cada um
Com twinx/secondary_yaxis, defina locators e formatters em cada eixo para manter cores, ticks e unidades coerentes. Alinhe a legenda como na guia de eixo secundário.
Checklist rápido
- Saltos estranhos? Defina um locator determinístico (
MultipleLocator). - Rótulos cortados?
constrained_layout=Trueouplt.tight_layout(). - Ticks demais? Reduza para
MaxNLocator(nbins=5)ou esconda os minor (`ax.tick_params(which="minor", length=0)").