Motivations

Trong một status trên FB cá nhân, anh Phạm Thế AnhVEPR có trích lại barplot từ một báo cáo của GSO dưới đây:

Chúng ta có thể vẽ lại barplot này tốt hơn bằng R/ggplot2.

Version 1

Dễ thấy là vấn đề overlap phần text. Chúng ta có thể vẽ lại plot trên để xử lí vấn đề này như sau:

Dưới đây là R codes:

# Data downloaded from https://www.mediafire.com/file/bxee2utpqbi3u0n/data_anh_TheAnh.xlsx/file

rm(list = ls())

library(readxl)
library(tidyverse)
library(tidytext)
library(stringi)

# Load data: 

read_excel("data_anh_TheAnh.xlsx", sheet = 1, skip = 0) -> data_TheAnh

# Prepare data for ploting: 

names(data_TheAnh) <- c("nganh", "Theo giá hiện thời", "Theo giá cố định")

data_TheAnh %>% 
  mutate(nganh_latin = stri_trans_general(nganh, "Latin-ASCII")) %>% 
  mutate(nganh_latin = str_to_lower(nganh_latin)) %>% 
  filter(str_detect(nganh_latin, "thuy san|tro giup|lam nghiep|xay dung|giao duc|che bien|phan phoi dien|GDP|luu tru|khai khoang|tai chinh|sua chua|bat dong san|nong nghiep|van tai")) %>% 
  slice(-8) -> data_for_bar

data_for_bar %>% 
  arrange(`Theo giá cố định`) %>% 
  mutate(nganh = factor(nganh, levels = nganh)) -> df_bar_fct

df_bar_fct %>% 
  select(-nganh_latin) %>% 
  gather(type, value, -nganh) -> df_long

df_long %>% 
  mutate(type = factor(type, levels = c("Theo giá hiện thời", "Theo giá cố định"))) %>% 
  ggplot(aes(nganh, value, fill = type)) + 
  geom_col(position = "dodge", width = 0.75) + 
  coord_flip() -> bar_draft

library(showtext) # Package for using extra fonts. 

my_colors <- c("#2E74C0", "#CB454A") # Set colors for bar. 

my_font <- "Roboto Condensed"  # --> Set Ubunto Condensed font for our plot. 

font_add_google(name = my_font, family = my_font)

# Automatically use showtext to render text: 

showtext_auto()

library(scales)

# Version 1 of barplot: 

bar_draft + 
  theme_minimal() + 
  scale_y_continuous(limits = c(-0.1, 0.5), breaks = seq(-0.1, 0.5, 0.05), labels = percent, expand = c(0, 0)) + 
  scale_fill_manual(values = my_colors, name = "", labels = c("Theo giá hiện thời", "Theo giá cố định")) + 
  theme(legend.text = element_text(size = 10.5, color = "grey30", family = my_font)) +  
  theme(legend.position = "top") + 
  theme(legend.key.size = unit(0.3, "cm")) + 
  guides(fill = guide_legend(reverse = TRUE)) + 
  theme(plot.margin = unit(rep(0.7, 4), "cm")) + 
  theme(panel.grid.minor = element_blank()) + 
  theme(axis.title = element_blank()) + 
  theme(axis.text.y = element_text(size = 10, color = "grey30", family = my_font)) + 
  theme(axis.text.x = element_text(size = 12, color = "grey30", family = my_font)) + 
  theme(strip.text = element_text(color = "grey20", size = 13, face = "bold", family = my_font)) + 
  labs(title = "Hình 1: Mức tăng trưởng của một số nghành", 
       caption = "Data Source: pham.theanh@neu.edu.vn") + 
  theme(plot.title = element_text(size = 20, family = my_font)) + 
  theme(plot.caption = element_text(size = 9, family = my_font, color = "grey30", vjust = -1)) + 
  theme(plot.background = element_rect(fill = "seashell", color = NA))

Version 2

Các cột màu đỏ ở version 1 được sắp xếp theo giảm dần của tăng trưởng tính theo thước đo “giá cố định’. Chúng ta không thể đồng thời làm điều này với cột màu xanh được tính theo thước đo”giá hiện thời” trên cùng một hình được. Giải pháp khác là chúng ta trình bày thành một panel gồm hai barplots đồng thời highlight các ngành mà tăng trưởng âm để phân biệt với nhóm tăng trưởng dương (version 2):

Dưới đây là R codes cho version 2 theo style của tạp chí The Economist:

# Version 2 of barplot: 

library(tidytext)
library(ggthemes)

df_long %>% 
  mutate(nganh = reorder_within(nganh, value, type)) %>% 
  mutate(type2 = case_when(value > 0 ~ "Tăng", TRUE ~ "Giảm")) -> df_ordered

my_colors2 <- c("#EF5B3E", "#014d64")

brgColor <- "#CDDEE6"

df_ordered %>% 
  ggplot(aes(nganh, value, fill = type2)) + 
  geom_col(width = 0.7) + 
  scale_fill_manual(values = my_colors2, name = "Nhóm Ngành:") + 
  facet_wrap(~ type, scales = "free_y") + 
  coord_flip() + 
  scale_x_reordered() + 
  theme_minimal() + 
  theme(panel.grid.minor.x = element_blank()) + 
  theme(panel.grid.major.y = element_blank()) + 
  scale_y_continuous(limits = c(-0.1, 0.5), breaks = seq(-0.1, 0.5, 0.05), labels = percent, expand = c(0, 0)) + 
  theme(plot.margin = unit(rep(0.7, 4), "cm")) + 
  theme(plot.background = element_rect(fill = brgColor, color = NA)) + 
  theme(panel.background = element_rect(fill = brgColor, color = NA)) + 
  theme(axis.title = element_blank()) + 
  theme(axis.text.y = element_text(size = 10, color = "grey30", family = my_font)) + 
  theme(axis.text.x = element_text(size = 10.5, color = "grey30", family = my_font)) + 
  theme(strip.text = element_text(color = "grey20", size = 13, face = "bold", family = my_font)) + 
  labs(title = "Hình 1: Phần trăm tăng trưởng của một số nghành", 
       caption = "Data Source: pham.theanh@neu.edu.vn") + 
  theme(plot.title = element_text(size = 20, family = my_font)) + 
  theme(plot.caption = element_text(size = 9, family = my_font, color = "grey30", vjust = -1)) + 
  theme(legend.position = "top") + 
  theme(legend.key.size = unit(0.3, "cm")) + 
  guides(fill = guide_legend(reverse = TRUE)) + 
  theme(legend.text = element_text(size = 10.5, color = "grey20", family = my_font)) + 
  theme(strip.text = element_text(color = "grey30", size = 11, family = my_font)) + 
  theme(legend.title = element_text(size = 10.5, family = my_font, color = "grey20"))

library(grid)
grid.rect(x = 0.018, y = 0.93, hjust = 1, vjust = 0, gp = gpar(fill = "#e5001c", lwd = 0, col = "#e5001c"))