Visualização de Dados com Python

Explorando bibliotecas de visualização: Matplotlib, Plotly e Altair

python
visualização
data-science
Autor

João Pedro F. Duarte

Data de Publicação

10/02/2024

Introdução

A visualização de dados é uma habilidade essencial para qualquer cientista de dados ou engenheiro. Neste post, vamos explorar três bibliotecas populares de visualização em Python: Matplotlib, Plotly e Altair.

Dataset de Exemplo

Vamos usar um dataset sintético para demonstrar diferentes tipos de visualizações:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import plotly.express as px
import plotly.graph_objects as go

# Configurar seed para reprodutibilidade
np.random.seed(42)

# Criar dataset sintético
n_samples = 200
data = pd.DataFrame({
    'x': np.random.randn(n_samples),
    'y': np.random.randn(n_samples),
    'categoria': np.random.choice(['A', 'B', 'C', 'D'], n_samples),
    'valor': np.random.uniform(10, 100, n_samples),
    'tempo': pd.date_range('2024-01-01', periods=n_samples, freq='D')
})

# Adicionar correlação
data['y'] = data['y'] + 0.5 * data['x'] + np.random.randn(n_samples) * 0.3

print(data.head())
print(f"\nShape: {data.shape}")
          x         y categoria      valor      tempo
0  0.496714  0.219156         C  51.628124 2024-01-01
1 -0.138264  0.103129         C  77.272384 2024-01-02
2  0.647689  1.306160         A  13.301488 2024-01-03
3  1.523030  2.316023         A  32.719325 2024-01-04
4 -0.234153 -1.572623         D  74.201463 2024-01-05

Shape: (200, 5)

1. Matplotlib: O Clássico

Matplotlib é a biblioteca de visualização mais tradicional do Python. Oferece controle total sobre cada aspecto do gráfico.

Scatter Plot com Regressão

from scipy import stats

# Criar figura
fig, ax = plt.subplots(figsize=(10, 6))

# Scatter plot
scatter = ax.scatter(data['x'], data['y'], 
                     c=data['valor'], 
                     cmap='viridis', 
                     alpha=0.6, 
                     s=50)

# Linha de regressão
slope, intercept, r_value, p_value, std_err = stats.linregress(data['x'], data['y'])
line_x = np.array([data['x'].min(), data['x'].max()])
line_y = slope * line_x + intercept
ax.plot(line_x, line_y, 'r--', linewidth=2, label=f'Regressão (R² = {r_value**2:.3f})')

# Configurações
ax.set_xlabel('X', fontsize=12)
ax.set_ylabel('Y', fontsize=12)
ax.set_title('Scatter Plot com Linha de Regressão', fontsize=14, fontweight='bold')
ax.legend()
ax.grid(True, alpha=0.3)

# Colorbar
cbar = plt.colorbar(scatter, ax=ax)
cbar.set_label('Valor', fontsize=10)

plt.tight_layout()
plt.show()

Distribuições por Categoria

fig, axes = plt.subplots(2, 2, figsize=(12, 10))

# Histograma
axes[0, 0].hist(data['valor'], bins=20, color='skyblue', edgecolor='black', alpha=0.7)
axes[0, 0].set_title('Distribuição de Valores', fontweight='bold')
axes[0, 0].set_xlabel('Valor')
axes[0, 0].set_ylabel('Frequência')
axes[0, 0].grid(True, alpha=0.3)

# Box plot por categoria
data.boxplot(column='valor', by='categoria', ax=axes[0, 1])
axes[0, 1].set_title('Valores por Categoria', fontweight='bold')
axes[0, 1].set_xlabel('Categoria')
axes[0, 1].set_ylabel('Valor')
plt.suptitle('')  # Remover título automático

# Bar plot - média por categoria
categoria_media = data.groupby('categoria')['valor'].mean().sort_values()
axes[1, 0].barh(categoria_media.index, categoria_media.values, color='coral')
axes[1, 0].set_title('Valor Médio por Categoria', fontweight='bold')
axes[1, 0].set_xlabel('Valor Médio')
axes[1, 0].grid(True, alpha=0.3, axis='x')

# Série temporal
data_temporal = data.groupby('tempo')['valor'].mean()
axes[1, 1].plot(data_temporal.index, data_temporal.values, linewidth=2, color='green')
axes[1, 1].set_title('Evolução Temporal (Média)', fontweight='bold')
axes[1, 1].set_xlabel('Data')
axes[1, 1].set_ylabel('Valor Médio')
axes[1, 1].grid(True, alpha=0.3)
axes[1, 1].tick_params(axis='x', rotation=45)

plt.tight_layout()
plt.show()

2. Plotly: Visualizações Interativas

Plotly permite criar gráficos interativos que podem ser explorados pelo usuário.

Scatter Plot 3D Interativo

# Adicionar terceira dimensão
data['z'] = data['x'] * data['y'] + np.random.randn(n_samples) * 0.5

fig = px.scatter_3d(
    data, 
    x='x', 
    y='y', 
    z='z',
    color='categoria',
    size='valor',
    hover_data=['valor'],
    title='Scatter Plot 3D Interativo',
    labels={'x': 'Eixo X', 'y': 'Eixo Y', 'z': 'Eixo Z'}
)

fig.update_layout(
    scene=dict(
        xaxis_title='X',
        yaxis_title='Y',
        zaxis_title='Z'
    ),
    height=600
)

fig.show()

Heatmap de Correlação

# Calcular matriz de correlação
numeric_cols = ['x', 'y', 'z', 'valor']
corr_matrix = data[numeric_cols].corr()

# Criar heatmap
fig = go.Figure(data=go.Heatmap(
    z=corr_matrix.values,
    x=corr_matrix.columns,
    y=corr_matrix.columns,
    colorscale='RdBu',
    zmid=0,
    text=corr_matrix.values.round(2),
    texttemplate='%{text}',
    textfont={"size": 12},
    colorbar=dict(title="Correlação")
))

fig.update_layout(
    title='Matriz de Correlação',
    xaxis_title='Variáveis',
    yaxis_title='Variáveis',
    height=500,
    width=600
)

fig.show()

Time Series com Range Slider

# Agregar dados por tempo e categoria
ts_data = data.groupby(['tempo', 'categoria'])['valor'].mean().reset_index()

fig = px.line(
    ts_data, 
    x='tempo', 
    y='valor', 
    color='categoria',
    title='Evolução Temporal por Categoria',
    labels={'tempo': 'Data', 'valor': 'Valor Médio'}
)

fig.update_xaxes(
    rangeslider_visible=True,
    rangeselector=dict(
        buttons=list([
            dict(count=1, label="1m", step="month", stepmode="backward"),
            dict(count=3, label="3m", step="month", stepmode="backward"),
            dict(count=6, label="6m", step="month", stepmode="backward"),
            dict(step="all", label="Tudo")
        ])
    )
)

fig.update_layout(height=500)
fig.show()

3. Estatísticas Descritivas

print("Estatísticas Descritivas:")
print("=" * 50)
print(data[numeric_cols].describe())

print("\n\nContagem por Categoria:")
print("=" * 50)
print(data['categoria'].value_counts())
Estatísticas Descritivas:
==================================================
                x           y           z       valor
count  200.000000  200.000000  200.000000  200.000000
mean    -0.040771    0.061824    0.610739   54.768640
std      0.931004    1.168072    1.232384   25.334563
min     -2.619745   -3.951252   -1.996559   10.416882
25%     -0.705128   -0.659598   -0.175267   32.587442
50%     -0.004192    0.120707    0.438314   55.607458
75%      0.500852    0.826598    1.040599   76.988763
max      2.720169    4.107723    6.555791   99.096421


Contagem por Categoria:
==================================================
categoria
B    56
A    54
C    51
D    39
Name: count, dtype: int64

Conclusão

Cada biblioteca tem seus pontos fortes:

  • Matplotlib: Controle total, publicações científicas, gráficos estáticos
  • Plotly: Interatividade, dashboards, exploração de dados
  • Altair: Sintaxe declarativa, gráficos complexos com código simples

A escolha depende do seu caso de uso específico!

Próximos Passos

No próximo post, vamos explorar algoritmos de grafos e como visualizá-los de forma eficiente.


Recursos: - Matplotlib Documentation - Plotly Python - Altair Documentation