Observação
Clique aqui para baixar o código de exemplo completo
Controlando programaticamente o ajuste da subtrama #
Observação
Este exemplo destina-se principalmente a mostrar alguns conceitos avançados no Matplotlib.
Se você está procurando apenas ter espaço suficiente para seus rótulos, é quase sempre mais simples e bom o suficiente definir os parâmetros da subtrama manualmente usando Figure.subplots_adjust
ou usar um dos mecanismos de layout automático ( Guia de layout restrito ou
Guia de layout apertado ).
Este exemplo descreve uma maneira definida pelo usuário de ler os tamanhos do Artista e definir os parâmetros da subtrama de acordo. Seu principal objetivo é ilustrar alguns conceitos avançados, como ler posições de texto, trabalhar com caixas delimitadoras e transformações e usar eventos . Mas também pode servir como ponto de partida se você quiser automatizar o layout e precisar de mais flexibilidade do que um layout rígido e um layout restrito.
Abaixo, coletamos as caixas delimitadoras de todos os rótulos y e movemos a borda esquerda da subtrama para a direita para que haja espaço suficiente para a união de todas as caixas delimitadoras.
Há um problema com o cálculo de caixas delimitadoras de texto: consultar as caixas delimitadoras de texto ( Text.get_window_extent
) requer um renderizador ( RendererBase
instância) para calcular o tamanho do texto. Este renderizador só está disponível após o desenho da figura ( Figure.draw
).
Uma solução para isso é colocar a lógica de ajuste em um callback de desenho. Esta função é executada após a figura ter sido desenhada. Agora ele pode verificar se a subtrama deixa espaço suficiente para o texto. Caso contrário, os parâmetros da subtrama são atualizados e o segundo sorteio é acionado.
import matplotlib.pyplot as plt
import matplotlib.transforms as mtransforms
fig, ax = plt.subplots()
ax.plot(range(10))
ax.set_yticks([2, 5, 7], labels=['really, really, really', 'long', 'labels'])
def on_draw(event):
bboxes = []
for label in ax.get_yticklabels():
# Bounding box in pixels
bbox_px = label.get_window_extent()
# Transform to relative figure coordinates. This is the inverse of
# transFigure.
bbox_fig = bbox_px.transformed(fig.transFigure.inverted())
bboxes.append(bbox_fig)
# the bbox that bounds all the bboxes, again in relative figure coords
bbox = mtransforms.Bbox.union(bboxes)
if fig.subplotpars.left < bbox.width:
# Move the subplot left edge more to the right
fig.subplots_adjust(left=1.1*bbox.width) # pad a little
fig.canvas.draw()
fig.canvas.mpl_connect('draw_event', on_draw)
plt.show()
Referências
O uso das seguintes funções, métodos, classes e módulos é mostrado neste exemplo: