Azimlib0.3.0 · documentation

GridSpec, proporções e painéis com spans

Outputs under gallery/ are local generated previews, not distributed assets. For versioned current images, see the 0.3 gallery.

GridSpec próprio separa a alocação das células da projeção/renderização de cada mapa. SubplotSpec descreve um retângulo de células, com a mesma forma de chamada familiar de Matplotlib:

import azimlib as azl

fig = azl.figure(figsize=(12, 8), layout="constrained")
gs = fig.add_gridspec(2, 3, width_ratios=[2.3, 1, 1])

brasil = fig.add_subplot(gs[:, 0], projection="mercator")
minas = fig.add_subplot(gs[0, 1:], projection="mercator")
sao_paulo = fig.add_subplot(gs[1, 1:], projection="mercator")

brasil.map("brazil")
minas.state("MG")
sao_paulo.state("SP")
fig.suptitle("Atlas regional")
fig.savefig("atlas.png", dpi=150)
azl.show()

As linhas são contadas de cima para baixo; colunas, da esquerda para a direita. Índices são zero-based e aceitam valores negativos. gs[0] é a primeira célula na ordem por linhas; gs[-1] é a última. gs[:, 0] ocupa toda a primeira coluna, gs[0, :] ocupa toda a primeira linha. gs[1:, 1:] seleciona um bloco. O fim de uma slice é exclusivo. A seleção cria um SubplotSpec, sem criar Axes.

Slices planas, como gs[2:5], usam o retângulo definido pelas células inicial e final, seguindo a referência. Esse retângulo pode conter células fora da sequência plana. Para intenção clara, prefira gs[rows, columns].

Também funcionam fig.add_subplot(231), fig.add_subplot(2, 3, 4) e fig.add_subplot(2, 3, (2, 6)): índices numéricos são one-based; o par seleciona o retângulo entre as duas células. Chamadas numéricas da mesma forma de grid reutilizam seu GridSpec; cada chamada cria um novo Axes.

Proporções e espaços

fig, axs = azl.subplots(
    2, 2, width_ratios=[2, 1], height_ratios=[1, 3],
    gridspec_kw={"wspace": 0.3, "hspace": 0.4},
)
# Alternativa: todos os parâmetros em gridspec_kw.
gs = axs[0, 0].get_gridspec()

Proporções são pesos relativos, copiados da entrada: [2,1] aloca à primeira coluna duas vezes a largura útil da segunda. width_ratios tem um valor por coluna; height_ratios, por linha. A área de um span inclui os espaços internos entre suas células. Não corresponde necessariamente ao tamanho visível do mapa: a proporção geográfica pode deixar espaço em branco no retângulo alocado.

left, right, bottom e top usam frações da Figure. wspace/hspace usam frações da largura/altura média das células, independentemente dos pesos. Opções locais têm precedência sobre fig.subplots_adjust(...). Quando não há opção local, o grid herda os parâmetros da Figure.

fig.subplots_adjust(left=0.15, right=0.92, wspace=0.25)
gs.update(left=0.2, wspace=0.35)
gs.update(left=None)  # Volta a herdar o parâmetro da Figure.

gs.set_width_ratios([1, 2])
gs.set_height_ratios([2, 1])
gs.update()  # Aplica os novos pesos às posições em layout manual.

Como na referência, setters de proporção não reposicionam imediatamente Axes em layout manual. gs.update() aplica as proporções atuais. Engines automáticos leem esses pesos no próximo desenho. Valores inválidos são rejeitados antes de alterar proporções, parâmetros ou posições.

Layout e componentes

Tight/constrained próprios medem títulos, ticks, labels, legendas e colorbars considerando os limites externos de cada span. Reservas de margem/espaçamento são conservadoras; não são o solver do Matplotlib nem garantem pixels iguais. Opções locais de margem limitam a área disponível ao solver. Espaços locais são mínimos: decorações podem exigir separação maior.

Colorbar compartilhada funciona sobre a união dos mapas, incluindo spans:

bar = fig.colorbar(layer, ax=[brasil, minas, sao_paulo], orientation="horizontal")

Também é possível reservar uma célula/span para cax=fig.add_subplot(gs[...]). O retângulo desse cax continua explícito e não é movido pelo solver automático. Para um atlas com cax reservado, use layout manual ou reserve uma área externa ao rect do solver; ele ainda não evita esse cax como um obstáculo independente. add_axes() também preserva seu retângulo manual.

get_subplotspec() retorna a seleção de um Axes; get_gridspec() retorna seu grid. Em Axes manuais os dois retornam None. spec.get_position(fig).bounds retorna a alocação nominal pelas margens/espaços, antes do solver automático e da correção de aspecto do mapa. Não mede o viewport renderizado. gs.get_grid_positions(fig) retorna tuplas de bottoms/tops/lefts/rights. gs.get_subplot_params(fig) retorna uma cópia com acesso por chave ou atributo.

Os componentes continuam opcionais. GridSpec não acrescenta grade, legenda, barra de escala, colorbar, minimapa, seta de norte ou rosa dos ventos.

Escopo e diferenças deliberadas

Exemplo completo e atlas renderizado (gallery/gridspec-atlas.png, generated locally). tools/inspect_gridspec.py registra 24 seleções, seis estados de edição e três seleções numéricas do Matplotlib 3.11.2/Agg em gridspec-reference.json. Os testes comparam a alocação manual em frações de Figure; não exigem Matplotlib instalado. O núcleo continua sem backend cartográfico externo.