Hiểu cách sử dụng các lệnh geom_*()
của ggplot
Sử dụng plotly để tạo biểu đồ tương tác
Học cách vẽ bản đồ bằng leaflet
Như đã học ở phần trước, quá trình vẽ ggplot được thực hiện tương tự như quá trình vẽ đồ thị thủ công, bao gồm việc vẽ từng lớp đồ thị và các lớp sẽ được nối bằng dấu +
.
Quá trình vẽ như sau
Bắt đầu với lớp nền bằng lệnh ggplot()
- nơi người dùng thường quy định dữ liệu được vẽ và các biến nằm trên trục x và y
Thêm các lớp geom
- mỗi lớp geom sẽ thêm 1 loại biểu đồ (VD: biểu đồ cột, biểu đồ đường, biểu đồ phân tán, histogram). Các hàm này đều bắt đầu bằng geom_*
Thêm các yếu tố thiết kế vào đồ thị, chẳng hạn như nhãn trục, tiêu đề, phông chữ, kích thước, phối màu, chú giải hoặc xoay trục
VD: Vẽ số ca theo thời gian từ dữ liệu covid
# ------ Tính số ca theo ngày phát triệu chứng ------
linelist <- read_rds("../data/simulated_covid.rds") %>% mutate_if(is.Date, ymd)
case_data <- linelist %>%
group_by(date_onset) %>% # nhóm theo ngày phát triệu chứng
summarize(
no_cases = n() # đếm số ca theo nhóm
)
# ------- Vẽ biểu đồ bằng ggplot() ------
ggplot(
data = case_data, # sử dụng case_data để plot
# quy định biến sử dụng làm trục x và y
# lấy ngày phát triệu chứng làm trục x, số ca làm trục y
aes(x = date_onset, y = no_cases)
) +
geom_col( # vẽ biểu đồ cột
# thêm các tuỳ chọn khác, ở vd này quy định màu là "cornflowerblue"
color = "cornflowerblue"
)+
labs(
# thêm tên bảng và tên các trục
title = "Số ca Covid theo ngày",
x = "Ngày",
y = "Số ca"
)+
theme_minimal() # chỉnh thêm màu sắc, font size
VD: Vẽ số ca theo thời gian từ dữ liệu covid
Ngoài các màu cơ bản, ta có thể quy định màu trong R dưới dạng hex color
VD
Để có được hex color, ta có thể google “hex color”, chọn màu phù hợp và copy HEX
geom_
thông dụngLệnh geom_ |
Công dụng | Các tuỳ chỉnh |
---|---|---|
geom_histogram() |
Tạo biểu đồ cột với x là biến liên tục động được chia thành các khoảng (bin ) còn y là số quan sát trong mỗi khoảng |
Dữ liệu cần cung cấp: Giá trị cho cột
|
geom_col() |
Tạo biểu đồ cột từ x và y | Dữ liệu cần cung cấp: Giá trị cho cột x và y |
geom_bar() |
Tương tự như geom_col() nhưng y sẽ tự động được tính theo tham số stat |
Dữ liệu cần cung cấp: Giá trị cho cột
|
geom_boxplot() |
Tạo boxplot từ x và y (nếu 1 trục là biến liên trục, trục còn lại phải thuộc biến phân loại) | Dữ liệu cần cung cấp: Giá trị cho cột x và y |
geom_point() |
Tạo biểu đồ phân tán từ x và y | Dữ liệu cần cung cấp: Giá trị cho cột x và y |
geom_line() |
Tạo biểu đồ đường từ x và y | Dữ liệu cần cung cấp: Giá trị cho cột x và y |
geom_smooth() |
Tạo biểu đồ đường hồi quy cùng khoảng tin cậy (confidence interval) từ x và y | Dữ liệu cần cung cấp: Giá trị cho cột
|
geom_histogram()
geom_bar()
hoặc geom_col()
geom_boxplot()
geom_point()
geom_line()
geom_smooth()
geom_area()
Tham số stat
của hàm geom
"identity"
lấy dữ liệu thô
"count"
đếm số quan sát (số hàng) trong từng phân nhóm
"sum"
tính tổng của các hàng trong từng phân nhóm
VD: vẽ biểu đồ số ca trực tiếp từ data linelist
thay vì case_data
bằng các quy định stat = "count"
VD: vẽ biểu đồ số ca trực tiếp từ data linelist
thay vì case_data
bằng các quy định stat = "count"
Một số đặc điểm quan trọng cho các lớp geom_
Tên đặc điểm | Công dụng |
---|---|
fill |
quy định fill color cho đồ thị |
color |
quy định border color cho đồ thị |
size |
quy định kích cỡ của đường/điểm cho đồ thị |
alpha |
quy định độ trong suốt của màu (từ 0-1, càng gần 0 màu càng trong suốt) |
linetype |
quy định loại đường (thẳng, đứt, …) cho các đồ thị đường |
shape |
quy định loại điểm cho các đồ thị có điểm |
Ta có thể quy định giá trị cho các đặc điểm của biểu đồ như một tham số của lệnh geom_
(VD: geom_bar(color = "cornflowerblue")
trong các ví dụ trên)
Tuy nhiên, nếu muốn thay đổi các đặc điểm dựa theo biến từ dữ liệu, ta cần quy định mối liên hệ giữa biến và đặc điểm trong lệnh aes()
Lệnh aes()
được sử dụng để quy định mối quan hệ giữa các biến và các đặc điểm của biểu đồ
VD: quy định màu của cột theo đợt dịch
linelist %>%
mutate(
# ----- Đổi label cho từng đợt dịch ------
outbreak = factor(outbreak,
levels = c("1st outbreak", "2nd outbreak"),
labels = c("Đợt dịch 1", "Đợt dịch 2"))
) %>%
ggplot(
aes(x = date_onset)
) +
geom_bar(
aes(fill = outbreak) # quy định mỗi đợt dịch có màu khác nhau
) +
labs(title = "Số ca Covid theo ngày",
x = "Ngày", y = "Số ca",
# optional: đổi tên ô chú thích
fill = "Đợt dịch"
)
Lệnh aes()
được sử dụng để quy định mối quan hệ giữa các biến và các đặc điểm của biểu đồ
VD: quy định màu của cột theo đợt dịch
Để tự quy định màu cho biểu đồ, ta có thể sử dụng các lệnh scale_color_*()
khi muốn quy định màu viền, hoặc scale_fill_*()
quy định màu fill
Function | Công dụng | Tham số |
---|---|---|
|
Quy định màu cho từng giá trị biến phân loại |
|
|
Quy định màu cho biến liên tục |
|
|
Tạo thang màu bằng cách chia giá trị biến liên tục thành các nhóm (bins). |
|
VD: quy định màu và label cho từng đợt dịch bằng lệnh scale_fill_manual()
linelist %>%
ggplot(aes(x = date_onset)) +
geom_bar(aes(fill = outbreak) ) +
# ------ Quy định màu cho từng đợt dịch ------
scale_fill_manual(
breaks = c("1st outbreak", "2nd outbreak"),
values = c("#91deed", "#67b6e0"),
labels = c("Đợt dịch 1", "Đợt dịch 2")
) +
labs(title = "Số ca Covid theo ngày", x = "Ngày", y = "Số ca", fill = "Đợt dịch")
VD: quy định màu và label cho từng đợt dịch bằng lệnh scale_fill_manual()
Facets, hay “chia nhỏ biểu đồ”, được sử dụng để chia một biểu đồ thành nhiều phần nhỏ, với mỗi phần (“facet”) đại diện cho một nhóm của dữ liệu.
Trong ggplot, có 2 loại facet chính
facet_wrap()
hiện thị các biểu đồ khác nhau cho từng nhóm của một biến số. (VD: thể hiện các đường cong dịch bệnh khác nhau cho từng khu vực).
facet_grid()
áp dụng khi muốn đưa một biến thứ hai vào sắp xếp các biểu đồ con. Ở đây mỗi ô thể hiện sự giao nhau của các giá trị giữa hai cột.
facet_wrap | facet_grid |
---|---|
biểu đồ số ca bệnh sốt rét chia theo tỉnh (tên tỉnh ở phía trên mỗi biểu đồ) | biểu đồ số ca bệnh sốt rét chia theo tỉnh và nhóm tuổi |
VD: dùng facet_grid
để vẽ biểu đồ theo giới tính và đợt dịch
linelist %>%
mutate(
# optional: đổi label cho biến đợt dịch và giới tính
outbreak = factor(outbreak,
levels = c("1st outbreak", "2nd outbreak"),
labels = c("Đợt dịch 1", "Đợt dịch 2")),
sex = factor(sex,
levels = c("f", "m"),
labels = c("nữ", "nam"))
) %>%
ggplot(
aes(x = date_onset)
) +
geom_bar(
color = "cornflowerblue"
) +
labs(title = "Số ca Covid theo ngày",
x = "Ngày", y = "Số ca"
) +
facet_grid(
cols = vars(outbreak),
rows = vars(sex)
)
VD: dùng facet_grid
để vẽ biểu đồ theo giới tính và đợt dịch
Để lưu biểu đồ, ta sử dụng lệnh ggsave()
với các tham số sau
path
đường dẫn đến nơi lưu bản đồ
filename
tên file được lưu
plot
biểu đồ được lưu (tự động lưu biểu đồ được vẽ gần nhất)
width
, height
kích cỡ của ảnh được lưu
dpi
độ phân giải của ảnh được lưu
VD: lưu biểu đồ
Package plotly
cung cấp lệnh ggplotly
giúp người dùng nhanh chóng biến biểu đồ của ggplot thành biểu đồ tương tác (interactive plot).
VD: dùng ggplotly để biến biểu đồ số ca thành dạng tương tác
# Vẽ biểu đồ bằng ggplot
case_plot <- linelist %>%
mutate(
# ----- Đổi label cho từng đợt dịch ------
outbreak = factor(outbreak,
levels = c("1st outbreak", "2nd outbreak"),
labels = c("Đợt dịch 1", "Đợt dịch 2"))
) %>%
group_by(outbreak, date_onset) %>%
summarize(no_cases = n()) %>%
ggplot(aes(x = date_onset, y = no_cases)) +
geom_col( aes(fill = outbreak) ) +
scale_x_date() +
labs(title = "Số ca Covid theo ngày", x = "Ngày", y = "Số ca", fill = "Đợt dịch")
# Dùng lệnh ggplotly để biến thành biểu đồ tương tác
ggplotly(case_plot)
Để thay đổi giá trị hiển trị trên tooltip, ta có thể tạo một đặc điểm qua lệnh aes() và quy định giá trị cho tham số tooltip khi sử dụng plotly
example_plot <- linelist %>%
mutate(
# ----- Đổi label cho từng đợt dịch ------
outbreak = factor(outbreak,
levels = c("1st outbreak", "2nd outbreak"),
labels = c("Đợt dịch 1", "Đợt dịch 2"))
) %>%
group_by(outbreak, date_onset) %>%
summarize(no_cases = n()) %>%
ggplot(
aes(x = date_onset, y = no_cases,
# ------- Tạo đặc điểm mới cho tooltip, đặt tên là text ------
text = paste0(
"Ngày: ", date_onset,
"\nSố ca: ",no_cases,
"\nĐợt dịch: ", outbreak
))
) +
geom_col( aes(fill = outbreak) ) +
scale_x_date() +
labs(title = "Số ca Covid theo ngày", x = "Ngày", y = "Số ca", fill = "Đợt dịch")
ggplotly(
example_plot,
# quy định lấy đặc điểm text làm tooltip
tooltip = "text"
)
Để thay đổi giá trị hiển trị trên tooltip, ta có thể tạo một đặc điểm qua lệnh aes() và quy định giá trị cho tham số tooltip khi sử dụng plotly
Trước tiên, ta cần dữ liệu để vẽ biểu đồ trong R. Trong khoá học này ta sẽ sử dụng dữ liệu được cấp bởi GADM.
Để download dữ liệu biểu đồ Việt Nam, thực hiện các bước sau:
Vào trang https://gadm.org/download_country.html
Chọn Vietnam
trong danh sách Country
Bấm Geopackage
File được tải về có tên là gadm41_VNM.gpkg
Dữ liệu bản đồ tải về sẽ có 3 cấp bậc
Cấp tỉnh/ thành phố
Cấp quận/ huyện
Cấp phường/ xã
Để đọc dữ liệu bản đồ, dùng lệnh st_read
của package sf
Để vẽ dữ liệu đọc được, dùng lệnh geom_sf
của ggplot
Khi thử nhìn dữ liệu cho bản đồ, ta có thể thấy dữ liệu đọc được cũng là một bảng dữ liệu và nhiều lệnh điều chỉnh bảng dữ liệu cũng có thể áp dụng với bảng này
Một số cột đáng lưu ý bao gồm
Các cột có format NAME_`cấp bậc hành chính`
chứa tên tiếng Việt
Các cột có format VARNAME_`cấp bậc hành chính`
chứa tên tiếng Anh
Cột geom
sẽ chứa dữ liệu để vẽ nên bản đồ
Để nối một số khu vực được vẽ trên bản đồ, ta có thể sử dụng lệnh st_join()
của gói sf
VD: gộp quận 2, quận 9 và quận Thủ Đức thành Thành phố Thủ Đức
# quy định các quận được gộp
thuduc_subset <- (hcm_map$VARNAME_2 == "District 2" | hcm_map$VARNAME_2 == "District 9" |
hcm_map$VARNAME_2 == "Thu Duc" )
# gộp các quận 2, 9, Thủ Đức và lưu giá trị vào cột geom của Thủ Đức trong bảng
hcm_map[hcm_map$VARNAME_2 == "Thu Duc", "geom"] <- st_union( subset(hcm_map, thuduc_subset)$geom )
# xoá dữ liệu cho Q2 và Q9 sau khi gộp
hcm_map <- hcm_map %>% filter(!VARNAME_2 == "District 2" & !VARNAME_2 == "District 9")
# vẽ biểu đồ sau khi gộp
hcm_map %>% ggplot() + geom_sf()
Để nối một số khu vực được vẽ trên bản đồ, ta có thể sử dụng lệnh st_join()
của gói sf
VD: gộp quận 2, quận 9 và quận Thủ Đức thành Thành phố Thủ Đức
Để thêm giá trị từ một bảng khác vào bảng dữ liệu biểu đồ, ta có thể sử dụng left_join()
tương tự các bài học trước
VD: vẽ bản đồ cùng số ca
# ------- Tính tổng số ca -------
case_by_district <- linelist %>%
group_by(district) %>%
summarize(
no_cases = n()
)
# -------- Nối bảng số ca và bảng dữ liệu bản đồ -----
hcm_map <- hcm_map %>%
mutate(
# Trước khi join, phải điều chỉnh cột dùng để join để các giá trị tương ứng giống nhau
VARNAME_2 = str_replace(VARNAME_2, "District", "Quan")
) %>%
left_join(
case_by_district,
by = join_by(VARNAME_2 == district)
)
# --------- Vẽ biểu đồ cùng dữ liệu số ca bằng ggplot ------
hcm_map %>%
ggplot() +
geom_sf(
# quy định màu theo số ca
aes(fill = no_cases)
) +
labs(fill = "Số ca")
Để thêm giá trị từ một bảng khác vào bảng dữ liệu biểu đồ, ta có thể sử dụng left_join()
tương tự các bài học trước
VD: vẽ bản đồ cùng số ca
Gói leaflet
được dùng để vẽ bản đồ tương tác.
Chúng ta sử dụng leaflet
thay vì ggplot + plotly vì bản đồ vẽ bởi leaflet thường đẹp hơn
Quá trình vẽ biểu đồ bằng leaflet cũng tương tự như ggplot, bao gồm các bước sau:
Gọi leaflet()
và cung cấp dữ liệu cần vẽ
Thêm lớp biểu đồ qua lệnh addPolygon()
Thêm ô chú thích bằng lệnh addLegend()
nếu cần thiết
Tên lệnh | Các tham số thông dụng |
---|---|
addPolygon() |
|
addLegend() |
|
# ----- quy định bảng màu ----
pal <- colorBin(
# bảng màu cho giá trị từ nhỏ đến lớn
palette = c("#cadefa","#73aeff", "#134c9c"),
domain = hcm_map$no_cases, # cung cấp khoảng giá trị
na.color = "grey" # quy định màu cho giá trị trống
)
# ----- vẽ biểu đồ ------
leaflet(hcm_map) %>%
# vẽ biểu đồ
addPolygons(
color="black", # quy định màu viền
# quy định fillColor dựa theo số ca, và dùng màu từ bảng màu pal
fillColor = ~pal(no_cases),
weight = 1, # độ dày của viền
# chỉnh tooltip
label = ~paste0(NAME_2, ". \nSố ca: ", no_cases),
fillOpacity=0.8
) %>%
# thêm ô chú thích
addLegend(pal = pal, values = ~no_cases, title = "Số ca", position = "bottomright", opacity=1)