Cách vẽ đồ thị hai trục tung

Câu 1 (Base R)

Bạn có dữ liệu như sau.

df <- airquality[1:30, ]
df
   Ozone Solar.R Wind Temp Month Day
1     41     190  7.4   67     5   1
2     36     118  8.0   72     5   2
3     12     149 12.6   74     5   3
4     18     313 11.5   62     5   4
5     NA      NA 14.3   56     5   5
6     28      NA 14.9   66     5   6
7     23     299  8.6   65     5   7
8     19      99 13.8   59     5   8
9      8      19 20.1   61     5   9
10    NA     194  8.6   69     5  10
11     7      NA  6.9   74     5  11
12    16     256  9.7   69     5  12
13    11     290  9.2   66     5  13
14    14     274 10.9   68     5  14
15    18      65 13.2   58     5  15
16    14     334 11.5   64     5  16
17    34     307 12.0   66     5  17
18     6      78 18.4   57     5  18
19    30     322 11.5   68     5  19
20    11      44  9.7   62     5  20
21     1       8  9.7   59     5  21
22    11     320 16.6   73     5  22
23     4      25  9.7   61     5  23
24    32      92 12.0   61     5  24
25    NA      66 16.6   57     5  25
26    NA     266 14.9   58     5  26
27    NA      NA  8.0   57     5  27
28    23      13 12.0   67     5  28
29    45     252 14.9   81     5  29
30   115     223  5.7   79     5  30

Bạn vẽ đồ thị hai trục tung (Y1: Temp, Y2: Wind, X: Day) bằng các lệnh Base R Graphics (lệnh plot() như thông thường).

par(mar = c(4,6,4,6))

plot(Temp ~ Day,
     type = "l",
     col = "red",
     ylim = c(0, 100),
     las = 1,
     data = df)

par(new = T)

plot(Wind ~ Day,
     type = "l",
      axes = FALSE,
     col = "blue",
     data = df,
     ylim = c(0,50),
     xlab = "",
     ylab = "")

axis(side = 4,
     las = 2)

mtext(text = "Wind",
      side = 4,
      line = 2.5)

legend(x = "top",
       y = NULL,
       legend = c("Temp", "Wind"),
       col = c("red", "blue"),
       horiz = T,
       lty = 1)

Câu 2 (ggplot2)

Từ bộ dữ liệu df ở trong câu 1, bạn hãy vẽ bằng package ggplot2 để được hình sau.

ggplot2 không thuận tiện để vẽ hai trục tung (theo tìm hiểu thì tác giả package không recomment hướng này mà muốn tách ra thành từng đồ thị đơn để không bị nhầm việc đọc kết quả), tuy vậy ta vẫn có tham số để hỗ trợ vẽ hai trục tung (dual-Y axis) bằng lệnh sec_axis(), bản chất là vẽ một trục Y bên phải, ta sẽ cần tách riêng hai linechart và tính scale_factor cho phù hợp. Tóm lại, muốn vẽ hai trục tung chuẩn nhất là ta vẽ bằng Base R như câu 1.

Ngoài ra vị trí legend trong ggplot2 ở “top”, thì nằm ngoài đồ thị, còn Base R thì nằm trong đồ thị, ta có thể tinh chỉnh thủ công cũng được.

library(ggplot2)
# package ggplot2 khi vẽ linechart sẽ tự động xếp đúng thứ tự từ nhỏ đến lớn ở trục X, không cần phải order như cách vẽ ở Base R, việc này có thể tiện lợi, nhưng cũng làm ta "chủ quan" không rõ cách vẽ của linechart.

scale_factor <- 2

ggplot() +
  
  geom_line(data = df,
       
       mapping = aes(x = Day,
                     y = Temp,
                     color = "Temp"),
       
       ) +
  
  geom_line(data = df,
            mapping = aes(x = Day,
                          y = Wind * 2,
                           color = "Wind"),
           ) +
  
  scale_y_continuous(name = "Temp",
                     limits = c(0, 100),
                     sec.axis = sec_axis(
                       ~ . / 2,
                       name = "Wind"
                       )
                     ) +
  theme_bw(base_size = 16) +
  
  scale_color_manual(values = c("Temp" = "red",
                               "Wind" = "blue"),
                     name = "") +
  
  theme(legend.position = "top")

Ngoài ra, ta có thể vẽ hai trục tung sử dụng package lattice.

https://latticeextra.r-forge.r-project.org/man/doubleYScale.html