Posicionando Caixas de Texto em Matplotlib

Beginner

This tutorial is from open-source community. Access the source code

Introdução

Ao criar visualizações de dados, adicionar anotações pode melhorar significativamente a compreensão dos seus gráficos por parte do visualizador. Caixas de texto são uma forma eficaz de incluir informações adicionais diretamente dentro das suas visualizações. Matplotlib, uma popular biblioteca Python para criar visualizações estáticas, animadas e interativas, oferece ferramentas poderosas para adicionar caixas de texto personalizáveis aos seus gráficos.

Neste laboratório, você aprenderá como colocar caixas de texto em gráficos Matplotlib usando Python. Você descobrirá como posicionar texto em coordenadas de eixos, o que mantém o texto em uma posição fixa em relação ao gráfico, independentemente das alterações nas escalas de dados. Além disso, você aprenderá como personalizar caixas de texto com diferentes estilos, cores e níveis de transparência usando a propriedade bbox.

Ao final deste laboratório, você será capaz de criar gráficos informativos e visualmente atraentes com anotações estrategicamente posicionadas para seus projetos de visualização de dados.

Dicas para a VM

Após a inicialização da VM ser concluída, clique no canto superior esquerdo para mudar para a aba Notebook para acessar o Jupyter Notebook para praticar.

click-notebook

Você pode precisar esperar alguns segundos para que o Jupyter Notebook termine de carregar. Devido a limitações no Jupyter Notebook, a validação das operações não pode ser automatizada.

Se você encontrar algum problema durante o laboratório, sinta-se à vontade para pedir ajuda ao Labby. Agradecemos seu feedback após a sessão para nos ajudar a melhorar a experiência do laboratório.

Criando um Jupyter Notebook e Preparando os Dados

Neste primeiro passo, criaremos um novo Jupyter Notebook e configuraremos nossos dados para visualização.

Criando um Novo Notebook

Na primeira célula do notebook, vamos importar as bibliotecas necessárias. Digite o seguinte código e execute-o clicando no botão "Run" ou pressionando Shift+Enter:

import matplotlib.pyplot as plt
import numpy as np
libraries-imported

Este código importa duas bibliotecas essenciais:

  • matplotlib.pyplot: Uma coleção de funções que fazem o matplotlib funcionar como o MATLAB
  • numpy: Um pacote fundamental para computação científica em Python

Criando Dados de Amostra

Agora, vamos criar alguns dados de amostra que visualizaremos. Em uma nova célula, insira e execute o seguinte código:

## Set a random seed for reproducibility
np.random.seed(19680801)

## Generate 10,000 random numbers from a normal distribution
x = 30 * np.random.randn(10000)

## Calculate basic statistics
mu = x.mean()
median = np.median(x)
sigma = x.std()

## Display the statistics
print(f"Mean (μ): {mu:.2f}")
print(f"Median: {median:.2f}")
print(f"Standard Deviation (σ): {sigma:.2f}")

Ao executar esta célula, você deverá ver uma saída semelhante a:

Mean (μ): -0.31
Median: -0.28
Standard Deviation (σ): 29.86

Os valores exatos podem variar ligeiramente. Criamos um conjunto de dados com 10.000 números aleatórios gerados a partir de uma distribuição normal e calculamos três estatísticas importantes:

  1. Média (μ): O valor médio de todos os pontos de dados
  2. Mediana: O valor do meio quando os dados são organizados em ordem
  3. Desvio Padrão (σ): Uma medida de quão dispersos os dados estão

Essas estatísticas serão usadas posteriormente para anotar nossa visualização.

Criando um Histograma Básico

Agora que temos nossos dados, vamos criar um histograma para visualizar sua distribuição. Um histograma divide os dados em bins (intervalos) e mostra a frequência de pontos de dados dentro de cada bin.

Criando o Histograma

Em uma nova célula no seu Jupyter Notebook, insira e execute o seguinte código:

## Create a figure and axes
fig, ax = plt.subplots(figsize=(10, 6))

## Create a histogram with 50 bins
histogram = ax.hist(x, bins=50, color='skyblue', edgecolor='black')

## Add title and labels
ax.set_title('Distribution of Random Data', fontsize=16)
ax.set_xlabel('Value', fontsize=12)
ax.set_ylabel('Frequency', fontsize=12)

## Display the plot
plt.tight_layout()
plt.show()

Ao executar esta célula, você deverá ver um histograma exibindo a distribuição dos seus dados aleatórios. A saída terá a aparência de uma curva em forma de sino (distribuição normal) centrada perto de zero.

Entendendo o Código

Vamos detalhar o que cada linha do código faz:

  1. fig, ax = plt.subplots(figsize=(10, 6)): Cria um objeto figura e eixos. O parâmetro figsize define o tamanho do gráfico em polegadas (largura, altura).

  2. histogram = ax.hist(x, bins=50, color='skyblue', edgecolor='black'): Cria um histograma dos nossos dados x com 50 bins. Os bins são coloridos em skyblue com bordas pretas.

  3. ax.set_title('Distribution of Random Data', fontsize=16): Adiciona um título ao gráfico com um tamanho de fonte de 16.

  4. ax.set_xlabel('Value', fontsize=12) e ax.set_ylabel('Frequency', fontsize=12): Adicionam rótulos aos eixos x e y com um tamanho de fonte de 12.

  5. plt.tight_layout(): Ajusta automaticamente o gráfico para caber na área da figura.

  6. plt.show(): Exibe o gráfico.

O histograma mostra como nossos dados são distribuídos. Como usamos np.random.randn(), que gera dados de uma distribuição normal, o histograma tem uma forma de sino centrada em torno de 0. A altura de cada barra representa quantos pontos de dados caem dentro daquele intervalo.

Adicionando uma Caixa de Texto com Estatísticas

Agora que temos um histograma básico, vamos aprimorá-lo adicionando uma caixa de texto que exibe as informações estatísticas sobre nossos dados. Isso tornará a visualização mais informativa para os espectadores.

Criando o Conteúdo do Texto

Primeiro, precisamos preparar o conteúdo do texto que irá dentro da nossa caixa de texto. Em uma nova célula, insira e execute o seguinte código:

## Create a string with the statistics
textstr = '\n'.join((
    r'$\mu=%.2f$' % (mu,),           ## Mean
    r'$\mathrm{median}=%.2f$' % (median,),  ## Median
    r'$\sigma=%.2f$' % (sigma,)       ## Standard deviation
))

print("Text content for our box:")
print(textstr)

Você deverá ver uma saída semelhante a:

Text content for our box:
$\mu=-0.31$
$\mathrm{median}=-0.28$
$\sigma=29.86$

Este código cria uma string de várias linhas contendo a média, a mediana e o desvio padrão dos nossos dados. Vamos examinar alguns aspectos interessantes deste código:

  1. O método \n'.join(...) junta várias strings com um caractere de nova linha entre elas.
  2. O r antes de cada string a torna uma string "raw", o que é útil ao incluir caracteres especiais.
  3. A notação $...$ é usada para formatação matemática no estilo LaTeX em matplotlib.
  4. \mu e \sigma são símbolos LaTeX para as letras gregas μ (mu) e σ (sigma).
  5. %.2f é um especificador de formatação que exibe um número de ponto flutuante com duas casas decimais.

Criando e Adicionando a Caixa de Texto

Agora, vamos recriar nosso histograma e adicionar a caixa de texto a ele. Em uma nova célula, insira e execute o seguinte código:

## Create a new figure and axes
fig, ax = plt.subplots(figsize=(10, 6))

## Create a histogram with 50 bins
histogram = ax.hist(x, bins=50, color='skyblue', edgecolor='black')

## Add title and labels
ax.set_title('Distribution of Random Data with Statistics', fontsize=16)
ax.set_xlabel('Value', fontsize=12)
ax.set_ylabel('Frequency', fontsize=12)

## Define the properties of the text box
properties = dict(boxstyle='round', facecolor='wheat', alpha=0.5)

## Add the text box to the plot
## Position the box in the top left corner (0.05, 0.95) in axes coordinates
ax.text(0.05, 0.95, textstr, transform=ax.transAxes, fontsize=14,
        verticalalignment='top', bbox=properties)

## Display the plot
plt.tight_layout()
plt.show()

Ao executar esta célula, você deverá ver seu histograma com uma caixa de texto no canto superior esquerdo exibindo as estatísticas.

Entendendo o Código da Caixa de Texto

Vamos detalhar as partes importantes do código que criam a caixa de texto:

  1. properties = dict(boxstyle='round', facecolor='wheat', alpha=0.5):

    • Isso cria um dicionário com propriedades para a caixa de texto.
    • boxstyle='round': Faz com que a caixa tenha cantos arredondados.
    • facecolor='wheat': Define a cor de fundo da caixa para trigo.
    • alpha=0.5: Torna a caixa semi-transparente (50% de opacidade).
  2. ax.text(0.05, 0.95, textstr, transform=ax.transAxes, fontsize=14, verticalalignment='top', bbox=properties):

    • Isso adiciona texto aos eixos na posição (0.05, 0.95).
    • transform=ax.transAxes: Isso é crucial - significa que as coordenadas estão em unidades de eixos (0-1) em vez de unidades de dados. Portanto, (0.05, 0.95) significa "5% da borda esquerda e 95% da borda inferior do gráfico."
    • fontsize=14: Define o tamanho da fonte.
    • verticalalignment='top': Alinha o texto para que a parte superior do texto esteja na coordenada y especificada.
    • bbox=properties: Aplica nossas propriedades da caixa de texto.

A caixa de texto permanecerá na mesma posição em relação aos eixos do gráfico, mesmo que você amplie o gráfico ou altere a faixa de dados. Isso ocorre porque usamos transform=ax.transAxes, que usa coordenadas de eixos em vez de coordenadas de dados.

Personalizando a Caixa de Texto

Agora que adicionamos com sucesso uma caixa de texto ao nosso gráfico, vamos explorar várias opções de personalização para torná-la mais visualmente atraente e adequada para diferentes contextos.

Experimentando com Diferentes Estilos

Vamos criar uma função para facilitar a experimentação com diferentes estilos de caixa de texto. Em uma nova célula, insira e execute o seguinte código:

def plot_with_textbox(boxstyle, facecolor, alpha, position=(0.05, 0.95)):
    """
    Create a histogram with a custom text box.

    Parameters:
    boxstyle (str): Style of the box ('round', 'square', 'round4', etc.)
    facecolor (str): Background color of the box
    alpha (float): Transparency of the box (0-1)
    position (tuple): Position of the box in axes coordinates (x, y)
    """
    ## Create figure and plot
    fig, ax = plt.subplots(figsize=(8, 5))
    ax.hist(x, bins=50, color='skyblue', edgecolor='black')

    ## Set title and labels
    ax.set_title(f'Text Box Style: {boxstyle}', fontsize=16)
    ax.set_xlabel('Value', fontsize=12)
    ax.set_ylabel('Frequency', fontsize=12)

    ## Create text box properties
    box_props = dict(boxstyle=boxstyle, facecolor=facecolor, alpha=alpha)

    ## Add text box
    ax.text(position[0], position[1], textstr, transform=ax.transAxes,
            fontsize=14, verticalalignment='top', bbox=box_props)

    plt.tight_layout()
    plt.show()

Agora, vamos usar esta função para experimentar diferentes estilos de caixa. Em uma nova célula, insira e execute:

## Try a square box with light green color
plot_with_textbox('square', 'lightgreen', 0.7)

## Try a rounded box with light blue color
plot_with_textbox('round', 'lightblue', 0.5)

## Try a box with extra rounded corners
plot_with_textbox('round4', 'lightyellow', 0.6)

## Try a sawtooth style box
plot_with_textbox('sawtooth', 'lightcoral', 0.4)

Ao executar esta célula, você verá quatro gráficos diferentes, cada um com um estilo de caixa de texto diferente.

Alterando a Posição da Caixa de Texto

A posição de uma caixa de texto pode ser crucial para a visualização. Vamos colocar caixas de texto em diferentes cantos do gráfico. Em uma nova célula, insira e execute:

## Create a figure with a 2x2 grid of subplots
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
axes = axes.flatten()  ## Flatten to easily iterate

## Define positions for the four corners
positions = [
    (0.05, 0.95),  ## Top left
    (0.95, 0.95),  ## Top right
    (0.05, 0.05),  ## Bottom left
    (0.95, 0.05)   ## Bottom right
]

## Define alignments for each position
alignments = [
    ('top', 'left'),          ## Top left
    ('top', 'right'),         ## Top right
    ('bottom', 'left'),       ## Bottom left
    ('bottom', 'right')       ## Bottom right
]

## Corner labels
corner_labels = ['Top Left', 'Top Right', 'Bottom Left', 'Bottom Right']

## Create four plots with text boxes in different corners
for i, ax in enumerate(axes):
    ## Plot histogram
    ax.hist(x, bins=50, color='skyblue', edgecolor='black')

    ## Set title
    ax.set_title(f'Text Box in {corner_labels[i]}', fontsize=14)

    ## Create text box properties
    box_props = dict(boxstyle='round', facecolor='wheat', alpha=0.5)

    ## Add text box
    ax.text(positions[i][0], positions[i][1], textstr,
            transform=ax.transAxes, fontsize=12,
            verticalalignment=alignments[i][0],
            horizontalalignment=alignments[i][1],
            bbox=box_props)

plt.tight_layout()
plt.show()

Este código cria uma grade 2x2 de histogramas, cada um com uma caixa de texto em um canto diferente.

Entendendo o Posicionamento da Caixa de Texto

Existem vários parâmetros-chave que controlam o posicionamento da caixa de texto:

  1. Coordenadas de posição: As coordenadas (x, y) determinam onde a caixa de texto é colocada. Ao usar transform=ax.transAxes, estas estão em coordenadas de eixos, onde (0, 0) é o canto inferior esquerdo e (1, 1) é o canto superior direito.

  2. Alinhamento vertical: O parâmetro verticalalignment controla como o texto é alinhado verticalmente em relação à coordenada y:

    • 'top': A parte superior do texto está na coordenada y especificada.
    • 'center': O centro do texto está na coordenada y especificada.
    • 'bottom': A parte inferior do texto está na coordenada y especificada.
  3. Alinhamento horizontal: O parâmetro horizontalalignment controla como o texto é alinhado horizontalmente em relação à coordenada x:

    • 'left': A borda esquerda do texto está na coordenada x especificada.
    • 'center': O centro do texto está na coordenada x especificada.
    • 'right': A borda direita do texto está na coordenada x especificada.

Essas opções de alinhamento são particularmente importantes ao colocar texto nos cantos. Por exemplo, no canto superior direito, você gostaria de usar horizontalalignment='right' para que a borda direita do texto se alinhe com a borda direita do gráfico.

Criando uma Visualização Final com Múltiplos Elementos de Texto

Nesta etapa final, combinaremos tudo o que aprendemos para criar uma visualização abrangente que inclui múltiplos elementos de texto com diferentes estilos. Isso demonstrará como as caixas de texto podem ser usadas para aprimorar a narrativa de dados.

Criando uma Visualização Avançada

Vamos criar um gráfico mais sofisticado que inclua nosso histograma e alguns elementos visuais adicionais. Em uma nova célula, insira e execute o seguinte código:

## Create a figure with a larger size for our final visualization
fig, ax = plt.subplots(figsize=(12, 8))

## Plot the histogram with more bins and a different color
n, bins, patches = ax.hist(x, bins=75, color='lightblue',
                           edgecolor='darkblue', alpha=0.7)

## Add title and labels with improved styling
ax.set_title('Distribution of Random Data with Statistical Annotations',
             fontsize=18, fontweight='bold', pad=20)
ax.set_xlabel('Value', fontsize=14)
ax.set_ylabel('Frequency', fontsize=14)

## Add grid for better readability
ax.grid(True, linestyle='--', alpha=0.7)

## Mark the mean with a vertical line
ax.axvline(x=mu, color='red', linestyle='-', linewidth=2,
           label=f'Mean: {mu:.2f}')

## Mark one standard deviation range
ax.axvline(x=mu + sigma, color='green', linestyle='--', linewidth=1.5,
           label=f'Mean + 1σ: {mu+sigma:.2f}')
ax.axvline(x=mu - sigma, color='green', linestyle='--', linewidth=1.5,
           label=f'Mean - 1σ: {mu-sigma:.2f}')

## Create a text box with statistics in the top left
stats_box_props = dict(boxstyle='round', facecolor='lightyellow',
                      alpha=0.8, edgecolor='gold', linewidth=2)

stats_text = '\n'.join((
    r'$\mathbf{Statistics:}$',
    r'$\mu=%.2f$ (mean)' % (mu,),
    r'$\mathrm{median}=%.2f$' % (median,),
    r'$\sigma=%.2f$ (std. dev.)' % (sigma,)
))

ax.text(0.05, 0.95, stats_text, transform=ax.transAxes, fontsize=14,
        verticalalignment='top', bbox=stats_box_props)

## Add an informational text box in the top right
info_box_props = dict(boxstyle='round4', facecolor='lightcyan',
                     alpha=0.8, edgecolor='deepskyblue', linewidth=2)

info_text = '\n'.join((
    r'$\mathbf{About\ Normal\ Distributions:}$',
    r'$\bullet\ 68\%\ of\ data\ within\ 1\sigma$',
    r'$\bullet\ 95\%\ of\ data\ within\ 2\sigma$',
    r'$\bullet\ 99.7\%\ of\ data\ within\ 3\sigma$'
))

ax.text(0.95, 0.95, info_text, transform=ax.transAxes, fontsize=14,
        verticalalignment='top', horizontalalignment='right',
        bbox=info_box_props)

## Add a legend
ax.legend(fontsize=12)

## Tighten the layout and show the plot
plt.tight_layout()
plt.show()

Ao executar esta célula, você verá uma visualização abrangente com:

  • Um histograma dos dados com estilo aprimorado
  • Linhas verticais marcando a média e a faixa de um desvio padrão
  • Uma caixa de texto de estatísticas no canto superior esquerdo
  • Uma caixa de texto informativa sobre distribuições normais no canto superior direito
  • Uma legenda explicando as linhas verticais

Entendendo os Elementos Avançados

Vamos examinar alguns dos novos elementos que adicionamos:

  1. Linhas Verticais com axvline():

    • Essas linhas marcam estatísticas importantes diretamente no gráfico.
    • O parâmetro label permite que essas linhas sejam incluídas na legenda.
  2. Múltiplas Caixas de Texto com Diferentes Estilos:

    • Cada caixa de texto serve a um propósito diferente e usa um estilo distinto.
    • A caixa de estatísticas mostra os valores calculados a partir de nossos dados.
    • A caixa informativa fornece contexto sobre distribuições normais.
  3. Formatação Aprimorada:

    • A formatação LaTeX é usada para criar texto em negrito com \mathbf{}
    • Marcadores são criados com \bullet
    • O espaçamento é controlado com \ (barra invertida seguida de um espaço)
  4. Grade e Legenda:

    • A grade ajuda os espectadores a ler os valores do gráfico com mais precisão.
    • A legenda explica o significado das linhas coloridas.

Notas Finais sobre o Posicionamento da Caixa de Texto

Ao colocar múltiplos elementos de texto em uma visualização, considere:

  1. Hierarquia visual: A informação mais importante deve se destacar mais.
  2. Posicionamento: Coloque informações relacionadas perto das partes relevantes da visualização.
  3. Contraste: Certifique-se de que o texto seja legível em relação ao seu fundo.
  4. Consistência: Use um estilo consistente para tipos semelhantes de informações.
  5. Desordem: Evite sobrecarregar a visualização com muitos elementos de texto.

Ao colocar e estilizar cuidadosamente as caixas de texto, você pode criar visualizações que são informativas e visualmente atraentes, guiando os espectadores a entender as principais informações de seus dados.

Resumo

Neste laboratório, você aprendeu a usar efetivamente caixas de texto no Matplotlib para aprimorar suas visualizações de dados. Vamos recapitular os pontos-chave:

Conceitos-Chave Cobertos

  1. Criando Caixas de Texto Básicas: Você aprendeu a adicionar caixas de texto aos gráficos usando a função matplotlib.pyplot.text() com o parâmetro bbox.

  2. Posicionamento da Caixa de Texto: Você descobriu como posicionar caixas de texto usando coordenadas de eixos com transform=ax.transAxes, que mantém o texto em uma posição fixa, independentemente da escala dos dados.

  3. Estilização da Caixa de Texto: Você explorou como personalizar caixas de texto com diferentes estilos (boxstyle), cores (facecolor), níveis de transparência (alpha) e propriedades de borda.

  4. Alinhamento de Texto: Você praticou o uso de verticalalignment e horizontalalignment para posicionar corretamente o texto em diferentes partes de sua visualização.

  5. Formatação LaTeX: Você utilizou a notação LaTeX para adicionar símbolos matemáticos e formatação ao seu texto.

  6. Visualização Abrangente: Você criou uma visualização completa que combina múltiplos elementos de texto com diferentes estilos para contar uma história de dados coesa.

Aplicações Práticas

As técnicas que você aprendeu neste laboratório podem ser aplicadas a:

  • Adicionar resumos estatísticos aos gráficos
  • Rotular recursos-chave em seus dados
  • Fornecer contexto ou explicações dentro das visualizações
  • Criar legendas ou chaves com formatação personalizada
  • Destacar descobertas ou insights importantes

Próximos Passos

Para aprimorar ainda mais suas habilidades de visualização de dados com Matplotlib, considere explorar:

  • Técnicas avançadas de anotação, como setas e caixas de anotação
  • Elementos de texto interativos usando o tratamento de eventos do Matplotlib
  • Personalizar texto com diferentes fontes e estilos
  • Criar subplots com anotações coordenadas
  • Salvar suas visualizações com elementos de texto para publicação

Ao dominar a arte das anotações de texto no Matplotlib, você pode criar visualizações de dados mais informativas e profissionais que comunicam efetivamente seus insights ao seu público.