1. Pengenalan Data Visualization
Data Visualization atau visualisasi data adalah representasi grafis dari informasi dan data. Dengan menggunakan elemen visual seperti chart, grafik, dan peta, data visualization memudahkan kita memahami tren, outlier, dan pola dalam data yang kompleks.
Python memiliki ekosistem library visualisasi data yang sangat kaya. Tiga library paling populer adalah:
| Library | Kekuatan | Tipe Output | Cocok Untuk |
|---|---|---|---|
| Matplotlib | Library dasar, sangat fleksibel | Static (PNG, SVG, PDF) | Plot ilmiah, publikasi, kontrol penuh |
| Seaborn | Statistical visualization, tema menarik | Static (berbasis matplotlib) | EDA, statistik, heatmap |
| Plotly | Interaktif, zoom, hover tooltips | Interactive (HTML) | Dashboard, web app, presentasi |
- Matplotlib β Saat butuh kontrol penuh atas setiap elemen visual
- Seaborn β Saat melakukan exploratory data analysis (EDA)
- Plotly β Saat butuh grafik interaktif untuk dashboard atau web
Instalasi Library
# Instalasi semua library visualisasi pip install matplotlib seaborn plotly pandas # Untuk Jupyter Notebook / Google Colab pip install matplotlib seaborn plotly pandas jupyter # Verifikasi instalasi python -c "import matplotlib; print(matplotlib.__version__)" python -c "import seaborn; print(seaborn.__version__)" python -c "import plotly; print(plotly.__version__)"
2. Matplotlib: Dasar Visualisasi
Matplotlib adalah library visualisasi paling fundamental di Python. Hampir semua library visualisasi lain dibangun di atas matplotlib. Library ini memungkinkan Anda membuat berbagai jenis plot dari data sederhana hingga kompleks.
Konsep Dasar Matplotlib
Matplotlib memiliki hierarki: Figure β Axes β Elements. Figure adalah kanvas utama, Axes adalah area plot di dalam Figure, dan Elements adalah garis, titik, label, dll.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β Figure β β βββββββββββββββββββββββββββββββββββββββββββββββ β β β Axes 1 β β β β βββββββ β β β β βTitleβ β β β β βββββββ β β β β Y-axisβ ββββββββββββββββββββββββββ β β β β labelβ β Line / Bar / Scatter β β β β β β β Plot Area β β β β β β ββββββββββββββββββββββββββ β β β β βββ X-axis label ββββββββββββ β β β βββββββββββββββββββββββββββββββββββββββββββββββ β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Line Chart β Grafik Garis
import matplotlib.pyplot as plt
# Data penjualan bulanan (dalam jutaan Rupiah)
bulan = ['Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun',
'Jul', 'Ags', 'Sep', 'Okt', 'Nov', 'Des']
penjualan_2025 = [45, 52, 48, 61, 55, 67, 72, 69, 78, 82, 75, 91]
penjualan_2026 = [51, 58, 63, 70, 68, 79, 85, 82, 90, 95, 88, 102]
# Membuat figure dengan ukuran tertentu
fig, ax = plt.subplots(figsize=(12, 6))
# Plot dua garis
ax.plot(bulan, penjualan_2025, marker='o', linewidth=2,
label='2025', color='#3498db')
ax.plot(bulan, penjualan_2026, marker='s', linewidth=2,
label='2026', color='#e74c3c')
# Kustomisasi
ax.set_title('Perbandingan Penjualan Bulanan', fontsize=16, fontweight='bold')
ax.set_xlabel('Bulan', fontsize=12)
ax.set_ylabel('Penjualan (Juta Rp)', fontsize=12)
ax.legend(fontsize=11)
ax.grid(True, alpha=0.3)
ax.set_ylim(0, 120)
plt.tight_layout()
plt.savefig('line_chart.png', dpi=150, bbox_inches='tight')
plt.show()
Bar Chart β Grafik Batang
import matplotlib.pyplot as plt
# Data penggunaan bahasa pemrograman
bahasa = ['Python', 'JavaScript', 'Java', 'C++', 'Go', 'Rust']
popularitas = [31.5, 28.2, 15.3, 10.1, 8.2, 4.7]
fig, ax = plt.subplots(figsize=(10, 6))
# Bar chart dengan gradient colors
colors = ['#3498db', '#f1c40f', '#e74c3c', '#2ecc71', '#9b59b6', '#e67e22']
bars = ax.bar(bahasa, popularitas, color=colors, edgecolor='white', linewidth=1.2)
# Tambahkan label nilai di atas setiap bar
for bar, val in zip(bars, popularitas):
ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.5,
f'{val}%', ha='center', fontsize=11, fontweight='bold')
ax.set_title('Popularitas Bahasa Pemrograman 2026', fontsize=16, fontweight='bold')
ax.set_xlabel('Bahasa Pemrograman', fontsize=12)
ax.set_ylabel('Market Share (%)', fontsize=12)
ax.set_ylim(0, 40)
ax.grid(axis='y', alpha=0.3)
plt.tight_layout()
plt.savefig('bar_chart.png', dpi=150, bbox_inches='tight')
plt.show()
Subplots β Multiple Charts
import matplotlib.pyplot as plt
import numpy as np
# Membuat 4 subplot dalam grid 2x2
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
fig.suptitle('Dashboard Analisis Data', fontsize=18, fontweight='bold')
# Plot 1: Line chart
x = np.linspace(0, 10, 100)
axes[0, 0].plot(x, np.sin(x), color='#3498db', linewidth=2)
axes[0, 0].set_title('Sin Wave')
axes[0, 0].grid(True, alpha=0.3)
# Plot 2: Bar chart
categories = ['A', 'B', 'C', 'D', 'E']
values = [23, 45, 12, 67, 34]
axes[0, 1].bar(categories, values, color='#2ecc71')
axes[0, 1].set_title('Distribusi Kategori')
# Plot 3: Scatter plot
np.random.seed(42)
x_scatter = np.random.randn(100)
y_scatter = x_scatter * 0.5 + np.random.randn(100) * 0.5
axes[1, 0].scatter(x_scatter, y_scatter, alpha=0.6, color='#e74c3c')
axes[1, 0].set_title('Scatter Plot')
# Plot 4: Histogram
data = np.random.normal(50, 15, 1000)
axes[1, 1].hist(data, bins=30, color='#9b59b6', edgecolor='white')
axes[1, 1].set_title('Distribusi Data')
plt.tight_layout()
plt.savefig('subplots.png', dpi=150, bbox_inches='tight')
plt.show()
3. Seaborn: Statistical Visualization
Seaborn adalah library visualisasi statistik yang dibangun di atas matplotlib. Seaborn menyediakan API tingkat tinggi yang memudahkan pembuatan visualisasi statistik yang menarik dengan kode yang lebih sedikit.
Keunggulan Seaborn
| Fitur | Matplotlib | Seaborn |
|---|---|---|
| Tema default | Kurang menarik | Modern dan menarik |
| Statistical plot | Perlu kode banyak | Satu baris kode |
| Pandas integration | Manual | Native DataFrame support |
| Color palette | Default | Banyak pilihan menarik |
| Multi-plot grid | Manual (subplot) | FacetGrid otomatis |
Contoh Heatmap dengan Seaborn
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# Membuat sample data korelasi
np.random.seed(42)
data = pd.DataFrame({
'Suhu': np.random.normal(30, 5, 100),
'Kelembaban': np.random.normal(70, 10, 100),
'Tekanan': np.random.normal(1013, 5, 100),
'Curah Hujan': np.random.normal(200, 50, 100),
'Angin': np.random.normal(15, 5, 100)
})
# Tambahkan korelasi buatan
data['Kelembaban'] = data['Curah Hujan'] * 0.3 + np.random.normal(0, 5, 100)
data['Suhu'] = -data['Curah Hujan'] * 0.1 + 35 + np.random.normal(0, 3, 100)
# Hitung matriks korelasi
corr_matrix = data.corr()
# Membuat heatmap
fig, ax = plt.subplots(figsize=(10, 8))
sns.heatmap(
corr_matrix,
annot=True, # Tampilkan angka korelasi
fmt='.2f', # Format 2 desimal
cmap='RdYlBu_r', # Color map (Red-Yellow-Blue reversed)
center=0, # Pusat warna di 0
square=True, # Bentuk kotak persegi
linewidths=1, # Garis antar sel
cbar_kws={'label': 'Koefisien Korelasi'},
ax=ax
)
ax.set_title('Matriks Korelasi Variabel Cuaca', fontsize=16, fontweight='bold')
plt.tight_layout()
plt.savefig('heatmap.png', dpi=150, bbox_inches='tight')
plt.show()
Scatter Plot dengan Seaborn
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# Dataset: Hubungan pendapatan dan pengeluaran
np.random.seed(42)
n = 200
df = pd.DataFrame({
'Pendapatan (Juta)': np.concatenate([
np.random.normal(5, 1.5, 50), # Kelompok rendah
np.random.normal(10, 2, 80), # Kelompok menengah
np.random.normal(20, 3, 70) # Kelompok tinggi
]),
'Pengeluaran (Juta)': np.concatenate([
np.random.normal(4, 1, 50),
np.random.normal(7, 1.5, 80),
np.random.normal(13, 2.5, 70)
]),
'Kategori': ['Rendah']*50 + ['Menengah']*80 + ['Tinggi']*70
})
# Scatter plot dengan hue (warna berdasarkan kategori)
fig, ax = plt.subplots(figsize=(10, 8))
sns.scatterplot(
data=df,
x='Pendapatan (Juta)',
y='Pengeluaran (Juta)',
hue='Kategori',
palette='viridis',
s=80,
alpha=0.7,
ax=ax
)
# Tambahkan regresi line
sns.regplot(
data=df,
x='Pendapatan (Juta)',
y='Pengeluaran (Juta)',
scatter=False,
color='red',
line_kws={'linestyle': '--', 'linewidth': 2},
ax=ax
)
ax.set_title('Hubungan Pendapatan vs Pengeluaran', fontsize=16, fontweight='bold')
ax.legend(title='Kelompok', fontsize=11)
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('scatter_seaborn.png', dpi=150, bbox_inches='tight')
plt.show()
Distribution Plot (Histogram + KDE)
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
# Data distribusi nilai ujian
np.random.seed(42)
nilai_a = np.random.normal(75, 10, 200) # Kelas A
nilai_b = np.random.normal(68, 12, 200) # Kelas B
nilai_c = np.random.normal(82, 8, 200) # Kelas C
fig, axes = plt.subplots(1, 2, figsize=(14, 6))
# Histogram + KDE
sns.histplot(nilai_a, kde=True, color='#3498db', label='Kelas A', alpha=0.5, ax=axes[0])
sns.histplot(nilai_b, kde=True, color='#e74c3c', label='Kelas B', alpha=0.5, ax=axes[0])
sns.histplot(nilai_c, kde=True, color='#2ecc71', label='Kelas C', alpha=0.5, ax=axes[0])
axes[0].set_title('Distribusi Nilai per Kelas')
axes[0].legend()
# Boxplot perbandingan
import pandas as pd
df_nilai = pd.DataFrame({
'Nilai': np.concatenate([nilai_a, nilai_b, nilai_c]),
'Kelas': ['A']*200 + ['B']*200 + ['C']*200
})
sns.boxplot(data=df_nilai, x='Kelas', y='Nilai', palette='Set2', ax=axes[1])
axes[1].set_title('Boxplot Nilai per Kelas')
plt.tight_layout()
plt.savefig('distribution.png', dpi=150, bbox_inches='tight')
plt.show()
4. Plotly: Interactive Charts
Plotly adalah library visualisasi interaktif yang menghasilkan grafik HTML. Plotly memungkinkan zoom, pan, hover tooltips, dan export ke berbagai format. Sangat cocok untuk dashboard dan web application.
Keunggulan Plotly
- Interaktif β Zoom, pan, hover tooltips, click events
- Responsif β Otomatis menyesuaikan ukuran layar
- Export β Simpan ke HTML, PNG, SVG, PDF
- 3D Charts β Support visualisasi 3D
- Map β Choropleth map dan scatter geo
Line Chart Interaktif
import plotly.graph_objects as go
import pandas as pd
# Data saham fiksi
dates = pd.date_range('2026-01-01', periods=180, freq='D')
import numpy as np
np.random.seed(42)
harga = 100 + np.cumsum(np.random.randn(180) * 2)
fig = go.Figure()
fig.add_trace(go.Scatter(
x=dates,
y=harga,
mode='lines',
name='Harga Saham',
line=dict(color='#3498db', width=2),
fill='tozeroy',
fillcolor='rgba(52, 152, 219, 0.1)'
))
fig.update_layout(
title='Harga Saham Fiksi (6 Bulan)',
xaxis_title='Tanggal',
yaxis_title='Harga (Rp)',
template='plotly_dark',
hovermode='x unified',
height=500
)
fig.show() # Buka di browser
# fig.write_html('stock_chart.html') # Simpan sebagai HTML
Interactive Bar Chart
import plotly.graph_objects as go
# Data perbandingan framework Python
frameworks = ['FastAPI', 'Flask', 'Django', 'Tornado', 'Sanic']
stars = [78, 68, 79, 24, 7]
contributors = [600, 650, 2200, 400, 120]
fig = go.Figure()
fig.add_trace(go.Bar(
name='GitHub Stars (K)',
x=frameworks,
y=stars,
marker_color='#3498db',
text=stars,
textposition='outside'
))
fig.add_trace(go.Bar(
name='Contributors',
x=frameworks,
y=contributors,
marker_color='#e74c3c',
text=contributors,
textposition='outside'
))
fig.update_layout(
title='Perbandingan Framework Python Populer',
barmode='group',
template='plotly_dark',
height=500,
legend=dict(orientation='h', y=1.12)
)
fig.show()
Heatmap Interaktif
import plotly.graph_objects as go
import numpy as np
import pandas as pd
# Data penjualan per hari per jam
hari = ['Senin', 'Selasa', 'Rabu', 'Kamis', 'Jumat', 'Sabtu', 'Minggu']
jam = [f'{h}:00' for h in range(8, 22)] # 08:00 - 21:00
np.random.seed(42)
# Simulasi: lebih ramai jam makan siang dan weekend
data = np.random.randint(10, 100, size=(7, 14))
data[:, 4:7] += 30 # Jam makan siang (12-15)
data[:, 11:13] += 20 # Jam makan malam (19-21)
data[5:, :] += 15 # Weekend lebih ramai
fig = go.Figure(data=go.Heatmap(
z=data,
x=jam,
y=hari,
colorscale='YlOrRd',
text=data,
texttemplate='%{text}',
textfont={'size': 10},
colorbar=dict(title='Jumlah Transaksi')
))
fig.update_layout(
title='Heatmap Transaksi Restoran per Hari & Jam',
xaxis_title='Jam',
yaxis_title='Hari',
template='plotly_dark',
height=400
)
fig.show()
Plotly Express (px) β API sederhana untuk membuat chart cepat. Graph Objects (go) β API detail untuk kustomisasi penuh. Gunakan px untuk prototyping, go untuk produksi.
5. Jenis Chart & Kapan Menggunakannya
Memilih jenis chart yang tepat sangat penting untuk menyampaikan informasi secara efektif. Berikut panduan lengkap kapan menggunakan masing-masing jenis chart:
| Jenis Chart | Kegunaan | Contoh Kasus | Library Terbaik |
|---|---|---|---|
| Line Chart | Menunjukkan tren seiring waktu | Harga saham, suhu harian, penjualan bulanan | Matplotlib, Plotly |
| Bar Chart | Membandingkan kategori | Populasi kota, penjualan per produk, skor ujian | Matplotlib, Plotly |
| Scatter Plot | Hubungan antara dua variabel | Tinggi vs berat, harga vs luas rumah | Seaborn, Plotly |
| Heatmap | Korelasi dan pola dalam matriks | Korelasi fitur, confusion matrix, traffic harian | Seaborn, Plotly |
| Histogram | Distribusi frekuensi data | Distribusi nilai ujian, usia penduduk | Matplotlib, Seaborn |
| Box Plot | Ringkasan statistik (median, outlier) | Perbandingan gaji, distribusi harga | Seaborn |
| Pie Chart | Komposisi proporsi | Market share, alokasi budget | Matplotlib |
| Area Chart | Akumulasi seiring waktu | Total produksi, kumulatif penjualan | Plotly, Matplotlib |
Panduan Visual: Kapan Harus Pakai Chart Apa?
Apa tujuan visualisasi?
β
βββββββββββββββββββΌββββββββββββββββββ
β β β
Tren/Waktu? Komposisi? Hubungan?
β β β
ββββββββ΄βββββββ ββββββ΄βββββ ββββββ΄βββββ
β β β β β β
Satu seri? Multi? Proporsi? Akumulasi? 2 var? 3 var?
β β β β β β
Line Chart Multi Pie/Donut Area Scatter 3D Scatter
Line Chart Chart Plot Plot
Perbandingan antar kategori?
β
Bar Chart / Grouped Bar
Pola dalam matriks?
β
Heatmap
Distribusi data?
β
Histogram / Box Plot
6. Membuat Dashboard
Dashboard menggabungkan beberapa visualisasi dalam satu tampilan untuk memberikan gambaran komprehensif. Kita akan membuat dashboard menggunakan Plotly Subplots dan Dash.
Dashboard dengan Plotly Subplots
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import numpy as np
import pandas as pd
np.random.seed(42)
# Membuat subplot 2x2
fig = make_subplots(
rows=2, cols=2,
subplot_titles=(
'Tren Penjualan',
'Distribusi Kategori',
'Top 5 Produk',
'Target vs Aktual'
),
specs=[
[{"type": "scatter"}, {"type": "pie"}],
[{"type": "bar"}, {"type": "bar"}]
]
)
# Plot 1: Line chart (tren)
bulan = ['Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun']
penjualan = [45, 52, 48, 61, 55, 67]
fig.add_trace(
go.Scatter(x=bulan, y=penjualan, mode='lines+markers',
name='Penjualan', line=dict(color='#3498db')),
row=1, col=1
)
# Plot 2: Pie chart (kategori)
kategori = ['Elektronik', 'Fashion', 'Makanan', 'Lainnya']
nilai = [35, 25, 22, 18]
fig.add_trace(
go.Pie(labels=kategori, values=nilai,
marker=dict(colors=['#3498db','#e74c3c','#2ecc71','#f1c40f'])),
row=1, col=2
)
# Plot 3: Bar chart (top produk)
produk = ['Laptop', 'HP', 'Tablet', 'TV', 'Headset']
jml = [120, 95, 78, 65, 52]
fig.add_trace(
go.Bar(x=produk, y=jml, name='Terjual',
marker_color='#2ecc71'),
row=2, col=1
)
# Plot 4: Target vs Aktual
target = [50, 55, 60, 65, 70, 75]
aktual = [45, 52, 58, 61, 68, 72]
fig.add_trace(
go.Bar(x=bulan, y=target, name='Target',
marker_color='#bdc3c7'),
row=2, col=2
)
fig.add_trace(
go.Bar(x=bulan, y=aktual, name='Aktual',
marker_color='#e74c3c'),
row=2, col=2
)
# Update layout
fig.update_layout(
title_text='Dashboard Penjualan Q1-Q2 2026',
template='plotly_dark',
height=700,
showlegend=True
)
fig.show()
# fig.write_html('dashboard.html')
Membuat Dashboard Web dengan Dash
# pip install dash
import dash
from dash import dcc, html
import plotly.graph_objects as go
app = dash.Dash(__name__)
app.layout = html.Div([
html.H1('Dashboard Penjualan', style={'textAlign': 'center'}),
# Dropdown filter
html.Label('Pilih Periode:'),
dcc.Dropdown(
id='periode-dropdown',
options=[
{'label': 'Q1 2026', 'value': 'q1'},
{'label': 'Q2 2026', 'value': 'q2'},
],
value='q1'
),
# Grafik
dcc.Graph(id='grafik-penjualan'),
# Statistik cards
html.Div([
html.Div([html.H3('Rp 500Jt'), html.P('Total Penjualan')],
className='stat-card'),
html.Div([html.H3('1,250'), html.P('Total Transaksi')],
className='stat-card'),
html.Div([html.H3('Rp 400K'), html.P('Rata-rata per Transaksi')],
className='stat-card'),
], style={'display': 'flex', 'gap': '20px'})
])
if __name__ == '__main__':
app.run(debug=True)
# Buka http://localhost:8050
7. Best Practices Visualisasi Data
Membuat visualisasi yang efektif bukan hanya soal kode β tapi juga soal desain dan komunikasi. Berikut best practices yang harus diikuti:
1. Pilih Chart yang Tepat
| Prinsip | Penjelasan |
|---|---|
| Jangan gunakan 3D kecuali perlu | Chart 3D sering menyulitkan pembacaan β 2D lebih akurat |
| Hindari pie chart untuk 5+ kategori | Sulit membandingkan irisan yang mirip β gunakan bar chart |
| Mulai Y-axis dari 0 | Mulai dari angka lain bisa menyesatkan persepsi |
| Gunakan warna bermakna | Hijau = positif, merah = negatif. Hindari terlalu banyak warna |
2. Konsistensi Warna & Style
import matplotlib.pyplot as plt
# Definisikan color palette konsisten
COLORS = {
'primary': '#3498db',
'secondary': '#2ecc71',
'danger': '#e74c3c',
'warning': '#f1c40f',
'info': '#9b59b6',
'dark': '#2c3e50',
'light': '#ecf0f1'
}
# Custom style sheet
plt.rcParams.update({
'figure.figsize': (10, 6),
'figure.dpi': 100,
'axes.titlesize': 16,
'axes.titleweight': 'bold',
'axes.labelsize': 12,
'xtick.labelsize': 10,
'ytick.labelsize': 10,
'axes.grid': True,
'grid.alpha': 0.3,
'font.family': 'sans-serif',
'axes.spines.top': False, # Hilangkan border atas
'axes.spines.right': False, # Hilangkan border kanan
})
3. Label & Anotasi yang Jelas
- Sertakan judul yang deskriptif (apa yang ditunjukkan chart)
- Tambahkan label sumbu dengan unit (Rp, %, kg, dll)
- Berikan sumber data di bagian bawah chart
- Gunakan anotasi untuk menyorot data penting
- Pastikan font cukup besar untuk dibaca (min 10pt)
4. Aksesibilitas
- Jangan hanya mengandalkan warna β gunakan juga pattern/tekstur untuk membedakan data
- Gunakan color blind-friendly palettes (cividis, viridis, plasma)
- Alt text untuk gambar chart
- Pastikan kontras cukup untuk dibaca
5. Tips Performa
| Tips | Alasan |
|---|---|
Gunakan plt.tight_layout() | Mencegah label terpotong |
Simpan dengan bbox_inches='tight' | Output rapi tanpa whitespace berlebih |
Gunakan DPI 150 untuk web | Resolusi cukup tanpa file terlalu besar |
| Downsample data besar (10K+ points) | Scatter plot dengan terlalu banyak titik lambat |
Gunakan rasterized=True untuk SVG | Mengecilkan ukuran file untuk data besar |
8. Quiz: Uji Pemahamanmu!
Setelah membaca tutorial di atas, jawablah 5 pertanyaan berikut untuk menguji pemahamanmu tentang Data Visualization dengan Python: