Observação
Clique aqui para baixar o código de exemplo completo
Organizando vários eixos em uma figura #
Freqüentemente, mais de um eixo é necessário em uma figura por vez, geralmente organizado em uma grade regular. O Matplotlib possui uma variedade de ferramentas para trabalhar com grades de eixos que evoluíram ao longo da história da biblioteca. Aqui discutiremos as ferramentas que achamos que os usuários devem usar com mais frequência, as ferramentas que sustentam como os Axes são organizados e mencionamos algumas das ferramentas mais antigas.
Observação
Matplotlib usa Axes para se referir à área de desenho que contém dados, eixos x e y, marcações, rótulos, títulos, etc. Consulte Partes de uma figura para obter mais detalhes. Outro termo frequentemente usado é "subplot", que se refere a um Axes que está em uma grade com outros objetos Axes.
Visão geral #
Crie combinações em forma de grade de eixos #
subplots
A função principal usada para criar figuras e uma grade de eixos. Ele cria e coloca todos os eixos na figura de uma vez e retorna uma matriz de objetos com alças para os eixos na grade. Veja
Figure.subplots
.
ou
subplot_mosaic
Uma maneira simples de criar figuras e uma grade de eixos, com a flexibilidade adicional de que os eixos também podem abranger linhas ou colunas. Os eixos são retornados em um dicionário rotulado em vez de uma matriz. Veja também
Figure.subplot_mosaic
e Composição de figuras complexas e semânticas .
Às vezes é natural ter mais de um grupo distinto de grades de Axes, caso em que o Matplotlib tem o conceito de SubFigure
:
SubFigure
Uma figura virtual dentro de uma figura.
Ferramentas subjacentes #
Subjacente a estes estão os conceitos de a GridSpec
e a SubplotSpec
:
GridSpec
Especifica a geometria da grade em que uma subtrama será colocada. O número de linhas e o número de colunas da grade precisam ser definidos. Opcionalmente, os parâmetros de layout da subtrama (por exemplo, esquerda, direita, etc.) podem ser ajustados.
SubplotSpec
Especifica a localização da subtrama no dado
GridSpec
.
Adicionando eixos únicos por vez #
As funções acima criam todos os eixos em uma única chamada de função. Também é possível adicionar eixos um de cada vez, e era assim que o Matplotlib funcionava originalmente. Fazer isso geralmente é menos elegante e flexível, embora às vezes útil para trabalho interativo ou para colocar um eixo em um local personalizado:
add_axes
Adiciona um único eixo em um local especificado por em frações da largura ou altura da figura.
[left, bottom, width, height]
subplot
ouFigure.add_subplot
Adiciona uma única subtrama em uma figura, com indexação baseada em 1 (herdada do Matlab). Colunas e linhas podem ser estendidas especificando um intervalo de células de grade.
subplot2grid
Semelhante a
pyplot.subplot
, mas usa indexação baseada em 0 e divisão de python bidimensional para escolher células.
Métodos de alto nível para fazer grades #
Grade básica 2x2 #
Podemos criar uma grade básica de eixos 2 por 2 usando
subplots
. Ele retorna uma Figure
instância e uma matriz de Axes
objetos. Os objetos Axes podem ser usados para acessar métodos para colocar artistas nos Axes; aqui usamos annotate
, mas outros exemplos poderiam ser plot
,
pcolormesh
, etc.
import matplotlib.pyplot as plt
import numpy as np
fig, axs = plt.subplots(ncols=2, nrows=2, figsize=(5.5, 3.5),
layout="constrained")
# add an artist, in this case a nice label in the middle...
for row in range(2):
for col in range(2):
axs[row, col].annotate(f'axs[{row}, {col}]', (0.5, 0.5),
transform=axs[row, col].transAxes,
ha='center', va='center', fontsize=18,
color='darkgrey')
fig.suptitle('plt.subplots()')
Text(0.5, 0.9880942857142857, 'plt.subplots()')
Anotaremos muitos eixos, então vamos encapsular a anotação, em vez de ter aquele grande pedaço de código de anotação sempre que precisarmos:
def annotate_axes(ax, text, fontsize=18):
ax.text(0.5, 0.5, text, transform=ax.transAxes,
ha="center", va="center", fontsize=fontsize, color="darkgrey")
O mesmo efeito pode ser obtido com subplot_mosaic
, mas o tipo de retorno é um dicionário em vez de um array, onde o usuário pode dar às chaves significados úteis. Aqui fornecemos duas listas, cada lista representando uma linha e cada elemento na lista uma chave representando a coluna.
fig, axd = plt.subplot_mosaic([['upper left', 'upper right'],
['lower left', 'lower right']],
figsize=(5.5, 3.5), layout="constrained")
for k in axd:
annotate_axes(axd[k], f'axd["{k}"]', fontsize=14)
fig.suptitle('plt.subplot_mosaic()')
Text(0.5, 0.9880942857142857, 'plt.subplot_mosaic()')
Grades de proporção de aspecto fixo Eixos #
Eixos de proporção fixa são comuns para imagens ou mapas. No entanto, eles representam um desafio para o layout porque dois conjuntos de restrições estão sendo impostos ao tamanho dos eixos - que eles caibam na figura e que tenham uma proporção definida. Isso leva a grandes lacunas entre os eixos por padrão:
fig, axs = plt.subplots(2, 2, layout="constrained", figsize=(5.5, 3.5))
for ax in axs.flat:
ax.set_aspect(1)
fig.suptitle('Fixed aspect Axes')
Text(0.5, 0.9880942857142857, 'Fixed aspect Axes')
Uma maneira de resolver isso é alterar o aspecto da figura para ficar próximo à proporção dos eixos, mas isso requer tentativa e erro. Matplotlib também fornece layout="compressed"
, que funcionará com grades simples para reduzir as lacunas entre os eixos. (O mpl_toolkits
também fornece ImageGrid
um efeito semelhante, mas com uma classe de machados não padrão).
fig, axs = plt.subplots(2, 2, layout="compressed", figsize=(5.5, 3.5))
for ax in axs.flat:
ax.set_aspect(1)
fig.suptitle('Fixed aspect Axes: compressed')
Text(0.5, 0.9880942857142857, 'Fixed aspect Axes: compressed')
Eixos abrangendo linhas ou colunas em uma grade #
Às vezes, queremos que os eixos abranjam linhas ou colunas da grade. Na verdade, existem várias maneiras de fazer isso, mas a mais conveniente é provavelmente subplot_mosaic
repetir uma das teclas:
fig, axd = plt.subplot_mosaic([['upper left', 'right'],
['lower left', 'right']],
figsize=(5.5, 3.5), layout="constrained")
for k in axd:
annotate_axes(axd[k], f'axd["{k}"]', fontsize=14)
fig.suptitle('plt.subplot_mosaic()')
Text(0.5, 0.9880942857142857, 'plt.subplot_mosaic()')
Veja abaixo a descrição de como fazer a mesma coisa usando
GridSpec
ou subplot2grid
.
Larguras ou alturas variáveis em uma grade #
Ambos subplots
e subplot_mosaic
permitem que as linhas na grade tenham alturas diferentes e as colunas tenham larguras diferentes usando o argumento de palavra-chave gridspec_kw . Parâmetros de espaçamento aceitos por GridSpec
podem ser passados para subplots
e
subplot_mosaic
:
gs_kw = dict(width_ratios=[1.4, 1], height_ratios=[1, 2])
fig, axd = plt.subplot_mosaic([['upper left', 'right'],
['lower left', 'right']],
gridspec_kw=gs_kw, figsize=(5.5, 3.5),
layout="constrained")
for k in axd:
annotate_axes(axd[k], f'axd["{k}"]', fontsize=14)
fig.suptitle('plt.subplot_mosaic()')
Text(0.5, 0.9880942857142857, 'plt.subplot_mosaic()')
Layouts de eixos aninhados #
Às vezes é útil ter duas ou mais grades de eixos que podem não precisar estar relacionadas entre si. A maneira mais simples de fazer isso é usar Figure.subfigures
. Observe que os layouts das subfiguras são independentes, portanto, as lombadas dos Axes em cada subfigura não estão necessariamente alinhadas. Veja abaixo uma maneira mais detalhada de obter o mesmo efeito com GridSpecFromSubplotSpec
.
fig = plt.figure(layout="constrained")
subfigs = fig.subfigures(1, 2, wspace=0.07, width_ratios=[1.5, 1.])
axs0 = subfigs[0].subplots(2, 2)
subfigs[0].set_facecolor('0.9')
subfigs[0].suptitle('subfigs[0]\nLeft side')
subfigs[0].supxlabel('xlabel for subfigs[0]')
axs1 = subfigs[1].subplots(3, 1)
subfigs[1].suptitle('subfigs[1]')
subfigs[1].supylabel('ylabel for subfigs[1]')
Text(0.016867713730569944, 0.5, 'ylabel for subfigs[1]')
Também é possível aninhar eixos usando subplot_mosaic
listas aninhadas. Este método não usa subfiguras, como acima, portanto, não tem a capacidade de adicionar por subfigura suptitle
e supxlabel
, etc. Em vez disso, é um wrapper de conveniência em torno do subgridspec
método descrito abaixo.
Métodos de grade avançados e de baixo nível #
Internamente, o arranjo de uma grade de Axes é controlado pela criação de instâncias de GridSpec
e SubplotSpec
. GridSpec define uma grade (possivelmente não uniforme) de células. A indexação no GridSpec retorna um SubplotSpec que abrange uma ou mais células da grade e pode ser usado para especificar a localização de um Axes.
Os exemplos a seguir mostram como usar métodos de baixo nível para organizar eixos usando objetos GridSpec .
Grade básica 2x2 #
Podemos realizar uma grade 2x2 da mesma maneira que
:plt.subplots(2, 2)
fig = plt.figure(figsize=(5.5, 3.5), layout="constrained")
spec = fig.add_gridspec(ncols=2, nrows=2)
ax0 = fig.add_subplot(spec[0, 0])
annotate_axes(ax0, 'ax0')
ax1 = fig.add_subplot(spec[0, 1])
annotate_axes(ax1, 'ax1')
ax2 = fig.add_subplot(spec[1, 0])
annotate_axes(ax2, 'ax2')
ax3 = fig.add_subplot(spec[1, 1])
annotate_axes(ax3, 'ax3')
fig.suptitle('Manually added subplots using add_gridspec')
Text(0.5, 0.9880942857142857, 'Manually added subplots using add_gridspec')
Eixos abrangendo linhas ou grades em uma grade #
Podemos indexar a matriz de especificações usando a sintaxe de fatia NumPy
e os novos eixos abrangerão a fatia. Isso seria o mesmo que :fig, axd = plt.subplot_mosaic([['ax0', 'ax0'], ['ax1', 'ax2']], ...)
fig = plt.figure(figsize=(5.5, 3.5), layout="constrained")
spec = fig.add_gridspec(2, 2)
ax0 = fig.add_subplot(spec[0, :])
annotate_axes(ax0, 'ax0')
ax10 = fig.add_subplot(spec[1, 0])
annotate_axes(ax10, 'ax10')
ax11 = fig.add_subplot(spec[1, 1])
annotate_axes(ax11, 'ax11')
fig.suptitle('Manually added subplots, spanning a column')
Text(0.5, 0.9880942857142857, 'Manually added subplots, spanning a column')
Ajustes manuais para um layout GridSpec #
Quando um GridSpec é usado explicitamente, você pode ajustar os parâmetros de layout das subtramas que são criadas a partir do GridSpec . Observe que esta opção não é compatível com constrained_layout
ou
Figure.tight_layout
ambas ignoram a esquerda e a direita e ajustam os tamanhos da subtrama para preencher a figura. Normalmente, esse posicionamento manual requer iterações para fazer com que os rótulos de marcação dos eixos não se sobreponham aos eixos.
Esses parâmetros de espaçamento também podem ser passados para subplots
e
subplot_mosaic
como o argumento gridspec_kw .
fig = plt.figure(layout=None, facecolor='0.9')
gs = fig.add_gridspec(nrows=3, ncols=3, left=0.05, right=0.75,
hspace=0.1, wspace=0.05)
ax0 = fig.add_subplot(gs[:-1, :])
annotate_axes(ax0, 'ax0')
ax1 = fig.add_subplot(gs[-1, :-1])
annotate_axes(ax1, 'ax1')
ax2 = fig.add_subplot(gs[-1, -1])
annotate_axes(ax2, 'ax2')
fig.suptitle('Manual gridspec with right=0.75')
Text(0.5, 0.98, 'Manual gridspec with right=0.75')
Layouts aninhados com SubplotSpec #
Você pode criar um layout aninhado semelhante ao subfigures
uso
de subgridspec
. Aqui os espinhos dos Axes estão
alinhados.
Observe que isso também está disponível no arquivo
gridspec.GridSpecFromSubplotSpec
.
fig = plt.figure(layout="constrained")
gs0 = fig.add_gridspec(1, 2)
gs00 = gs0[0].subgridspec(2, 2)
gs01 = gs0[1].subgridspec(3, 1)
for a in range(2):
for b in range(2):
ax = fig.add_subplot(gs00[a, b])
annotate_axes(ax, f'axLeft[{a}, {b}]', fontsize=10)
if a == 1 and b == 1:
ax.set_xlabel('xlabel')
for a in range(3):
ax = fig.add_subplot(gs01[a])
annotate_axes(ax, f'axRight[{a}, {b}]')
if a == 2:
ax.set_ylabel('ylabel')
fig.suptitle('nested gridspecs')
Text(0.5, 0.99131875, 'nested gridspecs')
Aqui está um exemplo mais sofisticado de GridSpec aninhado : Criamos uma grade 4x4 externa com cada célula contendo uma grade 3x3 interna de Axes. Delineamos a grade 4x4 externa ocultando os espinhos apropriados em cada uma das grades 3x3 internas.
def squiggle_xy(a, b, c, d, i=np.arange(0.0, 2*np.pi, 0.05)):
return np.sin(i*a)*np.cos(i*b), np.sin(i*c)*np.cos(i*d)
fig = plt.figure(figsize=(8, 8), constrained_layout=False)
outer_grid = fig.add_gridspec(4, 4, wspace=0, hspace=0)
for a in range(4):
for b in range(4):
# gridspec inside gridspec
inner_grid = outer_grid[a, b].subgridspec(3, 3, wspace=0, hspace=0)
axs = inner_grid.subplots() # Create all subplots for the inner grid.
for (c, d), ax in np.ndenumerate(axs):
ax.plot(*squiggle_xy(a + 1, b + 1, c + 1, d + 1))
ax.set(xticks=[], yticks=[])
# show only the outside spines
for ax in fig.get_axes():
ss = ax.get_subplotspec()
ax.spines.top.set_visible(ss.is_first_row())
ax.spines.bottom.set_visible(ss.is_last_row())
ax.spines.left.set_visible(ss.is_first_col())
ax.spines.right.set_visible(ss.is_last_col())
plt.show()
Mais leitura #
Mais detalhes sobre o mosaico da subtrama .
Mais detalhes sobre o layout restrito , usado para alinhar o espaçamento na maioria desses exemplos.
Referências
O uso das seguintes funções, métodos, classes e módulos é mostrado neste exemplo:
Tempo total de execução do script: ( 0 minutos 13.006 segundos)