Observação
Clique aqui para baixar o código de exemplo completo
Texto em Gráficos Matplotlib #
Introdução à plotagem e ao trabalho com texto no Matplotlib.
Matplotlib tem amplo suporte a texto, incluindo suporte para expressões matemáticas, suporte truetype para raster e saídas vetoriais, texto separado por nova linha com rotações arbitrárias e suporte Unicode.
Como ele incorpora fontes diretamente em documentos de saída, por exemplo, para postscript ou PDF, o que você vê na tela é o que obtém na cópia impressa.
O suporte FreeType produz fontes com suavização muito boas, que ficam bem mesmo em tamanhos raster pequenos. O Matplotlib inclui o seu próprio
matplotlib.font_manager
(graças a Paul Barrett), que implementa uma plataforma cruzada,
algoritmo de localização de fonte compatível com W3C .
O usuário tem um grande controle sobre as propriedades do texto (tamanho da fonte, peso da fonte, localização e cor do texto, etc.) com padrões sensatos definidos no arquivo rc . E significativamente, para aqueles interessados em figuras matemáticas ou científicas, o Matplotlib implementa um grande número de símbolos e comandos matemáticos TeX, suportando expressões matemáticas em qualquer lugar da sua figura.
Comandos básicos de texto #
Os seguintes comandos são usados para criar texto nas interfaces implícitas e explícitas (consulte Matplotlib Application Interfaces (APIs) para obter uma explicação das compensações):
API implícita |
API explícita |
Descrição |
---|---|---|
Adicione texto em um local arbitrário do arquivo |
||
Adicione uma anotação, com uma seta opcional, em um local arbitrário do arquivo
|
||
Adicione um rótulo ao
|
||
Adicione um rótulo ao
|
||
Adicione um título ao arquivo
|
||
Adicione texto em um local arbitrário do arquivo |
||
Adicione um título ao arquivo |
Todas essas funções criam e retornam uma Text
instância, que pode ser configurada com uma variedade de fontes e outras propriedades. O exemplo abaixo mostra todos esses comandos em ação e mais detalhes são fornecidos nas seções a seguir.
import matplotlib
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot()
fig.subplots_adjust(top=0.85)
# Set titles for the figure and the subplot respectively
fig.suptitle('bold figure suptitle', fontsize=14, fontweight='bold')
ax.set_title('axes title')
ax.set_xlabel('xlabel')
ax.set_ylabel('ylabel')
# Set both x- and y-axis limits to [0, 10] instead of default [0, 1]
ax.axis([0, 10, 0, 10])
ax.text(3, 8, 'boxed italics text in data coords', style='italic',
bbox={'facecolor': 'red', 'alpha': 0.5, 'pad': 10})
ax.text(2, 6, r'an equation: $E=mc^2$', fontsize=15)
ax.text(3, 2, 'Unicode: Institut für Festkörperphysik')
ax.text(0.95, 0.01, 'colored text in axes coords',
verticalalignment='bottom', horizontalalignment='right',
transform=ax.transAxes,
color='green', fontsize=15)
ax.plot([2], [1], 'o')
ax.annotate('annotate', xy=(2, 1), xytext=(3, 4),
arrowprops=dict(facecolor='black', shrink=0.05))
plt.show()
Rótulos para os eixos x e y #
A especificação dos rótulos para os eixos x e y é direta, por meio dos
métodos set_xlabel
e .set_ylabel
import matplotlib.pyplot as plt
import numpy as np
x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.15, left=0.2)
ax.plot(x1, y1)
ax.set_xlabel('time [s]')
ax.set_ylabel('Damped oscillation [V]')
plt.show()
Os rótulos x e y são colocados automaticamente para que limpem os rótulos x e y. Compare o gráfico abaixo com o gráfico acima e observe que o rótulo y está à esquerda do gráfico acima.
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.15, left=0.2)
ax.plot(x1, y1*10000)
ax.set_xlabel('time [s]')
ax.set_ylabel('Damped oscillation [V]')
plt.show()
Se quiser mover os rótulos, você pode especificar o argumento de palavra-chave labelpad , onde o valor é pontos (1/72", a mesma unidade usada para especificar o tamanho da fonte).
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.15, left=0.2)
ax.plot(x1, y1*10000)
ax.set_xlabel('time [s]')
ax.set_ylabel('Damped oscillation [V]', labelpad=18)
plt.show()
Ou os rótulos aceitam todos os Text
argumentos de palavra-chave, incluindo
position , por meio do qual podemos especificar manualmente as posições dos rótulos. Aqui colocamos o xlabel na extrema esquerda do eixo. Observe que a coordenada y desta posição não tem efeito - para ajustar a posição y, precisamos usar o
argumento de palavra-chave labelpad .
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.15, left=0.2)
ax.plot(x1, y1)
ax.set_xlabel('time [s]', position=(0., 1e6), horizontalalignment='left')
ax.set_ylabel('Damped oscillation [V]')
plt.show()
Toda a rotulagem neste tutorial pode ser alterada manipulando o
matplotlib.font_manager.FontProperties
método ou por argumentos de palavra-chave nomeados paraset_xlabel
from matplotlib.font_manager import FontProperties
font = FontProperties()
font.set_family('serif')
font.set_name('Times New Roman')
font.set_style('italic')
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.15, left=0.2)
ax.plot(x1, y1)
ax.set_xlabel('time [s]', fontsize='large', fontweight='bold')
ax.set_ylabel('Damped oscillation [V]', fontproperties=font)
plt.show()
Por fim, podemos usar a renderização nativa do TeX em todos os objetos de texto e ter várias linhas:
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.2, left=0.2)
ax.plot(x1, np.cumsum(y1**2))
ax.set_xlabel('time [s] \n This was a long experiment')
ax.set_ylabel(r'$\int\ Y^2\ dt\ \ [V^2 s]$')
plt.show()
Títulos #
Os títulos da subtrama são definidos da mesma maneira que os rótulos, mas há os argumentos de palavra-chave loc que podem alterar a posição e a justificação do valor padrão de loc=center
.
O espaçamento vertical para títulos é controlado via rcParams["axes.titlepad"]
(padrão: 6.0
). Definir um valor diferente move o título.
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(top=0.8)
ax.plot(x1, y1)
ax.set_title('Vertically offset title', pad=30)
plt.show()
Ticks e marcadores #
Colocar marcas e rótulos é um aspecto muito complicado de fazer uma figura. O Matplotlib faz o possível para realizar a tarefa automaticamente, mas também oferece uma estrutura muito flexível para determinar as opções de localização dos ticks e como eles são rotulados.
Terminologia #
Os eixos têm um matplotlib.axis.Axis
objeto para o ax.xaxis
e
ax.yaxis
que contém as informações sobre como os rótulos no eixo são dispostos.
A API do eixo é explicada em detalhes na documentação do
axis
.
Um objeto Axis tem marcações principais e secundárias. O Axis tem
métodos Axis.set_major_locator
que Axis.set_minor_locator
usam os dados que estão sendo plotados para determinar a localização dos tiques principais e secundários. Existem também métodos Axis.set_major_formatter
e Axis.set_minor_formatter
que formatam os rótulos dos ticks.
Carrapatos simples #
Freqüentemente, é conveniente simplesmente definir os valores dos ticks e, às vezes, os rótulos dos ticks, substituindo os localizadores e formatadores padrão. Isso é desencorajado porque interrompe a navegação interativa do enredo. Ele também pode redefinir os limites do eixo: observe que o segundo gráfico tem os ticks que solicitamos, incluindo aqueles que estão bem fora dos limites de visualização automática.
É claro que podemos corrigir isso após o fato, mas destaca uma fraqueza de codificar os ticks. Este exemplo também altera o formato dos ticks:
fig, axs = plt.subplots(2, 1, figsize=(5, 3), tight_layout=True)
axs[0].plot(x1, y1)
axs[1].plot(x1, y1)
ticks = np.arange(0., 8.1, 2.)
# list comprehension to get all tick labels...
tickla = [f'{tick:1.2f}' for tick in ticks]
axs[1].xaxis.set_ticks(ticks)
axs[1].xaxis.set_ticklabels(tickla)
axs[1].set_xlim(axs[0].get_xlim())
plt.show()
Localizadores e Formatadores de Marcas #
Em vez de fazer uma lista de todos os ticklabels, poderíamos ter usado matplotlib.ticker.StrMethodFormatter
(string de formato de novo estilo str.format()
) ou matplotlib.ticker.FormatStrFormatter
(string de formato '%' de estilo antigo) e passá-lo para o arquivo ax.xaxis
. A
matplotlib.ticker.StrMethodFormatter
também pode ser criado passando a
str
sem ter que criar explicitamente o formatador.
E é claro que poderíamos ter usado um localizador não padrão para definir os locais dos ticks. Observe que ainda passamos os valores do tick, mas a correção do limite x usada acima não é necessária.
O formatador padrão é matplotlib.ticker.MaxNLocator
chamado como
A palavra-chave steps contém uma lista de múltiplos que podem ser usados para valores de escala. ou seja, neste caso, 2, 4, 6 seriam ticks aceitáveis, assim como 20, 40, 60 ou 0,2, 0,4, 0,6. No entanto, 3, 6, 9 não seriam aceitáveis porque 3 não aparece na lista de etapas.ticker.MaxNLocator(self, nbins='auto', steps=[1, 2, 2.5, 5, 10])
nbins=auto
usa um algoritmo para determinar quantos tiques serão aceitáveis com base no comprimento do eixo. nbins=4
O tamanho da fonte do ticklabel é levado em consideração, mas o comprimento da string do tick não é (porque ainda não é conhecido). trama de mão.
fig, axs = plt.subplots(2, 2, figsize=(8, 5), tight_layout=True)
for n, ax in enumerate(axs.flat):
ax.plot(x1*10., y1)
formatter = matplotlib.ticker.FormatStrFormatter('%1.1f')
locator = matplotlib.ticker.MaxNLocator(nbins='auto', steps=[1, 4, 10])
axs[0, 1].xaxis.set_major_locator(locator)
axs[0, 1].xaxis.set_major_formatter(formatter)
formatter = matplotlib.ticker.FormatStrFormatter('%1.5f')
locator = matplotlib.ticker.AutoLocator()
axs[1, 0].xaxis.set_major_formatter(formatter)
axs[1, 0].xaxis.set_major_locator(locator)
formatter = matplotlib.ticker.FormatStrFormatter('%1.5f')
locator = matplotlib.ticker.MaxNLocator(nbins=4)
axs[1, 1].xaxis.set_major_formatter(formatter)
axs[1, 1].xaxis.set_major_locator(locator)
plt.show()
Por fim, podemos especificar funções para o formatador usando
matplotlib.ticker.FuncFormatter
. Além disso, como
matplotlib.ticker.StrMethodFormatter
, passar uma função criará automaticamente um matplotlib.ticker.FuncFormatter
.
def formatoddticks(x, pos):
"""Format odd tick positions."""
if x % 2:
return f'{x:1.2f}'
else:
return ''
fig, ax = plt.subplots(figsize=(5, 3), tight_layout=True)
ax.plot(x1, y1)
locator = matplotlib.ticker.MaxNLocator(nbins=6)
ax.xaxis.set_major_formatter(formatoddticks)
ax.xaxis.set_major_locator(locator)
plt.show()
Datetics #
Matplotlib pode aceitar datetime.datetime
e numpy.datetime64
objetos como argumentos de plotagem. Datas e horas requerem formatação especial, que muitas vezes pode se beneficiar da intervenção manual. Para ajudar, as datas possuem Localizadores e Formatadores especiais, definidos no matplotlib.dates
módulo.
Um exemplo simples é o seguinte. Observe como temos que girar os rótulos dos ticks para que eles não se sobreponham.
import datetime
fig, ax = plt.subplots(figsize=(5, 3), tight_layout=True)
base = datetime.datetime(2017, 1, 1, 0, 0, 1)
time = [base + datetime.timedelta(days=x) for x in range(len(x1))]
ax.plot(time, y1)
ax.tick_params(axis='x', rotation=70)
plt.show()
Podemos passar um formato para matplotlib.dates.DateFormatter
. Observe também que o dia 29 e o próximo mês estão muito próximos. Podemos corrigir isso usando a dates.DayLocator
classe, que nos permite especificar uma lista de dias do mês a ser usada. Formatadores semelhantes são listados no matplotlib.dates
módulo.
import matplotlib.dates as mdates
locator = mdates.DayLocator(bymonthday=[1, 15])
formatter = mdates.DateFormatter('%b %d')
fig, ax = plt.subplots(figsize=(5, 3), tight_layout=True)
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(formatter)
ax.plot(time, y1)
ax.tick_params(axis='x', rotation=70)
plt.show()
Legendas e Anotações #
Legendas: Guia de lendas
Anotações: Anotações
Tempo total de execução do script: ( 0 minutos 5,998 segundos)