Chuyển đến nội dung chính

Hướng dẫn Altair trong Python: Trực quan hóa dữ liệu

Tìm hiểu cách tạo trực quan hóa dữ liệu trong Python bằng Altair và Bộ dữ liệu Phim.
Đã cập nhật 5 thg 10, 2026  · 12 phút đọc

Khám phá cùng AI

ChatGPTClaudePerplexity
xây dựng kỹ năng python để phát triển sự nghiệp cùng datacamp

Khả năng tạo ra các biểu đồ dễ hiểu nhưng tinh tế là yếu tố then chốt để trở thành một nhà khoa học dữ liệu thành công. Trực quan hóa là cách tuyệt vời để kể câu chuyện ẩn sau dữ liệu của bạn. Nó làm nổi bật các mối quan hệ trong dữ liệu và hé lộ những thông tin mà mắt người có thể nhìn thấy nhưng con số đơn thuần thì không truyền tải được. Nhưng bạn biết điều gì còn tốt hơn trực quan hóa thông thường cho phân tích dữ liệu không? Trực quan hóa tương tác!

Đáng tiếc là với người mới bắt đầu, điều đó có thể trông như một nhiệm vụ khó nhằn. Python và R đều cung cấp một loạt công cụ và mẹo để hỗ trợ bạn. Trong hướng dẫn này, chúng tôi sẽ giới thiệu bạn với Altair. Với Altair, bạn có thể tạo ra các trực quan hóa ý nghĩa, tinh tế và hiệu quả chỉ với vài dòng code trong thời gian rất ngắn. Bắt đầu thôi!

Altair là gì?

Altair là một thư viện Python được thiết kế cho trực quan hóa thống kê. Nó mang tính khai báo (chúng ta sẽ nói kỹ hơn về định nghĩa này sau). Altair dựa trên Vega và Vega-Lite, cả hai đều là “ngữ pháp trực quan hóa” cho phép bạn mô tả diện mạo trực quan và hành vi tương tác của một biểu đồ ở định dạng JSON.

API mệnh lệnh vs. API khai báo

Như đã đề cập, Python đã có sẵn một danh sách dài các công cụ và thư viện tuyệt vời phục vụ trực quan hóa dữ liệu, và nhiều công cụ còn hỗ trợ trực quan hóa tương tác. Vậy điều gì khiến Altair nổi bật?

Câu trả lời nằm ở bản chất khai báo của nó so với các API mang tính mệnh lệnh khác.

Với API mệnh lệnh, bạn phải tập trung vào ‘làm thế nào’ thay vì ‘bạn muốn làm gì’. Bạn sẽ phải suy nghĩ nhiều về đoạn code cần thiết để tạo biểu đồ và tự tay chỉ định các bước vẽ – giới hạn trục, kích thước, xoay, chú giải, v.v.

Với tư cách là nhà khoa học dữ liệu, Altair cho phép bạn dành thời gian và công sức vào dữ liệu – hiểu, phân tích và trực quan hóa – thay vì vào code cần viết. Điều này có nghĩa bạn có thể định nghĩa dữ liệu và kết quả mong muốn (biểu đồ cuối cùng sẽ trông như thế nào), và Altair sẽ tự động thực hiện các thao tác cần thiết cho bạn.

Cài đặt

Trong hướng dẫn này, chúng ta sẽ sử dụng một bộ dữ liệu ví dụ từ Vega datasets. Để cài đặt Altair cùng với Vega datasets, hãy gõ lệnh sau trong cửa sổ console của bạn:

$ pip install altair vega_datasets

Nếu bạn dùng trình quản lý gói conda, lệnh tương đương là:

$ conda install -c conda-forge altair vega_datasets

Sau đó, bạn có thể chuyển sang Jupyter Notebook và import Altair để bắt đầu. Để tìm hiểu thêm về Jupyter Notebook, nhớ xem Cẩm nang hoàn chỉnh về Jupyter Notebook từ DataCamp.

Dữ liệu

Giờ chúng ta đã cài đặt Altair và Vega dataset, đến lúc tải dữ liệu. Bắt đầu với các import sau:

import pandas as pd
import altair as alt

Vì sao import Pandas?

Bởi vì dữ liệu trong Altair được xây dựng quanh Pandas DataFrame, nên bạn có thể thao tác dữ liệu trong Altair giống như khi làm việc với DataFrame của Pandas.

Và dù bên trong Altair lưu dữ liệu theo định dạng Pandas DataFrame, có nhiều cách để đưa dữ liệu vào:

  • dưới dạng Pandas DataFrame
  • dưới dạng Data hoặc đối tượng liên quan (ví dụ: UrlData, InlineData, NamedData)
  • dưới dạng chuỗi URL trỏ tới tệp văn bản định dạng JSON hoặc CSV
  • dưới dạng một đối tượng hỗ trợ geo_interface (ví dụ: Geopandas GeoDataFrame, Shapely Geometries, GeoJSON Objects)

Bộ dữ liệu Phim (Movies)

Trong hướng dẫn này, chúng ta sẽ làm việc với Movies Dataset từ Vega dataset. Bộ dữ liệu này hoặc các bộ tương tự về phim rất nổi tiếng trong cộng đồng khoa học dữ liệu, đặc biệt trong ngữ cảnh Hệ thống gợi ý. Tuy nhiên, ở đây chúng ta chỉ thực hiện phân tích dữ liệu bằng trực quan hóa với Altair.

Bộ dữ liệu chứa thông tin về phim như tiêu đề, doanh thu tại Mỹ và toàn cầu, cùng với ngân sách sản xuất, thể loại, điểm đánh giá từ IMDB và Rotten Tomatoes. Chúng ta sẽ không dùng tất cả các cột mà chỉ chọn một vài cột để hiểu cách Altair hoạt động như một công cụ trực quan hóa.

Hãy tiếp tục, lấy bộ dữ liệu và thực hiện một vài phân tích đơn giản để hiểu rõ hơn.

# Importing the Vega Dataset
from vega_datasets import data as vega_data

movies_df = pd.read_json(vega_data.movies.url)

# Checking the type of data that we get
print("movies_df is of the type: ", type(movies_df))

print("movies_df: ", movies_df.shape)
movies_df is of the type:  <class 'pandas.core.frame.DataFrame'>
movies_df:  (3201, 16)

Như bạn thấy, movies_df thực chất là một pandas DataFrame và có 3201 phim (hàng) với 16 thông tin đặc trưng (cột) cho mỗi phim. Hãy xem dữ liệu bên trong dataframe.

movies_df.head(5)
  Title US_Gross Worldwide_Gross US_DVD_Sales Production_Budget Release_Date MPAA_Rating Running_Time_min Distributor Source Major_Genre Creative_Type Director Rotten_Tomatoes_Rating IMDB_Rating IMDB_Votes
0 The Land Girls 146083.0 146083.0 NaN 8000000.0 Jun 12 1998 R NaN Gramercy None None None None NaN 6.1 1071.0
1 First Love, Last Rites 10876.0 10876.0 NaN 300000.0 Aug 07 1998 R NaN Strand None Drama None None NaN 6.9 207.0
2 I Married a Strange Person 203134.0 203134.0 NaN 250000.0 Aug 28 1998 None NaN Lionsgate None Comedy None None NaN 6.8 865.0
3 Let's Talk About Sex 373615.0 373615.0 NaN 300000.0 Sep 11 1998 None NaN Fine Line None Comedy None None 13.0 NaN NaN
4 Slam 1009819.0 1087521.0 NaN 1000000.0 Oct 09 1998 R NaN Trimark Original Screenplay Drama Contemporary Fiction None 62.0 3.4 165.0

Các giá trị cột là:

movies_df.columns
Index(['Title', 'US_Gross', 'Worldwide_Gross', 'US_DVD_Sales',
       'Production_Budget', 'Release_Date', 'MPAA_Rating', 'Running_Time_min',
       'Distributor', 'Source', 'Major_Genre', 'Creative_Type', 'Director',
       'Rotten_Tomatoes_Rating', 'IMDB_Rating', 'IMDB_Votes'],
      dtype='object')

Giờ chúng ta sẽ dùng hàm to_datetime trong pandas để chuyển cột Release_Date thành ngày tháng thực rồi trích xuất giá trị ‘năm’ từ đó. Sau này chúng ta sẽ dùng cột mới này trong trực quan hóa.

def extract_year(value):
    return pd.to_datetime(value, format='%b %d %Y').year

movies_df["Year"] = movies_df["Release_Date"].apply(extract_year)

Nếu giờ bạn kiểm tra các cột, bạn sẽ thấy một cột mới tên là Year chứa giá trị năm tương ứng với từng bộ phim.

movies_df.columns
Index(['Title', 'US_Gross', 'Worldwide_Gross', 'US_DVD_Sales',
       'Production_Budget', 'Release_Date', 'MPAA_Rating', 'Running_Time_min',
       'Distributor', 'Source', 'Major_Genre', 'Creative_Type', 'Director',
       'Rotten_Tomatoes_Rating', 'IMDB_Rating', 'IMDB_Votes', 'Year'],
      dtype='object')

Giờ chúng ta sẽ bắt tay tạo một vài biểu đồ. Nhưng trước khi làm điều đó, hãy chạy đoạn code sau:

alt.renderers.enable('notebook')
RendererRegistry.enable('notebook')

Đoạn code trên cho phép Altair render trực tiếp trong Jupyter notebook, để chúng ta có thể xem các hình vẽ được tạo. Nếu gặp vấn đề, hãy xem trang khắc phục sự cố của Altair.

Ở cái nhìn đầu tiên về dữ liệu, sẽ thú vị nếu xem mối quan hệ giữa số tiền bỏ ra để làm phim (Production_Budget) và số tiền phim thực sự kiếm được (Worldwide_Gross). Chúng ta sẽ vẽ các giá trị này trên trục X và Y.

Tuy nhiên, bộ dữ liệu khá lớn – mà mục tiêu của chúng ta là thực hành với Altair. Vì vậy, tạm thời chúng ta chỉ làm việc với một số điểm dữ liệu. Hãy xem số lượng phim trong một năm nhất định trong bộ dữ liệu và chọn một năm để tập trung.

movies_df["Year"].value_counts()
2006    220
2005    210
2002    208
2004    192
2000    188
       ...
1943      1
2015      1
2027      1
2037      1
1928      1
Name: Year, Length: 91, dtype: int64

Hãy tập trung vào năm 2000 và tạo một dataframe mới movies_2000 chỉ chứa dữ liệu năm này. Nó sẽ có 188 hàng (phim).

movies_2000 = movies_df[movies_df["Year"] == 2000]
movies_2000.shape
(188, 17)

Giờ chúng ta sẽ hướng tới trực quan hóa đầu tiên. Hãy đi sâu hơn một chút vào định dạng của Altair để làm điều đó.

Biểu đồ (Charts)

Chart là đối tượng cơ bản trong Altair, và nó nhận một đối số duy nhất – một dataframe. Cách định nghĩa chart như sau:

alt.Chart(DataFrame)

Nhưng bản thân chart thì chưa làm được nhiều, ngoài việc chỉ định dữ liệu bạn muốn làm việc; sau đó bạn cần nói bạn muốn làm gì tiếp theo với dữ liệu. Lúc này chúng ta dùng marks.

Đánh dấu (Marks)

Thuộc tính mark cho phép bạn chỉ định dữ liệu sẽ được biểu diễn trên biểu đồ như thế nào. Sau đây là các thuộc tính mark cơ bản mà Altair cung cấp:

Với thuộc tính mark, chúng ta muốn mỗi giá trị trong dataFrame được đánh dấu là một điểm (hình tròn) trên biểu đồ. Do đó, ta sẽ viết:

alt.Chart(DataFrame).mark_point()

Mã hóa (Encodings)

Khi đã có dữ liệu và cách biểu diễn – chúng ta muốn chỉ định vị trí biểu diễn. Tức là thiết lập vị trí, kích thước, màu sắc, v.v. Đây là lúc dùng encodings. Vì vậy, ta có:

alt.Chart(DataFrame).mark_point().encode()

Kết hợp tất cả và thêm chi tiết để tạo trực quan hóa đầu tiên:

alt.Chart(movies_2000).mark_point().encode(
    alt.X('Production_Budget'),
    alt.Y('Worldwide_Gross')
)
<vega.vegalite.VegaLite at 0x11709a1d0>
trực quan hóa 1

Tuyệt phải không? Chúng ta không cần làm nhiều – chỉ cần làm quen vài thuật ngữ và ghép chúng lại. Giờ ta có một biểu đồ thể hiện số tiền đã chi so với doanh thu toàn cầu của các phim trong năm 2000 trong bộ dữ liệu.

Hãy làm biểu đồ này thú vị hơn. Thay vì tất cả các điểm có cùng kích thước, thử làm cho kích thước điểm tương ứng với US_Gross. Để làm vậy, ta dùng thuộc tính Size. Vậy, điểm càng lớn thì doanh thu phòng vé Mỹ càng cao. Hãy tô màu các điểm tròn thay vì chỉ viền; để làm vậy, ta thêm một đối số vào thuộc tính mark_point().

alt.Chart(movies_2000).mark_point(filled=True).encode(
    alt.X('Production_Budget'),
    alt.Y('Worldwide_Gross'),
    alt.Size('US_Gross')
)
<vega.vegalite.VegaLite at 0x117cce790>
trực quan hóa 2

Bây giờ, chúng ta có một biểu đồ mô tả ngân sách của từng phim chỉ trong bốn dòng. Còn thiếu gì? MÀU SẮC!

Nhưng chúng ta sẽ không thêm màu ngẫu nhiên cho có! Chúng ta sẽ giữ biểu đồ hấp dẫn bằng cách đưa thêm một thông tin nữa trong bộ dữ liệu, Major_Genre. Chúng ta sẽ gán mỗi thể loại một màu riêng bằng tính năng Color và thêm một chút trong suốt với OpacityValue.

alt.Chart(movies_2000).mark_point(filled=True).encode(
    alt.X('Production_Budget'),
    alt.Y('Worldwide_Gross'),
    alt.Size('US_Gross'),
    alt.Color('Major_Genre'),
    alt.OpacityValue(0.7)
)
<vega.vegalite.VegaLite at 0x118e3ff50>
trực quan hóa 3

Như vậy là tốt rồi, nhưng vẫn có thể hay hơn! Sẽ thật tuyệt nếu ta có thể di chuyển trong biểu đồ và xem chi tiết về bộ phim mà điểm dữ liệu đại diện. Tooltip cho phép ta làm điều đó...

alt.Chart(movies_2000).mark_point(filled=True).encode(
    alt.X('Production_Budget'),
    alt.Y('Worldwide_Gross'),
    alt.Size('US_Gross'),
    alt.Color('Major_Genre'),
    alt.OpacityValue(0.7),
    tooltip = [alt.Tooltip('Title'),
               alt.Tooltip('Production_Budget'),
               alt.Tooltip('Worldwide_Gross'),
               alt.Tooltip('US_Gross')
              ]
)
<vega.vegalite.VegaLite at 0x118e3ff90>
trực quan hóa 4

Tuyệt vời phải không? Nhưng hãy chờ đã, ta sẽ làm thêm nữa. Nhớ lý do tại sao ta muốn dùng Altair ngay từ đầu chứ? Đó là để tạo trực quan hóa tương tác. Tooltip đã mang lại chút tương tác khi bạn rê chuột qua các điểm. Tuy nhiên, hãy thêm chức năng interactive() đơn giản vào những gì ta đang có...

alt.Chart(movies_2000).mark_point(filled=True).encode(
    alt.X('Production_Budget'),
    alt.Y('Worldwide_Gross'),
    alt.Size('US_Gross'),
    alt.Color('Major_Genre'),
    alt.OpacityValue(0.7),
    tooltip = [alt.Tooltip('Title'),
               alt.Tooltip('Production_Budget'),
               alt.Tooltip('Worldwide_Gross'),
               alt.Tooltip('US_Gross')
              ]
).interactive()
<vega.vegalite.VegaLite at 0x118e3c750>
trực quan hóa 5

Chỉ thêm một dòng đơn giản đã cho phép bạn phóng to một khu vực – tự động cố định giá trị trục để bạn tập trung vào vùng quan tâm. Nhưng vẫn còn nhiều tính năng tương tác nâng cao khác mà bạn có thể thêm vào biểu đồ. Hãy thử một trong số đó...

Cuối cùng chúng ta đã có một biểu đồ thú vị để trình bày dữ liệu. Hãy đưa tất cả các điểm dữ liệu vào biểu đồ. Nhưng khoan, có phải sẽ quá tải nếu nhét tất cả vào một trực quan hóa không? Và chắc chắn chúng ta muốn tách theo Year mà ta đã tạo trước đó. Để làm vậy, ta sẽ dùng thuộc tính selection nâng cao.

select_year = alt.selection_single(
    name='Select', fields=['Year'], init={'Year': 1928},
    bind=alt.binding_range(min=1928, max=2046, step=10)
)

alt.Chart(movies_df).mark_point(filled=True).encode(
    alt.X('Production_Budget'),
    alt.Y('Worldwide_Gross'),
    alt.Size('US_Gross'),
    alt.Color('Major_Genre'),
    alt.OpacityValue(0.7),
    tooltip = [alt.Tooltip('Title:N'),
               alt.Tooltip('Production_Budget:Q'),
               alt.Tooltip('Worldwide_Gross:Q'),
               alt.Tooltip('US_Gross:Q')
              ]
).add_selection(select_year).transform_filter(select_year)
<vega.vegalite.VegaLite at 0x117cd4cd0>
trực quan hóa 6

Vậy là, chúng ta dùng thuộc tính add_selection để đưa select_year như một lựa chọn đơn vào biểu đồ, sau đó áp dụng transform_filter() để thực sự lọc dữ liệu trên biểu đồ.

Bạn có nhận ra một bổ sung mới khác trong code không? Chữ ‘Q’ và ‘N’ trong Tooltip. Đây là để chỉ định kiểu dữ liệu: N-Nominal (danh mục), Q-Quantitative (số học), O-Ordinal (có thứ tự), hoặc T-Temporal (thời gian hoặc khoảng thời gian).

Hãy kiểm tra năm cũ nhất và mới nhất trong bộ dữ liệu.

print("The oldest year is: ", movies_df["Year"].min())
print("The latest year is: ", movies_df["Year"].max())
The oldest year is:  1928
The latest year is:  2046

Như bạn thấy, khi kéo thanh ‘Select_Year’, không có nhiều phim trong giai đoạn 1928–1967. Và không có dữ liệu phim sau 2018 và chắc chắn không tới 2046. Chúng ta có thể dùng thuộc tính binding_range() để chỉ định khoảng năm và bước nhảy năm.

Trong dự án thực tế, những phát hiện như vậy rất quan trọng và có thể chỉ ra lỗi ở giai đoạn thu thập dữ liệu hoặc ở đâu đó trong quy trình. Bạn sẽ cần xử lý lỗi hiệu quả. Đây là bước quan trọng trong tiền xử lý dữ liệu. Xem Chuẩn bị dữ liệu với pandas để có phần giới thiệu về các bước thiết yếu này.

Hãy điều chỉnh khoảng năm, và với đó, chúng ta đã sẵn sàng với trực quan hóa cuối cùng...

select_year = alt.selection_single(
    name='Select', fields=['Year'], init={'Year': 1968},
    bind=alt.binding_range(min=1968, max=2008, step=10)
)

alt.Chart(movies_df).mark_point(filled=True).encode(
    alt.X('Production_Budget'),
    alt.Y('Worldwide_Gross'),
    alt.Size('US_Gross'),
    alt.Color('Major_Genre'),
    alt.OpacityValue(0.7),
    tooltip = [alt.Tooltip('Title:N'),
               alt.Tooltip('Production_Budget:Q'),
               alt.Tooltip('Worldwide_Gross:Q'),
               alt.Tooltip('US_Gross:Q')
              ]
).add_selection(select_year).transform_filter(select_year)
<vega.vegalite.VegaLite at 0x1180cda10>
trực quan hóa 7

Trong hướng dẫn này, bạn đã được giới thiệu về Altair. Bạn đã thấy chỉ với vài dòng code, bạn có thể tạo ra các biểu đồ đẹp, tương tác giúp kể câu chuyện dữ liệu hiệu quả hơn. Hướng dẫn này hy vọng thể hiện sức mạnh và tiềm năng của Altair. Để tìm hiểu thêm về Altair, hãy truy cập trang web chính thức của họ.

khám phá thư viện khóa học python của datacamp
Chủ đề
Python
Trực quan hóa Dữ liệu

Tìm hiểu thêm về Python

Khóa học

Nhập môn trực quan hóa dữ liệu với Matplotlib

4 giờ
236.9K
Học cách tạo, tùy chỉnh và chia sẻ các biểu đồ dữ liệu bằng Matplotlib.
Xem chi tiếtRight Arrow
Bắt Đầu Khóa Học
Xem thêmRight Arrow
Liên quan

blog

Claude Opus 4.6: Tính năng, Điểm chuẩn, Bài kiểm tra thực hành và hơn thế nữa

Mô hình mới nhất của Anthropic dẫn đầu ở mã hóa tác tử và lập luận phức tạp. Thêm vào đó, nó có cửa sổ ngữ cảnh 1M.
Matt Crabtree's photo

Matt Crabtree

10 phút

Xem ThêmXem Thêm