Curso matplotlib - Elementos auxiliares (Anotações)
O plt.annotate()
já foi utilizado anteriormente, mas não foi estudado a fundo. Em geral, esta é a melhor forma de adicionar texto nos gráficos, especialmente se o este texto estiver relacionado a algum ponto do gráfico.
O elemento plt.annotate()
recebe pelo menos dois parâmetros, sendo o primeiro parâmetro o text
, que é o texto que será anotado (que deve ser uma str
), e o segundo é o parâmetro xy
, que é deve ser uma tuple
de dois elementos (int
ou float
) com os valores de x
e y
referentes a posição onde o texto será anotado.
Por exemplo:
plt.figure(figsize=(8,6))
plt.scatter(x,y)
plt.annotate("minha anotação", (x[0], y[0]))
plt.show()
Figura 1 - Gráfico de dispersão com texto inserido com o plt.annotate()
.
Entretanto, o parâmetro xy
define onde a anotação inicia. O parâmetro utilizado para definir onde o texto é realmente inserido é o parâmetro xytext
, que também recebe uma tuple
com as coordenadas xy
.
Por exemplo, passando o mesmo valor para xy
e xytext
, obtemos o mesmo resultado obtido anteriormente (Figura 1):
plt.figure(figsize=(8,6))
plt.scatter(x,y)
plt.annotate("minha anotação", (x[0], y[0]), xytext=(x[0],y[0]))
plt.show()
Figura 2 - Gráfico de dispersão com texto inserido com o plt.annotate()
.
Mas ao passar valores diferentes para xy
e xytext
, obtemos um comportamento diferente:
plt.figure(figsize=(8,6))
plt.scatter(x,y)
plt.annotate("minha anotação", (x[0], y[0]), xytext=(x[0] + 0.3,y[0] + 0.5))
plt.show()
Figura 3 - Gráfico de dispersão com texto inserido com o plt.annotate()
.
Annotações com setas
Este espaço “vazio” é importante para a adição de elementos entre os pontos definidos como xy
e xytext
. Por exemplo, podemos adicionar uma seta dentro de plt.annotate()
, passando o parâmetro arrowprops
.
Este parâmetro recebe um dict
com uma série de keys
para inserir a seta. Para alterar a espessura dessa seta, passamos um número (int
ou float
) através da key
width
:
plt.figure(figsize=(8,6))
plt.scatter(x,y)
plt.annotate("minha anotação", (x[0], y[0]), xytext=(x[0] + 0.3,y[0] + 0.5),
arrowprops={'width': 2})
plt.show()
Figura 4 - Gráfico de dispersão com texto com flecha inserido com o plt.annotate()
.
Espessura da ponta da seta
Para alterar a espessura da cabeça da seta, passamos um número (int
ou float
) para a key
headwidth
:
plt.figure(figsize=(8,6))
plt.scatter(x,y)
plt.annotate("minha anotação", (x[0], y[0]), xytext=(x[0] + 0.3,y[0] + 0.5),
arrowprops={'width': 2, 'headwidth': 20})
plt.show()
Figura 5 - Gráfico de dispersão com texto com flecha inserido com o plt.annotate()
.
Comprimento da ponta seta
Para alterar o comprimento da cabeça da seta, passamos um número (int
ou float
) para a key
headlength
:
plt.figure(figsize=(8,6))
plt.scatter(x,y)
plt.annotate("minha anotação", (x[0], y[0]), xytext=(x[0] + 0.3,y[0] + 0.5),
arrowprops={'width': 2, 'headwidth': 20, 'headlength': 20})
plt.show()
Figura 6 - Gráfico de dispersão com texto com flecha inserido com o plt.annotate()
.
Espaçamento entre o início e fim da seta
Podemos ainda adicionar um espaçamento nos limites do elemento, de forma a evitar que a seta fique exatamente em cima do ponto. Fazemos isso passando um número (int
ou float
) para a key
shrink
:
plt.figure(figsize=(8,6))
plt.scatter(x,y)
plt.annotate("minha anotação", (x[0], y[0]), xytext=(x[0] + 0.3,y[0] + 0.5),
arrowprops={'width': 2, 'headwidth': 20, 'headlength': 20, 'shrink': 0.1,})
plt.show()
Figura 7 - Gráfico de dispersão com texto com flecha inserido com o plt.annotate()
.
Outras edições
Para alterar a cor, espessura da linha, estilo de linha, etc, utilizamos os parâmetros normalmente que vimos anteriormente, como o facecolor
, linestyle
,linewidth
, etc. Por exemplo:
plt.figure(figsize=(8,6))
plt.scatter(x,y)
plt.annotate("minha anotação", (x[0], y[0]), xytext=(x[0] + 2,y[0] + 1.5),
arrowprops={'width': 1, 'headwidth': 20, 'headlength': 20, 'shrink': 0.01,
'facecolor': 'k', 'linewidth': 2, 'linestyle': ':'})
plt.show()
Figura 8 - Gráfico de dispersão com texto com flecha inserido com o plt.annotate()
.
Estilos pré definidos
Temos a opção de passar a key
arrowstyle
que tem uma série de values
pré-definidos com estilos. Entretanto, ao utilizar esta key
, não podemos passar as key
widht
, headwidht
, headlength
e shrink
.
Por exemplo:
plt.figure(figsize=(8,6))
plt.scatter(x,y)
plt.annotate("minha anotação", (x[0], y[0]), xytext=(x[0] + .3, y[0] + 0.5),
arrowprops={'arrowstyle': '-['})
plt.show()
Figura 9 - Gráfico de dispersão com texto com flecha inserido com o plt.annotate()
.
Todos os estilos disponíveis estão exemplificados na figura abaixo, sendo que o valor anotado é o nome do estilo que deve ser passado como value
para a key
arrowstyle
.
Click aqui para acessar o notebook utilizado para desenhar a imagem acima.
Um detalhe importante ao utilizar a anotação com setas, é a direção das setas, especialmente quando queremos que a seta seja paralela aos eixos. Por exemplo:
plt.figure(figsize=(8,6))
plt.scatter(x,y)
plt.annotate("minha anotação", xy=(x[1], y[1]), xytext=(x[2] + .3, y[1]),
arrowprops={'arrowstyle': '->'})
plt.show()
Figura 10 - Gráfico de dispersão com texto com flecha inserido com o plt.annotate()
.
Observe que, apesar dos valores de y
em xy
e em xytext
serem os mesmos (y[1]
) a linha da seta não é paralela ao eixo x
. Para confirmar isto, vou adicionar uma reta paralela ao eixo x
em y[1]
:
plt.figure(figsize=(8,6))
plt.scatter(x,y)
plt.annotate("minha anotação", xy=(x[1], y[1]), xytext=(x[2] + .3, y[1]),
arrowprops={'arrowstyle': '->'})
plt.axhline(y=y[1], xmin=0, xmax=1)
plt.show()
Figura 11 - Gráfico de dispersão com texto com flecha inserido com o plt.annotate()
.
Isto acontece pois a seta é direcionada ao ponto xy
vinda do centro do texto. Como a base do texto é o ponto setado em xytext
, temos esta pequena inclinação.
Para contornar isto, basta passar o parâmetro va
(de vertical alignment) em plt.annotate()
como center
:
plt.figure(figsize=(8,6))
plt.scatter(x,y)
plt.annotate("minha anotação", xy=(x[1], y[1]), xytext=(x[2] + .3, y[1]), va='center',
arrowprops={'arrowstyle': '->'})
plt.axhline(y=y[1], xmin=0, xmax=1)
plt.show()
Figura 12 - Gráfico de dispersão com texto com flecha inserido com o plt.annotate()
.
Maiores detalhes sobre este “problema” nesta thread no github.
Mais detalhes na sobre o plt.annotate()
na documentação.