Fundamentos de Visualização

Aula 05 — Módulo 1: Análise Exploratória

Heitor Ramos
heitor@dcc.ufmg.br

Departamento de Ciência da Computação — UFMG

Módulo 1 · Análise Exploratória

Visualizar é transformar dados em marcas que o sistema perceptivo consegue comparar.

Hoje

  1. Entender por que visualizamos dados.
  2. Relacionar tipos de variáveis a marcas e canais visuais.
  3. Comparar barras, histogramas, ECDFs, boxplots e dispersões.
  4. Entender percepção de posição, comprimento, área e cor.
  5. Usar visualização como parte da investigação.

Visualização serve a três trabalhos

Explorar · encontrar estrutura e formular perguntas.

Verificar · detectar erros, ausências e valores improváveis.

Comunicar · tornar uma conclusão examinável por outras pessoas.

Antes dos gráficos modernos, havia perguntas urgentes

O mapa de cólera de John Snow combinou localização e mortalidade para investigar um surto em Londres.

A força do mapa não estava na decoração, mas em aproximar uma pergunta de um padrão espacial.

Uma visualização é uma codificação

flowchart LR
  D[Dados] --> T[Transformação]
  T --> M[Marcas]
  M --> C[Canais visuais]
  C --> P[Percepção]
  P --> I[Interpretação]

flowchart LR
  D[Dados] --> T[Transformação]
  T --> M[Marcas]
  M --> C[Canais visuais]
  C --> P[Percepção]
  P --> I[Interpretação]

Pontos, linhas e áreas recebem posição, comprimento, tamanho, forma e cor.

A palavra-chave é percepção

Uma visualização não é lida como uma tabela. O cérebro compara propriedades visuais antes da interpretação consciente.

O gráfico precisa trabalhar com a percepção humana, não exigir que ela seja perfeita.

Visualização é para pessoas

  • Atenção é limitada.
  • Comparações precisam ser fáceis de localizar.
  • Memória de curto prazo não deve carregar dezenas de valores.
  • Convenções ajudam, mas precisam combinar com o dado.

A base principal da aula

Palmer Archipelago Penguins

  • 344 pinguins observados entre 2007 e 2009;
  • espécies Adelie, Chinstrap e Gentoo;
  • ilha, sexo, massa corporal e medidas de bico e nadadeira;
  • dados coletados pelo programa Palmer Station LTER.

Fonte: Kaggle — Palmer Penguins.

O que representa uma linha?

Uma linha corresponde a um pinguim observado.

coluna significado tipo
species espécie categórica
island ilha categórica
body_mass_g massa corporal numérica contínua
flipper_length_mm comprimento da nadadeira numérica contínua
sex sexo registrado categórica

Uma descrição rápida da base

penguins.shape
penguins["species"].value_counts()

Resultado: 344 linhas e 7 colunas; 152 Adelie, 124 Gentoo e 68 Chinstrap.

Algumas medidas corporais e registros de sexo estão ausentes.

Anatomia de um gráfico no Matplotlib

Gráfico de barras anotado com título, área de dados e rótulo do eixo.

Figure contém a composição; Axes contém a escala, as marcas e os rótulos.

Código do gráfico
fig, ax = plt.subplots()
ax.barh(contagens.index, contagens.values)
ax.set_title("Pinguins observados por espécie")
ax.set_xlabel("número de observações")

Categorias pedem contagens comparáveis

Contagem de pinguins por espécie.
Código do gráfico
sns.countplot(data=penguins, y="species", order=penguins.species.value_counts().index)

Barras codificam magnitude por comprimento

  • todas partem de uma referência comum;
  • o eixo categórico separa grupos;
  • ordenar pode revelar hierarquia;
  • barras não são histogramas.

Para comparar categorias, comprimento alinhado é um canal perceptivo forte.

Linhas pedem uma variável ordenada

Série mensal de pedidos da Olist durante 2017.

Conectar meses faz sentido porque o tempo define uma ordem; conectar espécies inventaria um caminho.

Código do gráfico
mensal = orders.set_index("order_purchase_timestamp").resample("MS").size()
mensal.plot.line(marker="o")

Uma variável numérica pede uma distribuição

Histogramas da massa corporal por espécie.

Para um valor \(x\), cada bin \([a,b)\) conta quantas observações satisfazem \(a \le x < b\).

O histograma mostra forma, centro, dispersão, caudas e possíveis lacunas.

Código do gráfico
sns.histplot(data=penguins, x="body_mass_g", hue="species",
             bins=24, element="step", stat="density", common_norm=False)

O número de bins muda o que vemos

Três histogramas da mesma variável com diferentes quantidades de bins.
  • Freedman-Diaconis: \(h = 2\,IQR(x)n^{-1/3}\).
  • Scott: \(h = 3{,}49\,s\,n^{-1/3}\).
  • Sturges: \(k = 1 + \log_2(n)\).

Nenhuma regra substitui olhar versões alternativas e considerar a resolução relevante para o fenômeno.

Código do gráfico
for bins in [6, 15, 35]:
    sns.histplot(penguins["body_mass_g"], bins=bins)

A ECDF evita escolher bins

Funções de distribuição empíricas da massa corporal dos pinguins, separadas por espécie.

\[\widehat F(x)=\frac{1}{n}\sum_{i=1}^n \mathbf{1}(X_i\le x).\]

Ela responde: qual proporção tem massa menor ou igual a \(x\)?

Código do gráfico
sns.ecdfplot(data=penguins, x="body_mass_g", hue="species")

KDE constrói uma densidade suave

Construção de uma KDE em três passos: kernels nas observações, normalização e soma.

\[\widehat f_h(x)=\frac{1}{nh}\sum_{i=1}^{n}K\!\left(\frac{x-x_i}{h}\right),\qquad K(u)=\frac{1}{\sqrt{2\pi}}e^{-u^2/2}.\]

Aqui, \(K\) é a Normal padrão, com variância 1. A transformação \(K_h(x-x_i)=h^{-1}K((x-x_i)/h)\) coloca em \(x_i\) uma Normal com desvio-padrão \(h\) e variância \(h^2\). Normalizar e somar produz uma densidade cuja área total é 1.

Código do gráfico
sns.kdeplot(data=penguins, x="body_mass_g", fill=True)

A largura de banda muda a história

Três KDEs da massa corporal usando larguras de banda pequena, intermediária e grande.
  • \(h\) é a largura de banda — o desvio-padrão de cada kernel gaussiano;
  • portanto, a variância de cada kernel é \(h^2\);
  • \(h\) pequeno preserva oscilações — inclusive ruído;
  • \(h\) grande pode apagar grupos e assimetrias;
  • como nos bins do histograma, compare escolhas plausíveis.

No Seaborn, bw_adjust multiplica a largura de banda calculada automaticamente; ele não é necessariamente o \(h\) medido em gramas.

Código do gráfico
for ajuste in [0.25, 1, 2.5]:
    sns.kdeplot(x=massa, bw_adjust=ajuste)

Boxplot e violinplot respondem perguntas diferentes

Comparação entre boxplots e violinplots da massa dos pinguins.

Boxplot: resume mediana, quartis e valores afastados. Violinplot: acrescenta a forma estimada da distribuição e pode revelar multimodalidade, mas depende da suavização escolhida.

Código do gráfico
sns.boxplot(data=penguins, x="species", y="body_mass_g")
sns.violinplot(data=penguins, x="species", y="body_mass_g", inner="quart")

Duas variáveis numéricas pedem posição

Dispersão entre comprimento da nadadeira e massa corporal.

Procure:

  • direção;
  • intensidade;
  • forma;
  • grupos;
  • valores isolados;
  • variação desigual.

Correlação resume apenas parte dessa estrutura.

Código do gráfico
sns.scatterplot(data=penguins, x="flipper_length_mm", y="body_mass_g", hue="species")

Cor acrescenta uma terceira variável

Medidas de bico de três espécies de pinguim.
Código do gráfico
sns.scatterplot(data=penguins, x="bill_length_mm", y="bill_depth_mm",
                hue="species", style="species")

Customização deve servir à mensagem

Comparação entre gráfico padrão e gráfico com título, rótulo e destaque visual.

Título, eixos e legenda reduzem ambiguidade; destaque orienta a comparação principal.

Código do gráfico
ax.set_title("Pinguins observados por espécie")
ax.set_xlabel("pinguins observados")
ax.barh(..., color=[cinza, cinza, destaque])

De df.plot() à figura exportada

ax = penguins["species"].value_counts().plot.barh(color="#176b87")
ax.set_title("Pinguins observados por espécie")
ax.set_xlabel("observações")
fig = ax.get_figure()
fig.savefig("especies.png", dpi=300, bbox_inches="tight")

df.plot() prepara rapidamente o gráfico; Matplotlib controla a apresentação e a exportação. PNG é adequado para tela; SVG/PDF preservam vetores.

Posição é percebida com grande precisão

Quatro representações da mesma diferença usando posição, comprimento, ângulo e área.

Posição em escala comum e comprimento permitem comparações mais precisas que ângulo e área.

Código do gráfico
# Os mesmos valores, 40 e 60, codificados por quatro canais

Comprimento é mais fácil que área

Valores um e sete representados por barras e áreas de círculos.

Comprimento expõe a razão; comparar áreas exige uma estimativa visual muito menos precisa.

Código do gráfico
ax.barh(["1", "7"], [1, 7])
ax.scatter([0, 1], [0, 0], s=np.array([1, 7]) * 900)

Ângulos dificultam comparações próximas

A mesma composição apresentada como gráfico de setores e barras.

Setores funcionam melhor com poucas partes e diferenças grandes; barras revelam diferenças próximas.

Código do gráfico
ax.pie([32, 29, 24, 15])
ax.barh(["D", "C", "B", "A"], [15, 24, 29, 32])

Forma distingue categorias, não magnitude

Dispersão de medidas dos pinguins usando círculos, quadrados e triângulos sem preenchimento colorido.

Formas ajudam com poucos grupos e funcionam sem cor, mas não possuem ordem natural.

Código do gráfico
markers = {"Adelie": "o", "Chinstrap": "s", "Gentoo": "^"}

Cor possui funções diferentes

Qualitativa · distinguir categorias.

Sequencial · representar baixo → alto.

Divergente · mostrar desvios em torno de um centro.

Luminância cria ordem

Comparação de gradientes Viridis, cinza e Jet.

viridis preserva melhor a progressão perceptiva; jet cria faixas de destaque que não existem nos dados.

Código do gráfico
ax.imshow(gradient, cmap="viridis", aspect="auto")

Vermelho e verde não bastam

Comparação entre codificação vermelho-verde e alternativa azul-laranja acompanhada de formas.

Cor acompanhada de forma permanece legível quando a distinção cromática falha.

Código do gráfico
sns.scatterplot(..., hue="species", style="species", palette="colorblind")

O mesmo resumo pode esconder um dinossauro

Animação do Datasaurus Dozen alternando conjuntos com resumos semelhantes e formas distintas.

O algoritmo move pontos preservando aproximadamente os resumos: estatísticas são projeções da base; visualizar revela o que foi perdido.

O Datasaurus formaliza o alerta

Para quase todos os treze conjuntos:

\[\bar x\approx54{,}27,\quad \bar y\approx47{,}83,\] \[s_x^2\approx281,\quad s_y^2\approx726,\quad r\approx-0{,}06.\]

Os números concordam; as formas não.

As formas aparecem quando plotamos

Grade com treze conjuntos Datasaurus de formas distintas.
Código do gráfico
sns.relplot(data=datasaurus, x="x", y="y", col="dataset", col_wrap=4)

Agregar é perder informação

Médias, medianas e correlações são úteis, mas não mostram sozinhas:

  • multimodalidade;
  • não linearidade;
  • grupos;
  • lacunas;
  • valores influentes;
  • heterogeneidade.

Visualização também detecta erros

Massas de pinguins por linha, com um valor impossível de quarenta mil gramas destacado.

Um zero extra produz um ponto impossível: o gráfico é parte da auditoria.

Código do gráfico
plt.scatter(base.index, base["body_mass_g"])
plt.annotate("provável erro", xy=(linha, 40000))

Comparações pedem domínio comum

Contagens por ilha e espécie usando escalas livres e escala vertical comum.

Escalas independentes fazem diferenças pequenas parecerem equivalentes a mudanças grandes.

Código do gráfico
g = sns.catplot(..., col="species", sharey=True)

Facetas condicionam sem misturar

Relação entre nadadeira e massa corporal em facetas separadas por espécie.

Use facetas para perguntar: o padrão permanece dentro de cada grupo?

Código do gráfico
sns.lmplot(data=penguins, x="flipper_length_mm", y="body_mass_g",
           col="species", sharex=True, sharey=True)

Relação não implica mecanismo

Comparação da associação agregada entre massa e nadadeira com associações separadas por espécie.

Condicionar muda a relação visual, mas ainda não identifica um mecanismo causal.

Código do gráfico
sns.regplot(data=penguins, x="flipper_length_mm", y="body_mass_g")
sns.lmplot(..., col="species")

Uma escolha de gráfico é uma escolha de pergunta

pergunta gráfico inicial
quantas observações por categoria? barras
qual é a forma de uma variável? histograma ou ECDF
como grupos diferem? box/violin + pontos
duas medidas variam juntas? dispersão
como algo muda no tempo? linha

Checklist de leitura

  1. O que representa uma linha?
  2. Quais variáveis estão codificadas?
  3. Por qual canal visual?
  4. Há escala, unidade e referência comuns?
  5. O que o gráfico mostra — e o que ele omite?

Síntese

  • Visualização complementa estatísticas.
  • Posição e comprimento sustentam comparações precisas.
  • Histogramas dependem dos bins; ECDFs não.
  • Área, ângulo e cor exigem cautela.
  • O gráfico deve responder a uma pergunta explícita.

Material de apoio

Próxima aula: como transformar esses fundamentos em boas práticas de comunicação?