MinAI - Về trang chủ
Lý thuyết
8/154 giờ
Đang tải...

Trực Quan Hóa Dữ Liệu

Matplotlib, Seaborn và Plotly — từ biểu đồ tĩnh đến tương tác

0

🎯 Mục tiêu bài học

TB5 min

Sau bài học này, bạn sẽ:

✅ Tạo biểu đồ cơ bản với Matplotlib (line, bar, scatter, histogram)

✅ Vẽ biểu đồ thống kê đẹp với Seaborn (distribution, categorical, relational)

✅ Tạo biểu đồ tương tác với Plotly (zoom, hover, animation)

✅ Biết chọn loại biểu đồ phù hợp cho từng loại dữ liệu

✅ Customize và export biểu đồ chuyên nghiệp

Thời gian: 4 giờ | Độ khó: Beginner → Intermediate | Yêu cầu: Pandas (Bài 6-7)

1

📖 Bảng Thuật Ngữ Quan Trọng

TB5 min
Thuật ngữTiếng ViệtMô tả
FigureKhung vẽContainer chứa toàn bộ biểu đồ
AxesTrục/subplotMột biểu đồ riêng lẻ trong figure
Distribution plotBiểu đồ phân phốiHistogram, KDE, Box — xem phân bố dữ liệu
Categorical plotBiểu đồ phân loạiBar, Count — so sánh giữa các nhóm
Relational plotBiểu đồ quan hệScatter, Line — tương quan giữa biến
HeatmapBản đồ nhiệtMa trận màu — thể hiện giá trị bằng màu sắc
Interactive plotBiểu đồ tương tácZoom, hover, click — dùng Plotly
FacetingChia nhỏChia 1 biểu đồ thành nhiều panel theo category
Color paletteBảng màuBộ màu được chọn sẵn cho biểu đồ
AnnotationChú thíchText/mũi tên đánh dấu trên biểu đồ

Checkpoint

Phân biệt Figure vs Axes trong Matplotlib? Khi nào cần tạo nhiều Axes?

2

📊 Matplotlib — Nền Tảng

TB5 min

Trực quan hóa dữ liệu (Data Visualization) là gì? Là biến con số khô khan thành hình ảnh trực quan — giúp bạn nhìn thấy pattern, trend, và outlier mà không thể thấy bằng bảng số.

Tại sao quan trọng? Một biểu đồ tốt giá trị hơn 1000 dòng số liệu. Trong Data Science, visualization giúp bạn:

  • Khám phá dữ liệu (EDA) — tìm pattern, outlier
  • Truyền tải insight cho stakeholders
  • Kiểm tra giả thuyết trực quan trước khi test thống kê

Setup

Python
1import matplotlib.pyplot as plt
2import numpy as np
3import pandas as pd
4
5# Style đẹp hơn mặc định
6plt.style.use('seaborn-v0_8-whitegrid')

Figure và Axes

Python
1# Cách 1: Quick plot
2plt.figure(figsize=(10, 6))
3plt.plot([1, 2, 3, 4], [10, 20, 25, 30])
4plt.title("Quick Plot")
5plt.show()
6
7# Cách 2: Object-oriented (KHUYẾN KHÍCH)
8fig, ax = plt.subplots(figsize=(10, 6))
9ax.plot([1, 2, 3, 4], [10, 20, 25, 30])
10ax.set_title("OOP Style")
11ax.set_xlabel("X")
12ax.set_ylabel("Y")
13plt.show()
14
15# Cách 3: Multiple subplots
16fig, axes = plt.subplots(2, 2, figsize=(12, 10))
17axes[0, 0].plot([1,2,3], [1,4,9])
18axes[0, 1].bar(['A','B','C'], [3,7,5])
19axes[1, 0].scatter(np.random.rand(50), np.random.rand(50))
20axes[1, 1].hist(np.random.randn(1000), bins=30)
21plt.tight_layout()
22plt.show()

Các loại biểu đồ cơ bản

Python
1fig, axes = plt.subplots(2, 3, figsize=(15, 10))
2
3# Line Plot
4x = np.linspace(0, 10, 100)
5axes[0,0].plot(x, np.sin(x), label='sin(x)')
6axes[0,0].plot(x, np.cos(x), label='cos(x)', linestyle='--')
7axes[0,0].legend()
8axes[0,0].set_title("Line Plot")
9
10# Bar Chart
11axes[0,1].bar(['Q1','Q2','Q3','Q4'], [100, 150, 120, 180], color='steelblue')
12axes[0,1].set_title("Bar Chart")
13
14# Scatter Plot
15axes[0,2].scatter(np.random.rand(50), np.random.rand(50),
16 c=np.random.rand(50), s=np.random.rand(50)*500, alpha=0.6)
17axes[0,2].set_title("Scatter Plot")
18
19# Histogram
20axes[1,0].hist(np.random.randn(1000), bins=30, edgecolor='black')
21axes[1,0].set_title("Histogram")
22
23# Pie Chart
24axes[1,1].pie([30, 25, 20, 15, 10], labels=['A','B','C','D','E'], autopct='%1.1f%%')
25axes[1,1].set_title("Pie Chart")
26
27# Box Plot
28data = [np.random.normal(0, std, 100) for std in range(1, 4)]
29axes[1,2].boxplot(data, labels=['σ=1', 'σ=2', 'σ=3'])
30axes[1,2].set_title("Box Plot")
31
32plt.suptitle("Matplotlib Basics", fontsize=16, fontweight='bold')
33plt.tight_layout()
34plt.show()

Luôn dùng OOP style (fig, ax = plt.subplots()) thay vì plt.plot(). Dễ customize và ít bug hơn khi vẽ nhiều biểu đồ.

Checkpoint

Tạo figure 2×2: Line, Bar, Scatter, Histogram. Thêm title, xlabel, ylabel cho mỗi subplot.

3

🎨 Seaborn — Statistical Visualization

TB5 min

Setup

Python
1import seaborn as sns
2
3sns.set_theme(style="whitegrid")
4
5# Load sample dataset
6tips = sns.load_dataset("tips")
7print(tips.head())

Distribution Plots — Biểu đồ xem phân bố dữ liệu

Dùng khi nào? Khi cần trả lời: "Dữ liệu phân bố ra sao? Có lệch không? Có outlier không?"

Biểu đồCho biết gì?Dùng khi
HistogramPhân bố tần suấtXem data tập trung ở đâu
KDEPhân bố mượt (đường cong)So sánh phân bố 2+ nhóm
Box PlotMedian, Q1/Q3, outlierPhát hiện outlier, so sánh nhóm
ViolinBox + KDE kết hợpThấy cả phân bố lẫn thống kê
Python
1fig, axes = plt.subplots(2, 2, figsize=(12, 10))
2
3# Histogram + KDE
4sns.histplot(data=tips, x="total_bill", kde=True, ax=axes[0,0])
5axes[0,0].set_title("Histogram + KDE")
6
7# KDE Plot grouped
8sns.kdeplot(data=tips, x="total_bill", hue="time", fill=True, ax=axes[0,1])
9axes[0,1].set_title("KDE by Time")
10
11# Box Plot
12sns.boxplot(data=tips, x="day", y="total_bill", hue="time", ax=axes[1,0])
13axes[1,0].set_title("Box Plot")
14
15# Violin Plot
16sns.violinplot(data=tips, x="day", y="total_bill", hue="sex",
17 split=True, ax=axes[1,1])
18axes[1,1].set_title("Violin Plot")
19
20plt.tight_layout()
21plt.show()

Categorical Plots — So sánh nhóm

Python
1fig, axes = plt.subplots(1, 3, figsize=(15, 5))
2
3# Bar Plot (mean + CI)
4sns.barplot(data=tips, x="day", y="total_bill", hue="sex",
5 errorbar="sd", ax=axes[0])
6axes[0].set_title("Bar Plot (Mean ± SD)")
7
8# Count Plot
9sns.countplot(data=tips, x="day", hue="time", palette="Set2", ax=axes[1])
10axes[1].set_title("Count Plot")
11
12# Swarm Plot
13sns.swarmplot(data=tips, x="day", y="total_bill", hue="sex", ax=axes[2])
14axes[2].set_title("Swarm Plot")
15
16plt.tight_layout()
17plt.show()

Relational Plots — Tương quan

Python
1# Scatter với nhiều dimensions
2plt.figure(figsize=(10, 6))
3sns.scatterplot(data=tips, x="total_bill", y="tip",
4 hue="time", size="size", style="sex",
5 palette="viridis", sizes=(20, 200))
6plt.title("Total Bill vs Tip (Multi-dimensional)")
7plt.show()
8
9# Regression plot
10sns.lmplot(data=tips, x="total_bill", y="tip",
11 hue="smoker", col="time", height=5)
12plt.show()

Heatmap — Ma trận tương quan

Python
1plt.figure(figsize=(8, 6))
2numeric_cols = tips.select_dtypes(include=[np.number])
3corr = numeric_cols.corr()
4
5sns.heatmap(corr, annot=True, cmap="coolwarm", center=0,
6 fmt=".2f", linewidths=0.5, square=True)
7plt.title("Correlation Heatmap")
8plt.show()

Pair Plot — Toàn cảnh

Python
1# Tất cả cặp biến
2sns.pairplot(tips, hue="time", diag_kind="kde", corner=True)
3plt.show()

Chọn biểu đồ theo mục đích:

Mục đíchBiểu đồ
Phân phối 1 biếnhistplot, kdeplot, boxplot
So sánh nhómbarplot, countplot, violinplot
Tương quan 2 biếnscatterplot, regplot
Correlation matrixheatmap
Khám phá toàn bộpairplot

Checkpoint

Vẽ 4 biểu đồ Seaborn trên dataset tips: histogram, boxplot, scatter, heatmap. Tất cả trong 1 figure 2×2.

4

✨ Plotly — Interactive Visualization

TB5 min

Plotly vs Matplotlib/Seaborn: Matplotlib/Seaborn tạo ảnh tĩnh (PNG). Plotly tạo biểu đồ tương tác — zoom, hover xem giá trị, click chọn nhóm. Rất phù hợp cho dashboard và trình bày.

Plotly Express — Quick Interactive Plots

Python
1import plotly.express as px
2
3# Sample data
4df = px.data.gapminder()
5tips = px.data.tips()

Scatter Plot (Interactive)

Python
1fig = px.scatter(df.query("year == 2007"),
2 x="gdpPercap", y="lifeExp",
3 color="continent", size="pop",
4 hover_name="country",
5 log_x=True,
6 title="GDP vs Life Expectancy (2007)")
7fig.show()

Bar Chart

Python
1# Grouped bar
2fig = px.bar(tips, x="day", y="total_bill", color="sex",
3 barmode="group",
4 title="Total Bill by Day and Sex")
5fig.show()

Histogram với Marginal

Python
1fig = px.histogram(tips, x="total_bill", nbins=30,
2 color="time",
3 marginal="box", # hoặc "rug", "violin"
4 title="Distribution of Total Bill")
5fig.show()

Box & Violin

Python
1fig = px.box(tips, x="day", y="total_bill", color="smoker",
2 notched=True,
3 title="Total Bill Distribution")
4fig.show()

Choropleth Map

Python
1fig = px.choropleth(df.query("year == 2007"),
2 locations="iso_alpha",
3 color="lifeExp",
4 hover_name="country",
5 color_continuous_scale="Viridis",
6 title="Life Expectancy (2007)")
7fig.show()

Animation!

Python
1fig = px.scatter(df, x="gdpPercap", y="lifeExp",
2 animation_frame="year",
3 animation_group="country",
4 size="pop", color="continent",
5 hover_name="country",
6 log_x=True, size_max=55,
7 range_x=[100, 100000],
8 range_y=[25, 90],
9 title="Gapminder Animation")
10fig.show()

Khi nào dùng Matplotlib/Seaborn vs Plotly?

Tình huốngChọn
Report/Paper (static)Matplotlib/Seaborn
Notebook khám pháPlotly
Dashboard/Web appPlotly + Dash
PresentationPlotly (wow factor)
Publication qualityMatplotlib (fine control)

Checkpoint

Tạo 1 scatter plot interactive với Plotly: color theo category, size theo value, hover hiện tên. Thử zoom và hover!

5

🛠️ Graph Objects — Advanced Plotly

TB5 min

Custom Figure

Python
1import plotly.graph_objects as go
2from plotly.subplots import make_subplots
3
4fig = go.Figure()
5
6fig.add_trace(go.Scatter(
7 x=[1, 2, 3, 4], y=[10, 11, 12, 13],
8 mode='lines+markers', name='Line 1'
9))
10fig.add_trace(go.Scatter(
11 x=[1, 2, 3, 4], y=[12, 9, 15, 12],
12 mode='lines+markers', name='Line 2'
13))
14
15fig.update_layout(
16 title="Custom Plot",
17 xaxis_title="X", yaxis_title="Y"
18)
19fig.show()

Dual Y-Axis

Python
1fig = go.Figure()
2
3fig.add_trace(go.Scatter(
4 x=[1,2,3,4], y=[100,200,300,400],
5 name="Revenue ($)", yaxis="y1"
6))
7fig.add_trace(go.Bar(
8 x=[1,2,3,4], y=[10,20,15,25],
9 name="Orders", yaxis="y2", opacity=0.5
10))
11
12fig.update_layout(
13 yaxis=dict(title="Revenue ($)", side="left"),
14 yaxis2=dict(title="Orders", side="right", overlaying="y"),
15 title="Dual Y-Axis"
16)
17fig.show()

Subplots

Python
1fig = make_subplots(rows=2, cols=2,
2 subplot_titles=("Scatter", "Bar", "Line", "Histogram"))
3
4fig.add_trace(go.Scatter(x=[1,2,3], y=[4,5,6], mode='markers'), row=1, col=1)
5fig.add_trace(go.Bar(x=['A','B','C'], y=[3,7,5]), row=1, col=2)
6fig.add_trace(go.Scatter(x=[1,2,3], y=[1,2,3], mode='lines'), row=2, col=1)
7fig.add_trace(go.Histogram(x=np.random.randn(500)), row=2, col=2)
8
9fig.update_layout(height=600, title_text="Subplots")
10fig.show()

Export

Python
1# Interactive HTML
2fig.write_html("chart.html")
3
4# Static image
5fig.write_image("chart.png", scale=2) # Cần kaleido
6fig.write_image("chart.pdf")
6

🎯 Styling và Best Practices

TB5 min

Chọn đúng biểu đồ

Câu hỏiBiểu đồ phù hợp
Dữ liệu thay đổi theo thời gian?Line chart
So sánh giữa các nhóm?Bar chart
Mối quan hệ 2 biến?Scatter plot
Phân bố dữ liệu?Histogram / Box plot
Tỷ lệ phần?Pie chart (dùng ít, thích bar hơn)
Tương quan nhiều biến?Heatmap

Seaborn Themes

Python
1# Themes: darkgrid, whitegrid, dark, white, ticks
2sns.set_theme(style="whitegrid", palette="Set2",
3 font_scale=1.2)

Color Palettes

Python
1# Categorical: Set1, Set2, Dark2, Paired, husl
2# Sequential: Blues, Reds, Viridis, coolwarm
3# Custom
4custom = ["#FF6B6B", "#4ECDC4", "#45B7D1", "#96CEB4"]
5sns.set_palette(custom)

Plotly Templates

Python
1# plotly, plotly_white, plotly_dark, ggplot2, seaborn, simple_white
2fig = px.scatter(tips, x="total_bill", y="tip",
3 template="plotly_white")

Best Practices:

  1. Luôn có title và label trục rõ ràng
  2. Chọn đúng loại biểu đồ cho loại dữ liệu
  3. Không quá 5-7 màu trong 1 biểu đồ
  4. Bắt đầu Y-axis từ 0 cho bar chart (tránh gây hiểu lầm)
  5. Dùng colorblind-friendly palette khi chia sẻ rộng

Checkpoint

Bạn đã biết khi nào dùng Histogram vs Box vs Violin chưa? Khi nào dùng Bar vs Line?

7

📝 Tổng Kết

TB5 min

So sánh 3 thư viện

Tiêu chíMatplotlibSeabornPlotly
Ease of useMediumEasyEasy
Static
Interactive
ThemesManualBuilt-inBuilt-in
StatisticalManual✅ Auto CILimited
3DBasic✅ Excellent
MapWith Basemap✅ Built-in
AnimationComplex✅ Easy
Dashboard✅ Dash

Quick Reference

Python
1# Matplotlib
2fig, ax = plt.subplots()
3ax.plot(x, y)
4plt.show()
5
6# Seaborn
7sns.histplot(data=df, x="col", hue="cat", kde=True)
8sns.scatterplot(data=df, x="x", y="y", hue="cat")
9sns.heatmap(corr, annot=True)
10sns.pairplot(df)
11
12# Plotly
13fig = px.scatter(df, x="x", y="y", color="cat", size="val")
14fig = px.bar(df, x="cat", y="val", color="group")
15fig.show()

Bài tiếp theo: Thực hành Visualization với dataset thực tế — tạo báo cáo trực quan! 📊

Câu hỏi tự kiểm tra

  1. Khi nào nên dùng biểu đồ Line chart thay vì Bar chart? Cho ví dụ cụ thể.
  2. So sánh Matplotlib, Seaborn và Plotly — mỗi thư viện phù hợp trong trường hợp nào?
  3. Heatmap dùng để trực quan hóa điều gì? Tại sao nó hữu ích trong phân tích tương quan?
  4. Kể ra 3 best practices quan trọng khi tạo biểu đồ trực quan hóa dữ liệu.

🎉 Tuyệt vời! Bạn đã hoàn thành bài học Visualization!

Tiếp theo: Thực hành Visualization với dataset thực tế để tạo báo cáo trực quan chuyên nghiệp!