Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

2
respostas

Modelo-Atraso-Voo.ipynb

import seaborn as sns
import matplotlib.pyplot as plt


# ==========================================================
# ANÁLISE DA DISTRIBUIÇÃO DOS ATRASOS DOS VOOS
# ==========================================================

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# ==========================================================
# CÁLCULO DAS MÉTRICAS PRINCIPAIS
# ==========================================================

mean_delay = dados['delay'].mean()
median_delay = dados['delay'].median()

# ==========================================================
# CONFIGURAÇÃO VISUAL
# ==========================================================

sns.set_theme(style="whitegrid")

fig, axes = plt.subplots(
    1,
    2,
    figsize=(14, 5)
)

# ==========================================================
# BOXPLOT
# ==========================================================

sns.boxplot(
    data=dados,
    y='delay',
    ax=axes[0],
    color='#1F4E79',
    width=0.5
)

axes[0].set_title(
    'Distribuição dos Atrasos (Boxplot)',
    fontsize=14
)

axes[0].set_ylabel(
    'Atraso (minutos)'
)

# Linha da mediana
axes[0].axhline(
    y=median_delay,
    color='#C0392B',
    linestyle='--',
    linewidth=2
)

# Anotação direta
axes[0].annotate(
    f'Mediana: {median_delay:.1f}',
    xy=(0, median_delay),
    xytext=(0.2, median_delay + 15),
    arrowprops=dict(
        arrowstyle='->'
    ),
    fontsize=10
)

# ==========================================================
# HISTOGRAMA
# ==========================================================

sns.histplot(
    data=dados,
    x='delay',
    kde=True,
    bins=40,
    alpha=0.5,
    color='#1F4E79',
    ax=axes[1]
)

axes[1].set_title(
    'Distribuição dos Atrasos (Histograma)',
    fontsize=14
)

axes[1].set_xlabel(
    'Atraso (minutos)'
)

axes[1].set_ylabel(
    'Número de Voos'
)

# Média
axes[1].axvline(
    x=mean_delay,
    color='#7F8C8D',
    linestyle='--',
    linewidth=2
)

# Mediana
axes[1].axvline(
    x=median_delay,
    color='#C0392B',
    linestyle='--',
    linewidth=2
)

# Labels diretos (evita legenda)
axes[1].text(
    mean_delay + 1,
    axes[1].get_ylim()[1] * 0.95,
    f'Média: {mean_delay:.1f}',
    color='#7F8C8D'
)

axes[1].text(
    median_delay + 1,
    axes[1].get_ylim()[1] * 0.85,
    f'Mediana: {median_delay:.1f}',
    color='#C0392B'
)

# Insight visual
axes[1].annotate(
    'Poucos voos com atrasos\nextremos puxam a média',
    xy=(60, 250),
    xytext=(85, 1200),
    arrowprops=dict(
        arrowstyle='->'
    ),
    fontsize=10
)

# ==========================================================
# TÍTULO EXECUTIVO
# ==========================================================

plt.suptitle(
    'Análise da Distribuição dos Atrasos dos Voos\nA mediana inferior à média indica influência de atrasos extremos',
    fontsize=16
)

plt.tight_layout()

plt.show()
2 respostas
import seaborn as sns
import matplotlib.pyplot as plt


PALETTE = {"box": "#4C72B0", "mean": "#C44E52", "median": "#DD8452", "neutral": "#555555"}


def plot_delay_distribution(df: pd.DataFrame, col: str = "delay", unit: str = "min") -> plt.Figure:
    """Plota distribuição e dispersão de uma métrica contínua com anotação de tendência central.

    Args:
        df: DataFrame de origem.
        col: Coluna numérica a analisar.
        unit: Unidade exibida nos eixos (ex.: 'min').

    Returns:
        Figura matplotlib pronta para exibição ou export.

    Raises:
        KeyError: Se `col` não existir no DataFrame.
    """
    if col not in df.columns:
        raise KeyError(f"Coluna '{col}' ausente. Disponíveis: {list(df.columns)}")

    serie = df[col].dropna()
    media, mediana = serie.mean(), serie.median()
    skew_pct = (media - mediana) / mediana * 100  # delta % média vs. mediana

    sns.set_theme(style="white", context="notebook")
    fig, (ax_box, ax_hist) = plt.subplots(
        1, 2, figsize=(11, 4.2), gridspec_kw={"width_ratios": [1, 2.4]}
    )

    # --- Boxplot: dispersão e outliers (papel secundário, mais estreito) ---
    sns.boxplot(
        y=serie, ax=ax_box, color=PALETTE["box"], width=0.4, fliersize=2,
        boxprops={"alpha": 0.85},
        flierprops={"marker": "o", "alpha": 0.25,
                    "markerfacecolor": PALETTE["neutral"], "markeredgecolor": "none"},
    )
    ax_box.axhline(media, color=PALETTE["mean"], ls="--", lw=1.3)
    ax_box.set_ylabel(f"Atraso ({unit})")
    ax_box.set_title("Dispersão & Outliers", fontsize=11, loc="left", color=PALETTE["neutral"])

    # --- Histograma: distribuição (papel principal) ---
    sns.histplot(serie, ax=ax_hist, kde=True, color=PALETTE["box"],
                 alpha=0.55, edgecolor="none", line_kws={"lw": 1.4})
    ax_hist.axvline(media, color=PALETTE["mean"], ls="--", lw=1.3)
    ax_hist.axvline(mediana, color=PALETTE["median"], ls="--", lw=1.3)
    ax_hist.set_xlabel(f"Atraso ({unit})")
    ax_hist.set_ylabel("Nº de voos")
    ax_hist.set_title("Distribuição", fontsize=11, loc="left", color=PALETTE["neutral"])

    # Anotação direta: valor na própria linha, sem depender de legenda
    topo = ax_hist.get_ylim()[1]
    ax_hist.annotate(f"Média {media:.1f}", xy=(media, topo * 0.92),
                     color=PALETTE["mean"], fontsize=9, xytext=(4, 0), textcoords="offset points")
    ax_hist.annotate(f"Mediana {mediana:.1f}", xy=(mediana, topo * 0.78),
                     color=PALETTE["median"], fontsize=9, ha="right",
                     xytext=(-4, 0), textcoords="offset points")

    fig.suptitle(
        f"Atrasos concentrados perto de 0, mas com cauda à direita  •  "
        f"Média {skew_pct:+.0f}% acima da mediana",
        fontsize=12, x=0.01, ha="left", weight="bold", color="#222222",
    )
    sns.despine(ax=ax_box)
    sns.despine(ax=ax_hist)
    fig.tight_layout(rect=[0, 0, 1, 0.95])
    return fig


fig = plot_delay_distribution(dados)
plt.show()

Análise de Distribuição de Atrasos de Voos

Projeto desenvolvido durante os estudos de Data Science com foco em visualização de dados e estatística descritiva.

Melhorias Aplicadas

  • Destaque visual para média e mediana.
  • Redução de ruído visual com anotações diretas.
  • Inclusão de insights no próprio gráfico.
  • Uso de cores intencionais para facilitar a interpretação.
  • Comparação entre Boxplot e Histograma para análise da distribuição.

Principais Insights

  • A distribuição dos atrasos apresenta assimetria à direita.
  • Poucos voos com atrasos extremos impactam significativamente a média.
  • A mediana representa melhor o comportamento da maior parte dos voos.

Ferramentas Utilizadas

  • Python
  • Pandas
  • Seaborn
  • Matplotlib
  • Google Colab

Objetivo

Praticar análise exploratória de dados (EDA), interpretação estatística e técnicas de storytelling visual para comunicar insights de forma mais clara e eficiente.

Os Dois code o primeiro foi criado no chatgpt e, o segundo no Claude implantando as melhorias visuais como testes no meu aprendizado