Introdução ao Matplotlib
Matplotlib é uma das bibliotecas mais influentes e versáteis para visualização de dados em Python. Ela fornece uma base robusta para a criação de gráficos estáticos, interativos e animados, sendo uma ferramenta indispensável para analistas de dados, cientistas e engenheiros. Com sua API flexível, é possível personalizar cada aspecto de um gráfico para atender a requisitos específicos de apresentação e análise.
Para iniciar, é fundamental importar os módulos necessários. O matplotlib.pyplot, geralmente importado como plt, oferece uma interface de alto nível para plotagem, enquanto pandas e numpy são comumente usados para manipulação e geração de dados.
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
Preparação de Dados: Conversão de Tipos
Antes de plotar, a preparação dos dados é crucial. Um passo frequente envolve a conversão de colunas de strings que representam datas para o tipo datetime do Pandas, o que permite plotagens cronológicas precisas.
# Carrega um conjunto de dados de exemplo com informações de desemprego
# Assumindo que 'unrate.csv' contém colunas 'DATE' (string) e 'VALUE' (numérica).
registro_desemprego = pd.read_csv("unrate.csv")
registro_desemprego["DATA_REGISTRO"] = pd.to_datetime(registro_desemprego["DATE"])
# A coluna 'DATA_REGISTRO' está agora pronta para uso em eixos temporais.
Gráfico de Linhas Simples
O gráfico de linhas é ideal para visualizar tendências e mudanças ao longo do tempo. É a forma mais básica de exibir a relação entre uma variável contínua (eixo X) e outra (eixo Y).
# Seleciona os primeiros 12 registros (ex: dados de um ano)
periodo_inicial = registro_desemprego.iloc[0:12]
plt.figure(figsize=(8, 5))
plt.plot(periodo_inicial["DATA_REGISTRO"], periodo_inicial["VALUE"], marker='o', linestyle='-', color='darkcyan')
plt.xticks(rotation=45, ha='right', fontsize=9) # Rotaciona rótulos do eixo X e ajusta alinhamento
plt.xlabel("Período Mensal", fontsize=11)
plt.ylabel("Taxa de Valor", fontsize=11)
plt.title("Variação da Taxa de Desemprego no Primeiro Ano", fontsize=13)
plt.grid(True, linestyle='--', alpha=0.6) # Adiciona uma grade para facilitar a leitura
plt.tight_layout() # Ajusta o layout para evitar sobreposição
plt.show()
Múltiplos Subplots em uma Figura
Para comparar diferentes conjuntos de dados ou visualizar diversas facetas de um mesmo dado, podemos organizar múltiplos gráficos em uma única figura usando subplots.
# Cria uma figura e adiciona dois subplots organizados em 2 linhas e 1 coluna
figura_multipla = plt.figure(figsize=(8, 6))
eixo_superior = figura_multipla.add_subplot(2, 1, 1) # Primeiro subplot (topo)
eixo_inferior = figura_multipla.add_subplot(2, 1, 2) # Segundo subplot (base)
# Plota dados aleatórios no subplot superior
eixo_superior.plot(np.arange(8), np.random.rand(8) * 10, color='purple', linestyle='--', marker='^')
eixo_superior.set_title("Série Aleatória Superior", fontsize=12)
eixo_superior.set_ylabel("Valores Aleatórios")
eixo_superior.grid(axis='y', linestyle=':', alpha=0.7)
# Plota outros dados aleatórios no subplot inferior
eixo_inferior.plot(np.arange(15), np.random.randint(5, 15, 15), color='darkgreen', marker='s')
eixo_inferior.set_title("Série Aleatória Inferior", fontsize=12)
eixo_inferior.set_xlabel("Índice")
eixo_inferior.set_ylabel("Contagem")
eixo_inferior.grid(axis='y', linestyle=':', alpha=0.7)
plt.tight_layout() # Ajusta o layout automaticamente
plt.show()
Plotagem de Múltiplas Linhas em um Único Gráfico
É comum precisar visualizar múltiplas séries de dados no mesmo gráfico para facilitar a comparação direta entre elas.
# Define o tamanho da figura para melhor visualização
figura_unica = plt.figure(figsize=(9, 5))
# Primeiro segmento de dados (ex: primeiro ano)
segmento_um = registro_desemprego.iloc[0:12].copy()
segmento_um["MES"] = segmento_um["DATA_REGISTRO"].dt.month
plt.plot(segmento_um["MES"], segmento_um["VALUE"], color="crimson", label="Primeiro Ano (1948)", linewidth=2)
# Segundo segmento de dados (ex: segundo ano)
segmento_dois = registro_desemprego.iloc[12:24].copy()
segmento_dois["MES"] = segmento_dois["DATA_REGISTRO"].dt.month
plt.plot(segmento_dois["MES"], segmento_dois["VALUE"], color="steelblue", label="Segundo Ano (1949)", linewidth=2)
plt.xticks(np.arange(1, 13), rotation=45, fontsize=9) # Define ticks para meses de 1 a 12
plt.xlabel("Mês do Ano", fontsize=11)
plt.ylabel("Nível de Valor", fontsize=11)
plt.title("Comparativo de Valores por Mês (1948 vs. 1949)", fontsize=13)
plt.legend(loc='upper right', fontsize=10) # Adiciona legenda para identificar as linhas
plt.grid(axis='y', linestyle=':', alpha=0.7)
plt.tight_layout()
plt.show()
Automação da Plotagem de Múltiplas Séries com Legendas
Para cenários com muitas séries a serem plotadas, um loop pode automatizar o processo, especialmente útil quando se precisa de legendas dinâmicas para cada série.
figura_automatizada = plt.figure(figsize=(12, 7))
paleta_cores = ['#e41a1c', '#377eb8', '#4daf4a', '#984ea3', '#ff7f00'] # Cores personalizadas
anos_exibidos = []
for idx in range(5):
inicio_intervalo = idx * 12
fim_intervalo = (idx + 1) * 12
dados_ano = registro_desemprego.iloc[inicio_intervalo : fim_intervalo].copy()
dados_ano['MES'] = dados_ano['DATA_REGISTRO'].dt.month
ano_referencia = str(1948 + idx)
plt.plot(dados_ano['MES'], dados_ano['VALUE'], color=paleta_cores[idx], label=ano_referencia, linewidth=2.5)
anos_exibidos.append(ano_referencia)
plt.xlabel("Mês", fontsize=11)
plt.ylabel("Valor", fontsize=11)
plt.title("Evolução Mensal de Valores ao Longo de Múltiplos Anos", fontsize=13)
# Legenda posicionada fora do gráfico para não sobrepor os dados
plt.legend(title="Anos", loc='upper left', bbox_to_anchor=(1.01, 1), borderaxespad=0., fontsize=10)
plt.grid(axis='y', linestyle='--', alpha=0.6)
plt.xticks(np.arange(1, 13), fontsize=9)
plt.yticks(fontsize=9)
plt.tight_layout(rect=[0, 0, 0.88, 1]) # Ajusta layout considerando a legenda externa
plt.show()
Gráficos de Barras Verticais
Gráficos de barras são eficazes para comparar quantidades entre diferentes categorias ou para mostrar mudanças discretas ao longo do tempo. O Matplotlib permite um controle detalhado sobre a largura, cor e posicionamento das barras.
# Simulação de dados de avaliação, pois o DataFrame 'fand_new' não está disponível
dados_avaliacoes = pd.DataFrame({
'Fandango_Stars': [4.5, 3.0, 4.0, 3.5, 5.0],
'Fandango_Ratingvalue': [4.3, 2.8, 3.8, 3.3, 4.8],
'Metacritic_norm': [3.5, 2.5, 3.0, 2.8, 4.0],
'RT_user_norm_round': [3.8, 2.9, 3.5, 3.1, 4.2],
'IMDB_norm_round': [4.0, 3.1, 3.7, 3.2, 4.5]
}, index=[0, 1, 2, 3, 4]) # Adiciona um índice para simular .ix[0, ...]
categorias_criticas = ['Fandango_Stars', 'Fandango_Ratingvalue', 'Metacritic_norm', 'RT_user_norm_round', 'IMDB_norm_round']
# Valores para as barras (ex: a primeira linha do DataFrame de avaliações)
alturas_barras = dados_avaliacoes.loc[0, categorias_criticas].values
posicoes_eixo = np.arange(len(categorias_criticas)) # Posições no eixo X
rotulos_categorias = [cat.replace('_', ' ').replace('norm round', '(Norm.)') for cat in categorias_criticas]
fig, ax_barras = plt.subplots(figsize=(10, 6))
ax_barras.bar(posicoes_eixo, alturas_barras, width=0.7, color='teal', edgecolor='black', alpha=0.8)
ax_barras.set_xticks(posicoes_eixo)
ax_barras.set_xticklabels(rotulos_categorias, rotation=45, ha='right', fontsize=10)
ax_barras.set_xlabel('Fonte da Avaliação', fontsize=11)
ax_barras.set_ylabel('Média de Avaliação', fontsize=11)
ax_barras.set_title('Média de Avaliações para "Filme Fictício" (Vertical)', fontsize=13)
ax_barras.yaxis.grid(True, linestyle='--', alpha=0.7) # Grade horizontal
plt.tight_layout()
plt.show()
Gráficos de Barras Horizontais
Para rótulos de categoria longos ou quando se deseja uma leitura mais fluida, gráficos de barras horizontais podem ser mais legíveis. A criação é similar aos gráficos de barras verticais, utilizando a função barh.
# Reutiliza os dados e variáveis do exemplo de barras verticais
# dados_avaliacoes, categorias_criticas, alturas_barras, rotulos_categorias
posicoes_eixo_h = np.arange(len(categorias_criticas)) # Posições no eixo Y para barras horizontais
fig, ax_barras_h = plt.subplots(figsize=(10, 6))
ax_barras_h.barh(posicoes_eixo_h, alturas_barras, height=0.7, color='lightcoral', edgecolor='black', alpha=0.8) # Barras horizontais
ax_barras_h.set_yticks(posicoes_eixo_h)
ax_barras_h.set_yticklabels(rotulos_categorias, fontsize=10) # Rótulos no eixo Y
ax_barras_h.set_xlabel('Média de Avaliação', fontsize=11)
ax_barras_h.set_ylabel('Fonte da Avaliação', fontsize=11)
ax_barras_h.set_title('Média de Avaliações para "Filme Fictício" (Horizontal)', fontsize=13)
ax_barras_h.xaxis.grid(True, linestyle='--', alpha=0.7) # Grade vertical
plt.tight_layout()
plt.show()
Gráficos de Dispersão
Gráficos de dispersão são excelentes para visualizar a relação ou correlação entre duas variáveis numéricas. Cada ponto no gráfico representa um par de valores das duas variáveis.
fig, ax_dispersao = plt.subplots(figsize=(8, 6))
# Plota as avaliações Fandango vs. Metacritic
ax_dispersao.scatter(dados_avaliacoes['Fandango_Stars'], dados_avaliacoes['Metacritic_norm'],
color='darkmagenta', alpha=0.7, s=120, edgecolor='black', linewidth=0.8)
ax_dispersao.set_xlabel('Avaliação Fandango', fontsize=11)
ax_dispersao.set_ylabel('Avaliação Metacritic (Normalizada)', fontsize=11)
ax_dispersao.set_title('Relação entre Avaliações Fandango e Metacritic', fontsize=13)
ax_dispersao.grid(True, linestyle=':', alpha=0.5)
plt.show()
Histogramas para Distribuição
Histogramas são usados para mostrar a distribuição de uma única variável numérica, agrupando valores em "bins" (intervalos). Eles revelam a frequência com que os dados caem dentro de cada intervalo.
fig, ax_hist = plt.subplots(figsize=(8, 5))
# Plota um histograma da distribuição das estrelas do Fandango
ax_hist.hist(dados_avaliacoes['Fandango_Stars'], bins=5, range=(2.5, 5.5), color='darkgreen', edgecolor='black', alpha=0.8)
ax_hist.set_xlabel('Estrelas Fandango', fontsize=11)
ax_hist.set_ylabel('Frequência', fontsize=11)
ax_hist.set_title('Distribuição de Estrelas Fandango', fontsize=13)
ax_hist.set_xticks(np.arange(3, 5.5, 0.5)) # Ajusta os ticks do eixo X
plt.grid(axis='y', linestyle='--', alpha=0.6)
plt.show()
Múltiplos Histogramas em Subplots
Para comparar distribuições de diferentes variáveis, é útil usar múltiplos histogramas organizados em subplots na mesma figura.
fig_multi_hist, eixos_hists = plt.subplots(2, 2, figsize=(14, 12)) # Cria uma grade 2x2 de subplots
# Ajusta o espaçamento entre subplots
fig_multi_hist.subplots_adjust(hspace=0.4, wspace=0.3)
# Lista de colunas para histogramas
colunas_para_hists = ['Fandango_Stars', 'IMDB_norm_round', 'Metacritic_norm', 'RT_user_norm_round']
titulos_hists = ['Estrelas Fandango', 'Avaliações IMDB (Norm.)', 'Avaliações Metacritic (Norm.)', 'Avaliações RT Usuário (Norm.)']
cores_hists = ['skyblue', 'lightgreen', 'lightcoral', 'orchid']
for i, ax_hist_single in enumerate(eixos_hists.flatten()): # Itera sobre os subplots achatados
coluna = colunas_para_hists[i]
titulo = titulos_hists[i]
cor = cores_hists[i]
ax_hist_single.hist(dados_avaliacoes[coluna], bins=15, range=(0, 5), color=cor, edgecolor='black', alpha=0.8)
ax_hist_single.set_title(f'Distribuição de {titulo}', fontsize=12)
ax_hist_single.set_xlabel('Pontuação Normalizada (0-5)', fontsize=10)
ax_hist_single.set_ylabel('Frequência', fontsize=10)
ax_hist_single.set_ylim(0, 50) # Mantém o limite do Y para comparação
ax_hist_single.grid(axis='y', linestyle=':', alpha=0.6)
plt.show()
Gráficos de Caixa (Box Plot)
Box plots (ou diagramas de caixa) são eficazes para visualizar a distribuição, mediana, quartis e identificar outliers de uma ou mais variáveis. Eles resumem a distribuição de dados de forma compacta.
fig, ax_boxplot = plt.subplots(figsize=(7, 6))
# Plota um box plot para a coluna 'Metacritic_norm'
ax_boxplot.boxplot(dados_avaliacoes['Metacritic_norm'], patch_artist=True, # Preenche as caixas
boxprops=dict(facecolor='lightblue', edgecolor='blue', linewidth=1.5), # Propriedades da caixa
medianprops=dict(color='red', linewidth=2)) # Propriedades da linha da mediana
ax_boxplot.set_xticklabels(['Metacritic (Norm.)'], fontsize=10) # Rótulo do eixo X
ax_boxplot.set_ylabel('Pontuação Normalizada', fontsize=11)
ax_boxplot.set_ylim(0, 5) # Limite do eixo Y
ax_boxplot.set_title('Distribuição da Avaliação Metacritic', fontsize=13)
ax_boxplot.grid(axis='y', linestyle='--', alpha=0.6)
plt.show()
Múltiplos Box Plots a partir de Dados de Múltiplas Colunas
É possível gerar box plots para múltiplas colunas de um DataFrame simultaneamente, agrupando-os na mesma figura para uma comparação visual rápida entre as distribuições.
colunas_numericas_avaliacoes = ['Fandango_Stars', 'IMDB_norm_round', 'Metacritic_norm', 'RT_user_norm_round']
fig, ax_multi_boxplot = plt.subplots(figsize=(12, 7))
# Plota múltiplos box plots lado a lado
ax_multi_boxplot.boxplot(dados_avaliacoes[colunas_numericas_avaliacoes].values,
patch_artist=True,
boxprops=dict(facecolor='lightgray', edgecolor='darkgray'),
medianprops=dict(color='darkblue', linewidth=2),
whiskerprops=dict(color='gray'),
capprops=dict(color='gray'))
ax_multi_boxplot.set_xticklabels(colunas_numericas_avaliacoes, rotation=45, ha='right', fontsize=10)
ax_multi_boxplot.set_ylabel('Pontuação Normalizada (0-5)', fontsize=11)
ax_multi_boxplot.set_ylim(0, 5)
ax_multi_boxplot.set_title('Comparação da Distribuição de Diferentes Avaliações', fontsize=13)
ax_multi_boxplot.grid(axis='y', linestyle='--', alpha=0.6)
plt.tight_layout()
plt.show()
Personalizando a Estética para Gráficos Mais Limpos
Para gráficos destinados a relatórios ou publicações, remover elementos visuais desnecessários (como molduras e ticks) pode melhorar significativamente a clareza e o foco nos dados. Isso é frequentemente chamado de "despined" (sem espinhas).
# Simulação de dados para este exemplo (em um cenário real, você carregaria seu DataFrame)
mulheres_diplomas = pd.DataFrame({
'Year': np.arange(1970, 2012, 5),
'Biology': [29, 32, 40, 50, 60, 65, 68, 70, 65],
'Computer Science': [10, 15, 20, 25, 30, 28, 25, 20, 18],
'Engineering': [2, 5, 8, 12, 15, 18, 20, 22, 20],
'Math and Statistics': [35, 38, 42, 45, 48, 45, 42, 40, 38]
})
fig, ax_limpo = plt.subplots(figsize=(10, 6))
ax_limpo.plot(mulheres_diplomas['Year'], mulheres_diplomas['Biology'], color='blue', label='Mulheres', linewidth=2)
ax_limpo.plot(mulheres_diplomas['Year'], 100 - mulheres_diplomas['Biology'], color='green', label='Homens', linewidth=2)
# Remove os "spines" (bordas do gráfico)
for sp in ax_limpo.spines.values():
sp.set_visible(False)
# Remove os ticks de cima/baixo e esquerda/direita
ax_limpo.tick_params(bottom=False, top=False, left=False, right=False)
ax_limpo.legend(loc='upper right', frameon=False, fontsize=10) # Legenda sem moldura
ax_limpo.set_title("Percentual de Diplomas em Biologia por Gênero", fontsize=14)
ax_limpo.set_xlabel("Ano", fontsize=11)
ax_limpo.set_ylabel("Percentual de Diplomas", fontsize=11)
ax_limpo.grid(axis='y', linestyle=':', alpha=0.6)
plt.show()
Múltiplos Gráficos de Linha com Estilo Consistente (Loop)
Estender o estilo limpo para múltiplos gráficos pode ser feito eficientemente usando um loop e organizando os gráficos em subplots, garantindo consistência visual entre eles.
categorias_principais = ['Biology', 'Computer Science', 'Engineering', 'Math and Statistics']
fig_multi_limpo = plt.figure(figsize=(14, 10))
fig_multi_limpo.subplots_adjust(hspace=0.5, wspace=0.3)
for i, categoria in enumerate(categorias_principais):
ax_sub = fig_multi_limpo.add_subplot(2, 2, i + 1)
ax_sub.plot(mulheres_diplomas['Year'], mulheres_diplomas[categoria], color='cornflowerblue', label='Mulheres', linewidth=2)
ax_sub.plot(mulheres_diplomas['Year'], 100 - mulheres_diplomas[categoria], color='salmon', label='Homens', linewidth=2)
for sp in ax_sub.spines.values():
sp.set_visible(False)
ax_sub.set_xlim(1968, 2011)
ax_sub.set_ylim(0, 100)
ax_sub.set_title(f'Diplomas em {categoria}', fontsize=12)
ax_sub.tick_params(bottom=False, top=False, left=False, right=False, labelsize=9)
ax_sub.grid(axis='y', linestyle=':', alpha=0.5)
ax_sub.set_xlabel("Ano", fontsize=10)
ax_sub.set_ylabel("Percentual", fontsize=10)
if i == 0: # Adiciona legenda apenas no primeiro gráfico para evitar redundância
ax_sub.legend(loc='upper right', frameon=False, fontsize=9)
plt.show()
Cores Personalizadas para Melhor Contraste
A escolha de cores pode ter um grande impacto na legibilidade e acessibilidade do gráfico. Cores personalizadas, especialmente aquelas amigáveis a daltônicos (colorblind-friendly), são frequentemente preferíveis às paletas padrão.
# Definição de cores personalizadas (ex: paleta "colorblind-friendly")
azul_escuro_cb = (0/255, 107/255, 164/255) # RGB para azul escuro
laranja_cb = (255/255, 128/255, 14/255) # RGB para laranja
fig_cores = plt.figure(figsize=(14, 10))
fig_cores.subplots_adjust(hspace=0.5, wspace=0.3)
for i, categoria in enumerate(categorias_principais): # Reutiliza categorias_principais e mulheres_diplomas
ax_sub_cor = fig_cores.add_subplot(2, 2, i + 1)
ax_sub_cor.plot(mulheres_diplomas['Year'], mulheres_diplomas[categoria], color=azul_escuro_cb, label='Mulheres', linewidth=2.5)
ax_sub_cor.plot(mulheres_diplomas['Year'], 100 - mulheres_diplomas[categoria], color=laranja_cb, label='Homens', linewidth=2.5)
for sp in ax_sub_cor.spines.values():
sp.set_visible(False)
ax_sub_cor.set_xlim(1968, 2011)
ax_sub_cor.set_ylim(0, 100)
ax_sub_cor.set_title(f'Diplomas em {categoria}', fontsize=12)
ax_sub_cor.tick_params(bottom=False, top=False, left=False, right=False, labelsize=9)
ax_sub_cor.grid(axis='y', linestyle=':', alpha=0.5)
ax_sub_cor.set_xlabel("Ano", fontsize=10)
ax_sub_cor.set_ylabel("Percentual", fontsize=10)
if i == 0:
ax_sub_cor.legend(loc='upper right', frameon=False, fontsize=9)
plt.show()
Ajustando a Espessura da Linha
Controlar a espessura da linha (parâmetro linewidth) pode enfatizar certas tendências ou melhorar a visibilidade em gráficos densos, tornando os dados mais proeminentes.
fig_largura = plt.figure(figsize=(18, 4)) # Figura mais larga para subplots lado a lado
fig_largura.subplots_adjust(wspace=0.25) # Ajusta o espaçamento horizontal
for i, categoria in enumerate(categorias_principais):
ax_sub_largura = fig_largura.add_subplot(1, 4, i + 1) # Subplots em uma única linha
ax_sub_largura.plot(mulheres_diplomas['Year'], mulheres_diplomas[categoria],
color=azul_escuro_cb, label='Mulheres', linewidth=4) # Linhas mais grossas
ax_sub_largura.plot(mulheres_diplomas['Year'], 100 - mulheres_diplomas[categoria],
color=laranja_cb, label='Homens', linewidth=4)
for sp in ax_sub_largura.spines.values():
sp.set_visible(False)
ax_sub_largura.set_xlim(1968, 2011)
ax_sub_largura.set_ylim(0, 100)
ax_sub_largura.set_title(f'{categoria}', fontsize=13)
ax_sub_largura.tick_params(bottom=False, top=False, left=False, right=False, labelsize=9)
ax_sub_largura.grid(axis='y', linestyle=':', alpha=0.5)
ax_sub_largura.set_xlabel("Ano", fontsize=10)
ax_sub_largura.set_ylabel("Percentual", fontsize=10)
if i == 0:
ax_sub_largura.legend(loc='upper right', frameon=False, fontsize=10)
plt.show()
Adicionando Anotações Diretas aos Gráficos
Para destacar pontos específicos, explicar tendências importantes ou rotular séries diretamente, anotações de texto podem ser inseridas em coordenadas específicas do gráfico, oferecendo clareza adicional ao leitor.
fig_anotacoes = plt.figure(figsize=(18, 4))
fig_anotacoes.subplots_adjust(wspace=0.25)
for i, categoria in enumerate(categorias_principais):
ax_sub_anot = fig_anotacoes.add_subplot(1, 4, i + 1)
ax_sub_anot.plot(mulheres_diplomas['Year'], mulheres_diplomas[categoria],
color=azul_escuro_cb, label='Mulheres', linewidth=3)
ax_sub_anot.plot(mulheres_diplomas['Year'], 100 - mulheres_diplomas[categoria],
color=laranja_cb, label='Homens', linewidth=3)
for sp in ax_sub_anot.spines.values():
sp.set_visible(False)
ax_sub_anot.set_xlim(1968, 2011)
ax_sub_anot.set_ylim(0, 100)
ax_sub_anot.set_title(f'{categoria}', fontsize=13)
ax_sub_anot.tick_params(bottom=False, top=False, left=False, right=False, labelsize=9)
ax_sub_anot.grid(axis='y', linestyle=':', alpha=0.5)
ax_sub_anot.set_xlabel("Ano", fontsize=10)
ax_sub_anot.set_ylabel("Percentual", fontsize=10)
# Adiciona anotações específicas para os primeiros e últimos subplots
if i == 0: # Biologia
ax_sub_anot.text(2005, 80, 'Homens', color=laranja_cb, fontsize=10, ha='center', fontweight='bold')
ax_sub_anot.text(2002, 12, 'Mulheres', color=azul_escuro_cb, fontsize=10, ha='center', fontweight='bold')
elif i == 3: # Matemática e Estatística
ax_sub_anot.text(2005, 55, 'Homens', color=laranja_cb, fontsize=10, ha='center', fontweight='bold')
ax_sub_anot.text(2001, 42, 'Mulheres', color=azul_escuro_cb, fontsize=10, ha='center', fontweight='bold')
plt.show()