Skip to content

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

TarefaFerramentaExemplo
Espaço fixo por passoMultipleLocatorA cada 5 unidades em x
Limitar quantidadeMaxNLocatorAté 6 ticks em y
DatasAutoDateLocatorMeses/anos automáticos
Rótulos customizadosFuncFormatterAcrescentar unidades/sufixos
Rotacionar rótulostick_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 + ConciseDateFormatter se 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=True ou plt.tight_layout().
  • Ticks demais? Reduza para MaxNLocator(nbins=5) ou esconda os minor (`ax.tick_params(which="minor", length=0)").