Vẽ biểu đồ lollipop chart

Tác giả: Hoàng Đức Anh | 2019-01-10

Trong trực quan hóa dữ liệu, lollipop chart tuy không phải là một trong những biểu đồ phổ biến nhưng lại rất hiệu quả khi muốn thể hiện sự dịch thay đổi của một chỉ số giữa hai điểm thời gian. Trong bài viết này, RAnalytics sẽ hướng dẫn các bạn cách xây dựng biểu đồ lollipop chart với ggplot2.

# Load library
library(tidyverse)
library(gapminder)

Để xây dựng biểu đồ, ta sử dụng dữ liệu gapminder từ tập dữ liệu gapminder. Mục tiêu của chúng ta là xây dựng biểu đồ thể hiện được sự thay đổi GDP/đầu người của các nước châu Âu trong năm 1952 so với năm 1977.

data <- gapminder %>% 
  filter(continent == "Europe") %>% 
  filter(year %in% c(1952, 1977)) %>% 
  select(country, year, gdpPercap) %>% 
  spread(year, gdpPercap) %>% 
  rename(y1952 = `1952`,
         y1977 = `1977`)
data %>% head(10)
## # A tibble: 10 x 3
##    country                y1952  y1977
##    <fct>                  <dbl>  <dbl>
##  1 Albania                1601.  3533.
##  2 Austria                6137. 19749.
##  3 Belgium                8343. 19118.
##  4 Bosnia and Herzegovina  974.  3528.
##  5 Bulgaria               2444.  7612.
##  6 Croatia                3119. 11305.
##  7 Czech Republic         6876. 14800.
##  8 Denmark                9692. 20423.
##  9 Finland                6425. 15605.
## 10 France                 7030. 18293.

Biểu đồ lollipop có thể xây dựng dựa trên geom_pointgeom_segment như sau.

Biểu đồ đầu tiên

data %>% 
  ggplot(aes(x  = country)) +
  # Tạo đường nối giữa hai điểm
  geom_segment(aes(y = y1952, yend = y1977,
               x = country, xend = country), size = 1,
               col = "grey50") +
  # Tạo điểm đầu
  geom_point(aes(country, y1952, color = "1952"), size = 3.5) +
  # Tạo điểm cuối
  geom_point(aes(country, y1977, 
             color = "1977"), size = 3.5) +
  coord_flip()

Tuy nhiên, với biểu đồ trên, ta thấy xuất hiện hai lỗi cơ bản sau:

  • Thứ nhất, thứ tự các các quan sát đang để dạng mặc định. Do đó, kết quả trực quan hóa chỉ mang tính thông tin mà chưa có yêu tố kể chuyện (story telling). Ta có thể giải quyết bằng cách sắp xếp lại factor theo thứ tự từ thấp đến cao.
  • Thứ hai, biểu đồ thể hiện theo chiều ngang. Do đó, các thông tin không cần thiết có thể được loại bỏ để biểu đồ gọn gàng và mạch lạc hơn.

Ta có thể chỉnh lại biểu đồ như sau.

# Tinh chỉnh theme cho biểu đồ
my_theme <- function(...) {
  theme_bw() + 
    theme(plot.background = element_rect(fill = "white")) + 
    theme(panel.grid.minor = element_blank()) + 
    theme(panel.grid.major.y = element_blank()) + 
    theme(panel.grid.major.x = element_line()) + 
    theme(axis.ticks = element_blank()) + 
    theme(panel.border = element_blank()) + 
    theme(text = element_text(size = 13, color = "black")) + 
    theme(plot.subtitle = element_text(color = "gray20", size = 10, face = "italic")) + 
    theme(legend.title = element_text(size = 10, color = "gray20")) + 
    theme(legend.position = "top")
} 

# Tạo biểu đồ mới
p1 <- data %>% 
  mutate(country = fct_reorder(country, y1977)) %>% 
  ggplot(aes(x  = country)) +
  geom_segment(aes(y = y1952, yend = y1977,
               x = country, xend = country), size = 1,
               col = "grey50",
               alpha = 0.7) +
  geom_point(aes(country, y1952, color = "1952"), 
             size = 3.5, alpha = 0.7) +
  geom_point(aes(country, y1977, color = "1977"), 
             size = 3.5, alpha = 0.7) +
  coord_flip() +
  my_theme() +
  scale_y_continuous(breaks = seq(0, 30000, by = 5000), 
                     limits = c(800, 27000)) +
  scale_color_manual(
    name = "Year",
    labels = c("1952", "1977"),
    values = c("darkblue", "darkred")
  ) +
  labs(x = NULL, y = NULL,
       title = "An example of lollipop chart",
       subtitle = "Changes of GDP per capita in Europe",
       caption = "Created by RAnalytics.vn")
p1

Bonus: Để nhấn mạnh hơn sự thay đổi của GDP per capita, ta có thể vẽ thêm các đường nối các điểm trong biểu đồ như sau.

p2 <- p1 + geom_line(aes(as.numeric(country), y1977), 
               col = "darkred")
p2

Như vậy, chúng ta đã vừa được học vẽ biểu đồ lollipop với ggplot2. Chúc các bạn học tập và làm việc hiệu quả với Ranalytics.vn!

comments powered by Disqus