Observação
Clique aqui para baixar o código de exemplo completo
Anotações #
Anotando texto com Matplotlib.
from matplotlib import pyplot as plt
Anotação básica #
Os usos do básico text()
colocarão o texto em uma posição arbitrária nos eixos. Um caso de uso comum de texto é anotar algum recurso do gráfico, e o
annotate()
método fornece funcionalidade auxiliar para facilitar as anotações. Em uma anotação, há dois pontos a serem considerados: o local que está sendo anotado representado pelo argumento
xy e o local do texto xytext . Ambos os argumentos são tuplas.(x, y)
Neste exemplo, os locais xy (ponta de seta) e xytext (localização de texto) estão em coordenadas de dados. Há uma variedade de outros sistemas de coordenadas que podem ser escolhidos - você pode especificar o sistema de coordenadas de xy e xytext com uma das seguintes strings para xycoords e textcoords (o padrão é 'data')
argumento |
sistema de coordenadas |
---|---|
'figura pontos' |
pontos do canto inferior esquerdo da figura |
'figura pixels' |
pixels do canto inferior esquerdo da figura |
'fração figura' |
(0, 0) é o canto inferior esquerdo da figura e (1, 1) é o canto superior direito |
'pontos de eixos' |
pontos do canto inferior esquerdo dos eixos |
'eixos pixels' |
pixels do canto inferior esquerdo dos eixos |
'fração de eixos' |
(0, 0) é o canto inferior esquerdo dos eixos e (1, 1) é o canto superior direito |
'dados' |
usar o sistema de coordenadas de dados de eixos |
Por exemplo, para colocar as coordenadas de texto em coordenadas de eixos fracionários, pode-se fazer:
ax.annotate('local max', xy=(3, 1), xycoords='data',
xytext=(0.8, 0.95), textcoords='axes fraction',
arrowprops=dict(facecolor='black', shrink=0.05),
horizontalalignment='right', verticalalignment='top',
)
Para sistemas de coordenadas físicas (pontos ou pixels), a origem é a parte inferior esquerda da figura ou dos eixos.
Opcionalmente, você pode habilitar o desenho de uma seta do texto para o ponto anotado fornecendo um dicionário de propriedades de seta no argumento de palavra-chave opcional arrowprops .
tecla de flechas |
Descrição |
---|---|
largura |
a largura da seta em pontos |
fratura |
a fração do comprimento da flecha ocupada pela cabeça |
largura da cabeça |
a largura da base da ponta da seta em pontos |
Psiquiatra |
mova a ponta e a base alguns percentuais para longe do ponto anotado e do texto |
** kwargs |
qualquer tecla para |
No exemplo abaixo, o ponto xy está em coordenadas nativas ( xycoords é padronizado como 'data'). Para eixos polares, isso está no espaço (teta, raio). O texto neste exemplo é colocado no sistema de coordenadas de figura fracionária. matplotlib.text.Text
argumentos de palavra-chave como horizontalalignment , verticalalignment e
fontsize são passados annotate
para a
Text
instância.
Para saber mais sobre todas as coisas incríveis e incríveis que você pode fazer com anotações, incluindo setas sofisticadas, consulte Anotações avançadas e plotagens de anotações .
Não prossiga a menos que você já tenha lido a anotação básica
text()
e annotate()
!
Anotações Avançadas #
Anotando com texto com caixa #
Vamos começar com um exemplo simples.
text
recebe um argumento de palavra-chave bbox , que desenha uma caixa ao redor do texto:
t = ax.text(
0, 0, "Direction", ha="center", va="center", rotation=45, size=15,
bbox=dict(boxstyle="rarrow,pad=0.3", fc="cyan", ec="b", lw=2))
O objeto patch associado ao texto pode ser acessado por:
bb = t.get_bbox_patch()
O valor de retorno é um FancyBboxPatch
; as propriedades do patch (facecolor, edgewidth, etc.) podem ser acessadas e modificadas normalmente.
FancyBboxPatch.set_boxstyle
define a forma da caixa:
bb.set_boxstyle("rarrow", pad=0.6)
Os argumentos são o nome do estilo de caixa com seus atributos como argumentos de palavra-chave. Atualmente, os seguintes estilos de caixa são implementados.
Classe
Nome
Atributos
Círculo
circle
almofada = 0,3
D Seta
darrow
almofada = 0,3
LSeta
larrow
almofada = 0,3
RA seta
rarrow
almofada = 0,3
Redondo
round
pad=0.3,rounding_size=Nenhum
Round4
round4
pad=0.3,rounding_size=Nenhum
dente redondo
roundtooth
pad=0.3,tooth_size=Nenhum
dente de serra
sawtooth
pad=0.3,tooth_size=Nenhum
Quadrado
square
almofada = 0,3
Observe que os argumentos de atributo podem ser especificados dentro do nome do estilo com vírgula de separação (este formulário pode ser usado como valor "boxstyle" do argumento bbox ao inicializar a instância de texto)
bb.set_boxstyle("rarrow,pad=0.6")
Anotando com a seta #
annotate
desenha uma seta conectando dois pontos em um Axes:
ax.annotate("Annotation",
xy=(x1, y1), xycoords='data',
xytext=(x2, y2), textcoords='offset points',
)
Isso anota um ponto em xy na coordenada fornecida ( xycoords ) com o texto em xytext fornecido em textcoords . Freqüentemente, o ponto anotado é especificado na coordenada de dados e o texto anotado em pontos de deslocamento . Veja annotate
os sistemas de coordenadas disponíveis.
Uma seta conectando xy a xytext pode ser desenhada opcionalmente especificando o argumento arrowprops . Para desenhar apenas uma seta, use uma string vazia como primeiro argumento.
ax.annotate("",
xy=(0.2, 0.2), xycoords='data',
xytext=(0.8, 0.8), textcoords='data',
arrowprops=dict(arrowstyle="->",
connectionstyle="arc3"),
)
A seta é desenhada da seguinte forma:
Um caminho conectando os dois pontos é criado, conforme especificado pelo parâmetro connectionstyle .
O caminho é cortado para evitar patches patchA e patchB , se estiverem definidos.
O caminho é reduzido ainda mais por ShrinkA e ShrinkB (em pixels).
O caminho é transmutado para um patch de seta, conforme especificado pelo parâmetro estilo de seta .
A criação do caminho de conexão entre dois pontos é controlada por
connectionstyle
chave e os seguintes estilos estão disponíveis.
Nome
Atributos
angle
ânguloA=90,ânguloB=0,rad=0,0
angle3
ânguloA=90,ânguloB=0
arc
angleA=0,angleB=0,armA=None,armB=None,rad=0.0
arc3
rad=0,0
bar
braçoA=0,0, braçoB=0,0,fração=0,3,ângulo=Nenhum
Observe que "3" em angle3
e arc3
serve para indicar que o caminho resultante é um segmento de spline quadrático (três pontos de controle). Como será discutido abaixo, algumas opções de estilo de seta só podem ser usadas quando o caminho de conexão for uma spline quadrática.
O comportamento de cada estilo de conexão é (limitadamente) demonstrado no exemplo abaixo. (Aviso: O comportamento do bar
estilo não está bem definido no momento, pode ser alterado no futuro).
O caminho de conexão (após o corte e encolhimento) é então transformado em um patch de seta, de acordo com o arquivo arrowstyle
.
Nome
Atributos
-
Nenhum
->
head_length=0.4,head_width=0.2
-[
larguraB=1,0,comprimentoB=0,2,ânguloB=Nenhum
|-|
larguraA=1,0,larguraB=1,0
-|>
head_length=0.4,head_width=0.2
<-
head_length=0.4,head_width=0.2
<->
head_length=0.4,head_width=0.2
<|-
head_length=0.4,head_width=0.2
<|-|>
head_length=0.4,head_width=0.2
fancy
head_length=0.4,head_width=0.4,tail_width=0.4
simple
head_length=0,5,head_width=0,5,tail_width=0,2
wedge
tail_width=0.3,shrink_factor=0.5
Alguns estilos de seta funcionam apenas com estilos de conexão que geram um segmento de spline quadrático. Eles são fancy
, simple
e wedge
. Para esses estilos de seta, você deve usar o estilo de conexão "angle3" ou "arc3".
Se a string de anotação for fornecida, o patchA é definido como o patch bbox do texto por padrão.
Assim como em text
, uma caixa ao redor do texto pode ser desenhada usando o argumento bbox
.
Por padrão, o ponto inicial é definido no centro da extensão do texto. Isso pode ser ajustado com relpos
o valor da chave. Os valores são normalizados na extensão do texto. Por exemplo, (0, 0) significa canto inferior esquerdo e (1, 1) significa canto superior direito.
Posicionando Artista em localizações de eixos ancorados #
Existem turmas de artistas que podem ser colocadas em um local ancorado nos Eixos. Um exemplo comum é a legenda. Esse tipo de artista pode ser criado usando a OffsetBox
classe. Algumas classes predefinidas estão disponíveis em matplotlib.offsetbox
e em
mpl_toolkits.axes_grid1.anchored_artists
.
from matplotlib.offsetbox import AnchoredText
fig, ax = plt.subplots()
at = AnchoredText(
"Figure 1a", prop=dict(size=15), frameon=True, loc='upper left')
at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
ax.add_artist(at)
<matplotlib.offsetbox.AnchoredText object at 0x7f2cdd7d9cf0>
A palavra-chave loc tem o mesmo significado do comando legend.
Uma aplicação simples é quando o tamanho do artista (ou coleção de artistas) é conhecido em tamanho de pixel durante o tempo de criação. Por exemplo, se você deseja desenhar um círculo com tamanho fixo de 20 pixels x 20 pixels (raio = 10 pixels), pode utilizar
AnchoredDrawingArea
. A instância é criada com um tamanho da área de desenho (em pixels) e artistas arbitrários podem ser adicionados à área de desenho. Observe que as extensões dos artistas que são adicionados à área de desenho não estão relacionadas ao posicionamento da própria área de desenho. Apenas o tamanho inicial importa.
Os artistas que são adicionados à área de desenho não devem ter um conjunto de transformação (será substituído) e as dimensões desses artistas são interpretadas como uma coordenada de pixel, ou seja, o raio dos círculos no exemplo acima são 10 pixels e 5 pixels , respectivamente.
from matplotlib.patches import Circle
from mpl_toolkits.axes_grid1.anchored_artists import AnchoredDrawingArea
fig, ax = plt.subplots()
ada = AnchoredDrawingArea(40, 20, 0, 0,
loc='upper right', pad=0., frameon=False)
p1 = Circle((10, 10), 10)
ada.drawing_area.add_artist(p1)
p2 = Circle((30, 10), 5, fc="r")
ada.drawing_area.add_artist(p2)
ax.add_artist(ada)
<mpl_toolkits.axes_grid1.anchored_artists.AnchoredDrawingArea object at 0x7f2cde0e07f0>
Às vezes, você deseja que seus artistas sejam dimensionados com a coordenada de dados (ou coordenadas diferentes dos pixels da tela). Você pode usar
AnchoredAuxTransformBox
classe. Isso é semelhante,
AnchoredDrawingArea
exceto que a extensão do artista é determinada durante o tempo de desenho, respeitando a transformação especificada.
A elipse no exemplo abaixo terá largura e altura correspondentes a 0,1 e 0,4 nas coordenadas de dados e será dimensionada automaticamente quando os limites de visualização dos eixos mudarem.
from matplotlib.patches import Ellipse
from mpl_toolkits.axes_grid1.anchored_artists import AnchoredAuxTransformBox
fig, ax = plt.subplots()
box = AnchoredAuxTransformBox(ax.transData, loc='upper left')
el = Ellipse((0, 0), width=0.1, height=0.4, angle=30) # in data coordinates!
box.drawing_area.add_artist(el)
ax.add_artist(box)
<mpl_toolkits.axes_grid1.anchored_artists.AnchoredAuxTransformBox object at 0x7f2cde48dea0>
Como na legenda, o argumento bbox_to_anchor pode ser definido. Usando o HPacker e o VPacker, você pode ter um arranjo (?) de artista como na legenda (na verdade, é assim que a legenda é criada).
Observe que, ao contrário da legenda, o bbox_transform
é definido como IdentityTransform por padrão.
Sistemas de coordenadas para Anotações #
As anotações do Matplotlib suportam vários tipos de coordenadas. Alguns são descritos na anotação básica ; opções mais avançadas são
Uma
Transform
instância. Por exemplo,ax.annotate("Test", xy=(0.5, 0.5), xycoords=ax.transAxes)
é idêntico a
ax.annotate("Test", xy=(0.5, 0.5), xycoords="axes fraction")
Isso permite anotar um ponto em outros eixos:
fig, (ax1, ax2) = plt.subplots(1, 2) ax2.annotate("Test", xy=(0.5, 0.5), xycoords=ax1.transData, xytext=(0.5, 0.5), textcoords=ax2.transData, arrowprops=dict(arrowstyle="->"))
Uma
Artist
instância. O valor xy (ou xytext ) é interpretado como uma coordenada fracionária do bbox (valor de retorno de get_window_extent ) do artista:an1 = ax.annotate("Test 1", xy=(0.5, 0.5), xycoords="data", va="center", ha="center", bbox=dict(boxstyle="round", fc="w")) an2 = ax.annotate("Test 2", xy=(1, 0.5), xycoords=an1, # (1, 0.5) of the an1's bbox xytext=(30, 0), textcoords="offset points", va="center", ha="left", bbox=dict(boxstyle="round", fc="w"), arrowprops=dict(arrowstyle="->"))
Observe que você deve garantir que a extensão do artista de coordenadas ( an1 no exemplo acima) seja determinada antes de an2 ser desenhado. Normalmente, isso significa que an2 precisa ser desenhado após an1 .
Um objeto que pode ser chamado que usa a instância do renderizador como único argumento e retorna um
Transform
ou umBboxBase
. O valor de retorno é tratado como em (1), para transformações, ou em (2), para bboxes. Por exemplo,an2 = ax.annotate("Test 2", xy=(1, 0.5), xycoords=an1, xytext=(30, 0), textcoords="offset points")
é idêntico a:
an2 = ax.annotate("Test 2", xy=(1, 0.5), xycoords=an1.get_window_extent, xytext=(30, 0), textcoords="offset points")
Um par de especificações de coordenadas -- a primeira para a coordenada x e a segunda para a coordenada y; por exemplo
annotate("Test", xy=(0.5, 1), xycoords=("data", "axes fraction"))
Aqui, 0,5 está em coordenadas de dados e 1 está em coordenadas de eixos normalizados. Cada uma das especificações de coordenadas também pode ser um artista ou uma transformação. Por exemplo,
Às vezes, você deseja sua anotação com alguns "pontos de deslocamento", não do ponto anotado, mas de algum outro ponto.
text.OffsetFrom
é um ajudante para tais casos.Você pode dar uma olhada neste exemplo de gráficos de anotação .
Usando ConnectionPatch #
ConnectionPatch
é como uma anotação sem texto. Embora annotate
seja suficiente na maioria das situações, ConnectionPatch
é útil quando você deseja conectar pontos em eixos diferentes.
from matplotlib.patches import ConnectionPatch
xy = (0.2, 0.2)
con = ConnectionPatch(xyA=xy, coordsA=ax1.transData,
xyB=xy, coordsB=ax2.transData)
fig.add_artist(con)
O código acima conecta o ponto xy nas coordenadas de dados de ax1
ao ponto xy nas coordenadas de dados de ax2
. Aqui está um exemplo simples.
Aqui, adicionamos o ConnectionPatch
à figura (com add_artist
) em vez de qualquer um dos eixos: isso garante que ele seja desenhado em cima de ambos os eixos e também é necessário se estiver usando o layout_constrangido para posicionar os eixos.
Tópicos Avançados #
Efeito de zoom entre eixos #
mpl_toolkits.axes_grid1.inset_locator
define algumas classes de patch úteis para interconectar dois eixos. Compreender o código requer algum conhecimento do sistema de transformação do Matplotlib.
Definir BoxStyle personalizado #
Você pode usar um estilo de caixa personalizado. O valor para o boxstyle
pode ser um objeto que pode ser chamado nas seguintes formas.:
def __call__(self, x0, y0, width, height, mutation_size,
aspect_ratio=1.):
'''
Given the location and size of the box, return the path of
the box around it.
- *x0*, *y0*, *width*, *height* : location and size of the box
- *mutation_size* : a reference scale for the mutation.
- *aspect_ratio* : aspect-ratio for the mutation.
'''
path = ...
return path
Aqui está um exemplo completo.
Da mesma forma, você pode definir um ConnectionStyle personalizado e um ArrowStyle personalizado. Veja o código fonte de lib/matplotlib/patches.py
e confira como cada classe de estilo é definida.