Khóa học
Plotly không chỉ để tạo ra các trực quan hoá đẹp mắt; mục tiêu của nó là khai mở toàn bộ tiềm năng dữ liệu của bạn và hé lộ những insight đáng lẽ sẽ bị bỏ lỡ. Đây là cây cầu giữa ngôn ngữ của những con số và ngôn ngữ của câu chuyện, giúp cá nhân và tổ chức đưa ra quyết định sáng suốt và tạo ra thay đổi có ý nghĩa.
Đó là cách ChatGPT mô tả Plotly. Rõ ràng, Plotly là một trong những thư viện trực quan hoá dữ liệu tốt nhất hiện nay.

Nó tạo ra các biểu đồ tương tác cao và trực quan bắt mắt như ví dụ dưới đây:
Hôm nay, bạn sẽ học các nền tảng để tạo các biểu đồ tuyệt vời với Plotly.
Những điều cơ bản về Plotly Express
Giống như mọi hướng dẫn khác, chúng ta bắt đầu bằng cách cài đặt thư viện qua pip (hoặc nếu bạn thích thì dùng conda).
$ pip install --upgrade plotly
$ conda install -c conda-forge plotly
Plotly được cập nhật thường xuyên, nên hãy đảm bảo bao gồm thẻ --upgrade nếu bạn đã cài thư viện trước đó.
Hướng dẫn này tập trung vào Express API của Plotly, được giới thiệu vào năm 2019, mang lại nhiều lợi ích so với cách tương tác cũ với thư viện Plotly lõi:
- Cú pháp đơn giản (đọc gần như tiếng Anh tự nhiên)
- Phạm vi trực quan hoá đa dạng (hoặc công cụ để tự tạo loại biểu đồ của bạn)
- Tự động co giãn trục và màu sắc
- Tích hợp với pandas (bạn có thể dùng Plotly làm backend vẽ cho hàm
.plotcủa Pandas)
Dưới đây là “giải phẫu” của một biểu đồ cơ bản trong Plotly Express:
import plotly.express as px
fig = px.plotting_function(
dataframe,
x='column-for-xaxis',
y='column-for-yaxis',
title='Title For the Plot',
width=width_in_pixels,
height=height_in_pixels
)
fig.show()
Các loại biểu đồ khác nhau nằm dưới tên riêng của chúng, như histogram hay scatter thuộc mô-đun express, được nạp với bí danh px. Tham số đầu tiên của mọi hàm vẽ là dataframe và tên cột cho trục X và Y.
Thực hành tốt khuyến nghị bạn nên đặt title có tính thông tin cho biểu đồ để người xem biết biểu đồ nói về điều gì.
Khi một hàm vẽ chạy, nó trả về một đối tượng Figure, và bạn gọi phương thức show trên đó để hiển thị biểu đồ trong notebook của mình.
Để bắt đầu tạo biểu đồ, chúng ta cần một tập dữ liệu. Trong hướng dẫn này, chúng ta dùng bộ dữ liệu Diamonds. Nó có sự kết hợp đẹp giữa đặc trưng số và phân loại - hoàn hảo cho mục đích của bài viết.
import pandas as pd
diamonds = pd.read_csv("data/diamonds.csv")
diamonds.head()

Bộ dữ liệu chứa hơn 53 nghìn viên kim cương với 10 đặc tính vật lý. Bạn có thể khám phá các thống kê cơ bản của dữ liệu bên dưới.
diamonds.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 53940 entries, 0 to 53939
Data columns (total 10 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 carat 53940 non-null float64
1 cut 53940 non-null object
2 color 53940 non-null object
3 clarity 53940 non-null object
4 depth 53940 non-null float64
5 table 53940 non-null float64
6 price 53940 non-null int64
7 x 53940 non-null float64
8 y 53940 non-null float64
9 z 53940 non-null float64
dtypes: float64(6), int64(1), object(3)
memory usage: 4.1+ MB
diamonds.describe()
Một trong những việc đầu tiên khi thực hiện Phân tích dữ liệu khám phá (EDA) là khám phá các phân phối riêng lẻ.
Plotly cung cấp nhiều biểu đồ cho tác vụ này: histogram, boxplot, violin plot, bar chart, v.v. Hãy xem một vài ví dụ.
Histogram trong Plotly Express
Histogram có lẽ là trực quan đầu tiên mà mọi người học.
Nó sắp xếp các giá trị của một phân phối vào các “bin”. Sau đó, các cột biểu thị có bao nhiêu giá trị rơi vào mỗi bin:
import plotly.express as px
fig = px.histogram(
diamonds,
x="price",
title="Histogram of diamond prices",
width=600,
height=400,
)
fig.show()

Nếu bạn rê chuột qua bất kỳ cột nào, bạn có thể thấy khoảng của bin tương ứng. Plotly tự động tìm số lượng bin, nhưng nếu muốn tự đặt, bạn có thể dùng tham số nbins.
Tuy nhiên, rất khó để tìm số bin “chuẩn” cho từng phân phối. Vì vậy, bạn có thể dùng thực hành phổ biến là đặt số bin bằng căn bậc hai của độ dài phân phối:
# Tìm số lượng bin phù hợp
nbins = int(len(diamonds) ** (1 / 2))
fig = px.histogram(
diamonds,
x="price",
title="Histogram of diamond prices",
nbins=nbins,
width=600,
height=400,
)
fig.show()
Biểu đồ cột (bar chart) trong Plotly Express
Histogram phân tích các đặc trưng định lượng. Để phân tích dữ liệu phân loại, ta chuyển sang biểu đồ cột. Chẳng hạn, truyền cột phân loại cut vào hàm histogram, ta nhận được một dạng bar chart gọi là countplot. Đúng vậy, nó đếm số quan sát trong mỗi hạng mục.
fig = px.histogram(diamonds, x="cut")
fig.show()

Nhưng khoan, chúng ta chưa đặt nhãn cho biểu đồ! Hãy khắc phục bằng update_layout, hàm có thể chỉnh sửa nhiều khía cạnh của một figure sau khi tạo.
fig.update_layout(
title="The number of diamonds in each diamond cut category",
xaxis_title="",
yaxis_title="Count",
)

Bạn đã biết title làm gì. xaxis_title và yaxis_title thay thế nhãn trục do Plotly tạo sẵn (vốn chỉ là tên cột).
Giờ hãy xem giá trung bình cho từng hạng mục độ cắt kim cương. Trước hết, dùng pandas groupby:
mean_prices = (
diamonds.groupby("cut")["price"].mean().reset_index()
)
mean_prices

Nối thêm reset_index vào cuối thao tác groupby sẽ biến đầu ra thành DataFrame, và Plotly “ưu ái” DataFrame. Vậy hãy truyền nó vào hàm bar:
fig = px.bar(mean_prices, x="cut", y="price")
fig.update_layout(
title="Average diamond prices for each cut category",
xaxis_title="",
yaxis_title="Mean price ($)",
)
fig.show()

bar nhận một đặc trưng phân loại và một đặc trưng số, tạo một cột cho mỗi hàng trong DataFrame được truyền vào. Kết quả là phép so sánh giá từng loại kim cương dễ nhìn.
Box plot trong Plotly Express
Một biểu đồ phổ biến khác để phân tích phân phối là boxplot, tạo với box trong Plotly Express:
fig = px.box(diamonds, x="clarity", y="carat")
fig.update_layout(
title="Distribution of diamond carats for each clarity category",
xaxis_title="Clarity",
yaxis_title="Carat",
)
fig.show()

Thay vì tạo cột chỉ hiển thị giá trị trung bình của carat, boxplot hiển thị nhiều thống kê:

Bạn có thể thấy:
- Giá trị nhỏ nhất/lớn nhất
- Trung vị
- Phân vị 25%
- Phân vị 75%
- và các ngoại lệ (outlier)
cho từng hạng mục độ trong suốt (clarity) của kim cương.
Violin plot trong Plotly Express
Một biểu đồ thú vị khác để khám phá phân phối là violin plot. Về cơ bản, violin plot là box plot với vài điểm nhấn bổ sung:
fig = px.violin(diamonds, x="cut", y="price")
fig.show()

Thay vì hiển thị một hộp, nó vẽ một đường cong mượt biểu thị mật độ của đặc trưng. Để chồng thêm box plot bên trong, bạn có thể đặt thuộc tính box là True:
fig = px.violin(diamonds, x="cut", y="price", box=True)
fig.show()

Không giống box plot chỉ hiển thị các thống kê tóm tắt, violin plot còn cho thấy hình dạng của phân phối.
Trực quan hoá mối quan hệ giữa các đặc trưng với Plotly Express
Bạn sẽ bắt đầu thấy các mẫu và insight mới khi vẽ các đặc trưng có liên hệ chặt chẽ. Ví dụ, nếu ta giả định carat (khối lượng) của kim cương là yếu tố chính quyết định giá, hãy khám phá mối liên hệ đó.
Scatterplot trong Plotly Express
Ta có thể dùng scatterplot (px.scatter) để vẽ mọi viên kim cương trong tập dữ liệu dưới dạng điểm. Vị trí điểm được xác định bởi giá và carat tương ứng:
fig = px.scatter(diamonds, x="price", y="carat")
fig.update_layout(
title="Price vs. Carat",
xaxis_title="Price ($)",
yaxis_title="Carat",
)
fig.show()

Chúng ta gặp phải vấn đề overplotting, xảy ra khi có quá nhiều dữ liệu hiển thị trong một biểu đồ. Thay vì cho thấy các mẫu và xu hướng thực sự, overplotting lại che mờ chúng.
Có thể khắc phục bằng cách chỉ vẽ ~10% tập dữ liệu, như vậy vẫn đủ để lộ ra các mẫu nếu có:
fig = px.scatter(
diamonds.sample(5000), x="price", y="carat"
)
fig.update_layout(
title="Price vs. Carat",
xaxis_title="Price ($)",
yaxis_title="Carat",
)
fig.show()

Trong lời gọi scatter, chúng ta chỉ truyền 5000 hàng (.sample(5000)), qua đó cho thấy xu hướng tăng nhẹ trong mối quan hệ giữa giá và carat.
Heatmap trong Plotly Express
Heatmap rất phù hợp để trực quan hoá các tập dữ liệu phức tạp, như một ma trận lớn nơi các con số dày đặc khiến khó nhận ra mẫu.
Một heatmap gán màu dựa trên độ lớn của từng ô trong ma trận. Một tình huống hữu ích là khi xem ma trận tương quan của một tập dữ liệu.
Tương quan đo lường mối quan hệ tuyến tính giữa các đặc trưng số. Vì vậy, mỗi ô của ma trận tương quan đại diện cho tương quan giữa một cặp đặc trưng.
Bạn có thể tính ma trận tương quan của bất kỳ tập dữ liệu nào bằng phương thức corr của pandas, trả về một DataFrame. Nếu truyền nó vào hàm imshow của Express, bạn sẽ có một heatmap:
import plotly.express as px
# Create heatmap using Plotly Express
fig = px.imshow(
diamonds.corr(),
color_continuous_scale="Inferno_r",
)
# Show plot
fig.show()

Giá trị tương quan nằm trong khoảng từ -1 đến 1. Các giá trị gần biên của khoảng biểu thị mối quan hệ tuyến tính dương hoặc âm mạnh giữa các đặc trưng.
Chúng ta chọn thang màu Inferno đảo ngược cho tham số color_continuous_scale. Bạn có thể chọn các thang màu khác từ trang thang màu trong tài liệu Plotly.
Tùy biến biểu đồ trong Plotly Express
Một trong những điểm mạnh nhất của API Plotly Express là khả năng tuỳ biến biểu đồ dễ dàng.
Hàm update_layout có rất nhiều tham số để bạn chỉnh sửa hầu như mọi khía cạnh của biểu đồ.
Tùy nơi biểu đồ của bạn sẽ được hiển thị, trách nhiệm của bạn là làm cho chúng trông chỉnh chu với mọi đối tượng, bối cảnh hoặc phương tiện.
Một trong những điều đầu tiên cần chọn là chủ đề (theme) biểu đồ. Theme trong Plotly là cấu hình mặc định điều khiển hầu hết các thành phần của biểu đồ.
Bạn có thể thay đổi bằng tham số template của bất kỳ hàm vẽ nào:
sample = diamonds.sample(3000)
fig = px.scatter(
sample, x="price", y="carat", template="ggplot2"
)
fig.show()

Một vài theme phổ biến là ggplot2, seaborn, plotly_dark và presentation. Bạn có thể xem danh sách đầy đủ bằng cách gọi plotly.io.templates.
Màu sắc
Đến giờ các scatterplot của chúng ta mới là hai chiều. Nhưng ta có thể bổ sung thông tin thông qua màu sắc.
Ví dụ, ta có thể tô màu mỗi điểm dựa trên hạng mục kim cương. Để làm vậy, bạn chỉ cần truyền cut vào tham số color:
sample = diamonds.sample(3000)
fig = px.scatter(sample, x="price", y="carat", color="cut")
fig.show()

Tham số cut cũng buộc hiển thị chú giải (legend) trên biểu đồ, cho biết màu của từng hạng mục.
Kích thước điểm đánh dấu (marker)
Một cách khác là biểu diễn đặc trưng số qua kích thước của các điểm.
Bằng cách đặt tham số size là carat, ta có các điểm khác kích thước dựa trên carat của kim cương:
fig = px.scatter(sample, x="price", y="x", size="carat")
fig.show()

Nếu dùng cả màu lẫn kích thước thì sao? Được chứ!
fig = px.scatter(
sample, x="price", y="x", size="carat", color="cut"
)
fig.show()

Nhưng biểu đồ này không quá hữu ích vì chứa quá nhiều thông tin để mắt thường xử lý. Thực hành tốt là không nhồi nhét quá ba đặc trưng vào một biểu đồ.
Kết luận
Chúc mừng bạn đã đi đến cuối! Bạn đã học đủ trong hướng dẫn này để tự học Plotly tiếp qua một số tài nguyên khác của chúng tôi:
- Khoá học Giới thiệu trực quan hoá dữ liệu với Plotly trong Python
- Hướng dẫn Trực quan hoá dữ liệu với Plotly trong R
- Hướng dẫn Tạo histogram trong Plotly
Bạn cũng có thể tìm hiểu về API Graph Objects của Plotly để có nhiều tuỳ biến hơn, kiểm soát đầy đủ khả năng tương tác và hoạt ảnh, cũng như hỗ trợ các loại trực quan hoá nâng cao.