Để vẽ đồ thị hai trục tung thì cách tiếp cận trong base-R graphics là vẽ lần lượt từng đồ thị gán lên nhau (painter mode).

Dataset dùng vẽ đồ thị

airquality
##     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
## 31     37     279  7.4   76     5  31
## 32     NA     286  8.6   78     6   1
## 33     NA     287  9.7   74     6   2
## 34     NA     242 16.1   67     6   3
## 35     NA     186  9.2   84     6   4
## 36     NA     220  8.6   85     6   5
## 37     NA     264 14.3   79     6   6
## 38     29     127  9.7   82     6   7
## 39     NA     273  6.9   87     6   8
## 40     71     291 13.8   90     6   9
## 41     39     323 11.5   87     6  10
## 42     NA     259 10.9   93     6  11
## 43     NA     250  9.2   92     6  12
## 44     23     148  8.0   82     6  13
## 45     NA     332 13.8   80     6  14
## 46     NA     322 11.5   79     6  15
## 47     21     191 14.9   77     6  16
## 48     37     284 20.7   72     6  17
## 49     20      37  9.2   65     6  18
## 50     12     120 11.5   73     6  19
## 51     13     137 10.3   76     6  20
## 52     NA     150  6.3   77     6  21
## 53     NA      59  1.7   76     6  22
## 54     NA      91  4.6   76     6  23
## 55     NA     250  6.3   76     6  24
## 56     NA     135  8.0   75     6  25
## 57     NA     127  8.0   78     6  26
## 58     NA      47 10.3   73     6  27
## 59     NA      98 11.5   80     6  28
## 60     NA      31 14.9   77     6  29
## 61     NA     138  8.0   83     6  30
## 62    135     269  4.1   84     7   1
## 63     49     248  9.2   85     7   2
## 64     32     236  9.2   81     7   3
## 65     NA     101 10.9   84     7   4
## 66     64     175  4.6   83     7   5
## 67     40     314 10.9   83     7   6
## 68     77     276  5.1   88     7   7
## 69     97     267  6.3   92     7   8
## 70     97     272  5.7   92     7   9
## 71     85     175  7.4   89     7  10
## 72     NA     139  8.6   82     7  11
## 73     10     264 14.3   73     7  12
## 74     27     175 14.9   81     7  13
## 75     NA     291 14.9   91     7  14
## 76      7      48 14.3   80     7  15
## 77     48     260  6.9   81     7  16
## 78     35     274 10.3   82     7  17
## 79     61     285  6.3   84     7  18
## 80     79     187  5.1   87     7  19
## 81     63     220 11.5   85     7  20
## 82     16       7  6.9   74     7  21
## 83     NA     258  9.7   81     7  22
## 84     NA     295 11.5   82     7  23
## 85     80     294  8.6   86     7  24
## 86    108     223  8.0   85     7  25
## 87     20      81  8.6   82     7  26
## 88     52      82 12.0   86     7  27
## 89     82     213  7.4   88     7  28
## 90     50     275  7.4   86     7  29
## 91     64     253  7.4   83     7  30
## 92     59     254  9.2   81     7  31
## 93     39      83  6.9   81     8   1
## 94      9      24 13.8   81     8   2
## 95     16      77  7.4   82     8   3
## 96     78      NA  6.9   86     8   4
## 97     35      NA  7.4   85     8   5
## 98     66      NA  4.6   87     8   6
## 99    122     255  4.0   89     8   7
## 100    89     229 10.3   90     8   8
## 101   110     207  8.0   90     8   9
## 102    NA     222  8.6   92     8  10
## 103    NA     137 11.5   86     8  11
## 104    44     192 11.5   86     8  12
## 105    28     273 11.5   82     8  13
## 106    65     157  9.7   80     8  14
## 107    NA      64 11.5   79     8  15
## 108    22      71 10.3   77     8  16
## 109    59      51  6.3   79     8  17
## 110    23     115  7.4   76     8  18
## 111    31     244 10.9   78     8  19
## 112    44     190 10.3   78     8  20
## 113    21     259 15.5   77     8  21
## 114     9      36 14.3   72     8  22
## 115    NA     255 12.6   75     8  23
## 116    45     212  9.7   79     8  24
## 117   168     238  3.4   81     8  25
## 118    73     215  8.0   86     8  26
## 119    NA     153  5.7   88     8  27
## 120    76     203  9.7   97     8  28
## 121   118     225  2.3   94     8  29
## 122    84     237  6.3   96     8  30
## 123    85     188  6.3   94     8  31
## 124    96     167  6.9   91     9   1
## 125    78     197  5.1   92     9   2
## 126    73     183  2.8   93     9   3
## 127    91     189  4.6   93     9   4
## 128    47      95  7.4   87     9   5
## 129    32      92 15.5   84     9   6
## 130    20     252 10.9   80     9   7
## 131    23     220 10.3   78     9   8
## 132    21     230 10.9   75     9   9
## 133    24     259  9.7   73     9  10
## 134    44     236 14.9   81     9  11
## 135    21     259 15.5   76     9  12
## 136    28     238  6.3   77     9  13
## 137     9      24 10.9   71     9  14
## 138    13     112 11.5   71     9  15
## 139    46     237  6.9   78     9  16
## 140    18     224 13.8   67     9  17
## 141    13      27 10.3   76     9  18
## 142    24     238 10.3   68     9  19
## 143    16     201  8.0   82     9  20
## 144    13     238 12.6   64     9  21
## 145    23      14  9.2   71     9  22
## 146    36     139 10.3   81     9  23
## 147     7      49 10.3   69     9  24
## 148    14      20 16.6   63     9  25
## 149    30     193  6.9   70     9  26
## 150    NA     145 13.2   77     9  27
## 151    14     191 14.3   75     9  28
## 152    18     131  8.0   76     9  29
## 153    20     223 11.5   68     9  30
str(airquality)
## 'data.frame':    153 obs. of  6 variables:
##  $ Ozone  : int  41 36 12 18 NA 28 23 19 8 NA ...
##  $ Solar.R: int  190 118 149 313 NA NA 299 99 19 194 ...
##  $ Wind   : num  7.4 8 12.6 11.5 14.3 14.9 8.6 13.8 20.1 8.6 ...
##  $ Temp   : int  67 72 74 62 56 66 65 59 61 69 ...
##  $ Month  : int  5 5 5 5 5 5 5 5 5 5 ...
##  $ Day    : int  1 2 3 4 5 6 7 8 9 10 ...

Đồ thị đường với hai trục y khác nhau

Vẽ hai đường OzoneTemp trong tháng 5 ở dataset airquality.

month_5 <- subset(airquality, Month == 5)

par(mar = c(5, 4, 4, 4) + 0.5)

plot(Ozone ~ Day, na.omit(month_5[, c("Ozone", "Day")]),
  type = "l", lwd = 2, las = 1, col = "blue",
  xaxs = "i", yaxs = "i",
  xaxt = "n", yaxt = "n",
  ylim = c(0, round(max(airquality$Ozone, na.rm = TRUE), digits = -2)),
  xlim = c(0, max(month_5$Day, na.rm = TRUE)),
  xlab = "Ngày", ylab = ""
)

title(
  main = "Chỉ số quan trắc môi trường tháng 05/2022",
  col.main = "darkgreen", line = 2
)
mysubtitle <- "Đồ thị được code bởi Duc Nguyen | www.tuhocr.com"
mtext(line = 0.4, mysubtitle, col = "darkgreen")

y1 <- par("usr")

# Changing x axis

lastnum_seq_x <- function(start, end, by) {
  by <- seq(from = start, to = end, by = by)
  e <- c(by, end)
  if (e[length(e)] - e[length(e) - 1] < 3) {
    e_1 <- c(e[1:c(length(e) - 2)], e[length(e)])
    e_2 <- append(e_1, 1, after = 1) # insert element
    return(e_2)
  }
  e_3 <- c(by, end)
  e_4 <- append(e_3, 1, after = 1)
  return(e_4)
}

xtick <- lastnum_seq_x(0, max(month_5$Day, na.rm = TRUE), 5)

axis(side = 1, at = xtick, labels = FALSE)

text(
  x = xtick, y1[3] - 2,
  labels = xtick, srt = 0, pos = 1, xpd = TRUE
)

# Changing y axis

lastnum_seq_y <- function(start, end, by) {
  by <- seq(from = start, to = end, by = by)
  e <- c(by, end)
  if (e[length(e)] - e[length(e) - 1] < 9) {
    e_1 <- c(e[1:c(length(e) - 2)], e[length(e)])
    e_2 <- append(e_1, 1, after = 1) # insert element
    return(e_1)
  }
  e_3 <- c(by, end)
  e_4 <- append(e_3, 1, after = 1)
  return(e_3)
}

ytick <- lastnum_seq_y(0, round(max(airquality$Ozone, na.rm = TRUE), digits = -2), 20)

axis(side = 2, at = ytick, labels = FALSE)

text(y1[1] - 0.2, ytick,
  labels = ytick, srt = 0, pos = 2, xpd = TRUE, col = "blue"
)

text(y1[1] - 3, mean(y1[3:4]),
  labels = "Ozone (ppb)", srt = 90,
  # pos = 2,
  xpd = NA, col = "blue"
)

# text(mean(y1[1:2]), y1[3] - 13,
#   labels = "Ngày", srt = 0,
#   # pos = 1,
#   xpd = NA, col = "black"
# )

## Vẽ line chart thứ 2

par(new = TRUE)

plot(Temp ~ Day, na.omit(month_5[, c("Temp", "Day")]),
  type = "b", axes = FALSE, ylab = "", lty = 1, lwd = 2, col = "red",
  xaxs = "i", yaxs = "i",
  ylim = c(0, round(max(airquality$Temp, na.rm = TRUE), digits = -2)),
  xlim = c(0, max(month_5$Day, na.rm = TRUE)),
  xlab = ""
)

axis(side = 1, at = xtick, labels = FALSE) # trục x của plot 2 được ẩn

# Changing y_2 axis

ytick_2 <- lastnum_seq_y(0, round(max(airquality$Temp, na.rm = TRUE), digits = -2) , 20)

y2 <- par("usr")

axis(side = 4, at = ytick_2, labels = FALSE)

text(y2[2] + 0.2, ytick_2,
  labels = ytick_2, srt = 0, pos = 4, xpd = TRUE, col = "red"
)

# mtext(side = 4, line = 2, "Temp")

text(y2[2] + 3, mean(y2[3:4]),
  labels = "Nhiệt độ (°F)",
  xpd = NA, srt = -90, col = "red"
)

legend("topleft",
  legend = c("Nhiệt độ (°F)", "Ozone (ppb)"),
  col = c("red", "blue"),
  lty = c(2, 1), cex = 1,
  pch = c(21, NA),
  lwd = 2,
  x.intersp = 1,
  y.intersp = 2,
  inset = 0.02,
  box.lty = 0,
  horiz = FALSE
)

Function hóa để vẽ các đồ thị còn lại

## Function vẽ đồ thị hai trục tung

ve_hai_truc_tung <- function(month_input, 
                             main_title = "Chỉ số quan trắc môi trường",
                             sub_title = "Đồ thị được code bởi Duc Nguyen | www.tuhocr.com",
                             label_y1 = 3,
                             label_y2 = 3,
                             legend_show = "1",
                             add_one = "1"){

month_5 <- subset(airquality, Month == month_input)

par(mar = c(5, 4, 4, 4) + 0.5)

plot(Ozone ~ Day, na.omit(month_5[, c("Ozone", "Day")]),
  type = "l", lwd = 2, las = 1, col = "blue",
  xaxs = "i", yaxs = "i",
  xaxt = "n", yaxt = "n",
  ylim = c(0, round(max(airquality$Ozone, na.rm = TRUE), digits = -2)),
  xlim = c(0, max(month_5$Day, na.rm = TRUE)),
  xlab = "Ngày", ylab = ""
)

title(main = paste(main_title, "tháng", paste0("0", month_input, "/2022")), 
      col.main = "darkgreen", line = 2)
mysubtitle <- sub_title
mtext(line = 0.4, mysubtitle, col = "darkgreen")

y1 <- par("usr")

# Changing x axis

lastnum_seq_x <- function(start, end, by) {
  by <- seq(from = start, to = end, by = by)
  e <- c(by, end)
  if (e[length(e)] - e[length(e) - 1] < 3) {
    e_1 <- c(e[1:c(length(e) - 2)], e[length(e)])
    if(add_one == "1"){
      e_2 <- append(e_1, 1, after = 1) # insert element 
      return(e_2)
    }
    return(e_1)
  }
  e_3 <- c(by, end)
  e_4 <- append(e_3, 1, after = 1)
  return(e_4)
}

xtick <- lastnum_seq_x(0, max(month_5$Day, na.rm = TRUE), 5)

axis(side = 1, at = xtick, labels = FALSE)

text(
  x = xtick, y1[3] - 2,
  labels = xtick, srt = 0, pos = 1, xpd = TRUE
)

# Changing y axis

lastnum_seq_y <- function(start, end, by) {
  by <- seq(from = start, to = end, by = by)
  e <- c(by, end)
  if (e[length(e)] - e[length(e) - 1] < 9) {
    e_1 <- c(e[1:c(length(e) - 2)], e[length(e)])
    e_2 <- append(e_1, 1, after = 1) # insert element
    return(e_1)
  }
  e_3 <- c(by, end)
  e_4 <- append(e_3, 1, after = 1)
  return(e_3)
}

ytick <- lastnum_seq_y(0, round(max(airquality$Ozone, na.rm = TRUE), digits = -2), 20)

axis(side = 2, at = ytick, labels = FALSE)

text(y1[1] - 0.2, ytick,
  labels = ytick, srt = 0, pos = 2, xpd = TRUE, col = "blue"
)

text(y1[1] - label_y1, mean(y1[3:4]),
  labels = "Ozone (ppb)", srt = 90,
  # pos = 2,
  xpd = NA, col = "blue"
)

# text(mean(y1[1:2]), y1[3] - 13,
#   labels = "Ngày", srt = 0, xpd = NA, col = "black")

## Vẽ line chart thứ 2

par(new = TRUE)

plot(Temp ~ Day, na.omit(month_5[, c("Temp", "Day")]),
  type = "b", axes = FALSE, ylab = "", lty = 1, lwd = 2, col = "red",
  xaxs = "i", yaxs = "i",
  ylim = c(0, round(max(airquality$Temp, na.rm = TRUE), digits = -2)),
  xlim = c(0, max(month_5$Day, na.rm = TRUE)),
  xlab = ""
)

axis(side = 1, at = xtick, labels = FALSE) # trục x của plot 2 được ẩn

# Changing y_2 axis

ytick_2 <- lastnum_seq_y(0, round(max(airquality$Temp, na.rm = TRUE), digits = -2), 20)

y2 <- par("usr")

axis(side = 4, at = ytick_2, labels = FALSE)

text(y2[2] + 0.2, ytick_2,
  labels = ytick_2, srt = 0, pos = 4, xpd = TRUE, col = "red"
)

# mtext(side = 4, line = 2, "Temp")

text(y2[2] + label_y2, mean(y2[3:4]),
  labels = "Nhiệt độ (°F)",
  xpd = NA, srt = -90, col = "red"
)

if(legend_show == 1){
 legend("topleft",
  legend = c("Nhiệt độ (°F)", "Ozone (ppb)"),
  col = c("red", "blue"),
  lty = c(2, 1), cex = 1,
  pch = c(21, NA),
  lwd = 2,
  x.intersp = 1,
  y.intersp = 2,
  inset = 0.4,
  box.lty = 0,
  horiz = FALSE
)   
}

}

Đồ thị tháng 6

ve_hai_truc_tung(month_input = 6)

Đồ thị tháng 7

ve_hai_truc_tung(month_input = 7)

Đồ thị tháng 8

ve_hai_truc_tung(month_input = 8)

Đồ thị tháng 9

ve_hai_truc_tung(month_input = 9)

Gộp chung các đồ thị

par(mfrow = c(2, 3))
ve_hai_truc_tung(month_input = 5, "", "", label_y1 = 8, label_y2 = 8, legend_show = 0, add_one = 0)
ve_hai_truc_tung(month_input = 6, "", "", label_y1 = 8, label_y2 = 8, legend_show = 0, add_one = 0)
ve_hai_truc_tung(month_input = 7, "", "", label_y1 = 8, label_y2 = 8, legend_show = 0, add_one = 0)
ve_hai_truc_tung(month_input = 8, "", "", label_y1 = 8, label_y2 = 8, legend_show = 0, add_one = 0)
ve_hai_truc_tung(month_input = 9, "", "", label_y1 = 8, label_y2 = 8, legend_show = 0, add_one = 0)
plot.new()
title(
  main = "Kết quả quan trắc \nmôi trường năm 2022",
  col.main = "darkgreen", line = -3, cex.main = 1.8
)
# mtext("Kết quả quan trắc môi trường năm 2022 | tuhocr.com",
#       side = 3,
#       line = -30,
#       outer = TRUE)
# plot(1:10,ty="n")
library(png) ## dùng đề chèn file ảnh
library(grid) ## canh chỉnh vị trí ảnh
image_tuhocr <- readPNG("img/logor.png")
# rasterImage(image_tuhocr,5,5,7,7)
grid.raster(image_tuhocr, x = 0.88, y = 0.15, width = 0.15)


### BẢNG CHÚ THÍCH
legend("top",
  legend = c("Nhiệt độ (°F)", "Ozone (ppb)"),
  col = c("red", "blue"),
  lty = c(2, 1), cex = 1.3,
  pch = c(21, NA),
  lwd = 2,
  x.intersp = 1.2,
  y.intersp = 1.2,
  inset = 0.24,
  box.lty = 1,
  horiz = FALSE,
  bg = "yellow",
  title = as.expression(bquote(bold("www.tuhocr.com"))))

Đồ thị cột với hai trục y khác nhau

Ta sẽ tính trung bình của 2 cột OzoneTemp theo từng tháng, sau đó vẽ đồ thị cột side-by-side để thuận tiện đánh giá kết quả chỉ tiêu môi trường.

## Vẽ barchart hai trục y cần tinh chỉnh một chút dataset. Các bạn theo dõi dòng code nhé.
x <- tapply(airquality$Temp, airquality$Month, mean, na.rm = TRUE)
y <- tapply(airquality$Ozone, airquality$Month, mean, na.rm = TRUE)
sum_data <- data.frame("Ozone" = y, "Temp" = x)
sum_data <- as.matrix(sum_data)
sum_data ## Chuyển thành matrix để vẽ barchart
##      Ozone     Temp
## 5 23.61538 65.54839
## 6 29.44444 79.10000
## 7 59.11538 83.90323
## 8 59.96154 83.96774
## 9 31.44828 76.90000
## tính SD để vẽ error bar
x_sd <- tapply(airquality$Temp, airquality$Month, sd, na.rm = TRUE)
y_sd <- tapply(airquality$Ozone, airquality$Month, sd, na.rm = TRUE)
sum_sd <- data.frame("Ozone" = y_sd, "Temp" = x_sd)
sum_sd <- as.matrix(sum_sd)
sum_sd ## Chuyển thành matrix để vẽ barchart
##      Ozone     Temp
## 5 22.22445 6.854870
## 6 18.20790 6.598589
## 7 31.63584 4.315513
## 8 39.68121 6.585256
## 9 24.14182 8.355671
sum_data_1 <- t(sum_data)
sum_data_1[2, ] <- NA
sum_data_2 <- t(sum_data)
sum_data_2[1, ] <- NA

sum_sd_1 <- t(sum_sd)
sum_sd_1[2, ] <- NA
sum_sd_2 <- t(sum_sd)
sum_sd_2[1, ] <- NA

##
error.bar <- function(x, y, upper, lower = upper, length = 0.035, ...) {
    arrows(x , y + upper, x, y - lower, angle = 90, code = 3, length = length, ...)
}

##

par(mar = c(5, 4, 4, 4) + 0.5)

ok_1 <- barplot(sum_data_1, col = "#89cff0",
     # xaxs = "i", 
     yaxs = "i",
     # xaxt="n", 
     yaxt="n",
     ylim = c(0, round(max(sum_data_1[1, ]), digits = 0) + 70),
     # xlim = c(0, max(month_5$Day, na.rm = TRUE)),
     xlab = "Tháng", ylab = "", beside = TRUE)
error.bar(ok_1, sum_data_1, sum_sd_1) 

y3 <- par('usr')

lastnum_seq_y <- function(start, end, by){
    by <- seq(from = start, to = end, by = by)
    e <- c(by, end)
    if(e[length(e)] - e[length(e) - 1] < 9){
        e_1 <- c(e[1:c(length(e) - 2)], e[length(e)])
        e_2 <- append(e_1, 1, after = 1) # insert element
        return(e_1)
    }
    e_3 <- c(by, end)
    e_4 <- append(e_3, 1, after = 1)
    return(e_3)
}

ytick <- lastnum_seq_y(0, round(max(sum_data_1[1, ]), digits = 0) + 70, 10)

axis(side = 2, at = ytick, labels = FALSE)

text(y3[1] - 0.2 , ytick,  
     labels = ytick, srt = 0, pos = 2, xpd = TRUE, col = "blue")

text(y3[1] - 1.5, mean(y3[3:4]),  
     labels = "Ozone (ppb)", srt = 90, 
     # pos = 2, 
     xpd = NA, col = "blue")

# text(mean(y3[1:2]), y3[3] - 8,  
#      labels = "Tháng", srt = 0, 
#      # pos = 1, 
#      xpd = NA, col = "black")

par(new = TRUE)

ok_2 <- barplot(sum_data_2, col = "#fe6f5e",
        # xaxs = "i", 
        yaxs = "i",
        xaxt = "n",
        yaxt = "n",
        # ylim = c(0, 500),
        ylim = c(0, round(max(sum_data_2[2, ]), digits = -2) + 20),
        # xlim = c(0, max(month_5$Day, na.rm = TRUE)),
        xlab = "", ylab = "", beside = TRUE)
error.bar(ok_2, sum_data_2, sum_sd_2) 
# ytick_2 <- lastnum_seq_y(0, 100, 10)

ytick_2 <- lastnum_seq_y(0, round(max(sum_data_2[2, ]), digits = -2) + 20, 10)

y4 <- par('usr') 

axis(side = 4, at = ytick_2, labels = FALSE)

text(y4[2] + 0.2, ytick_2,  
     labels = ytick_2, srt = 0, pos = 4, xpd = TRUE, col = "red")

text(y4[2] + 1.5, mean(y2[3:4]), labels = "Nhiệt độ (°F)", 
     xpd = NA, srt = -90, col = "red")

legend("topright",
       legend = c("Ozone (ppb)", "Nhiệt độ (°F)"),
       fill = c("#89cff0", "#fe6f5e"),
       # lty = c(1, 2), cex = 1,
       # pch = c(NA, 21),
       # lwd = 2,
       x.intersp = 1,
       y.intersp = 2,
       inset = 0.001,
       box.lty = 0,
       horiz = TRUE)
box()
# abline(h = 120, lwd = 1)
# abline(h = 0, lwd = 1)

title(main = "Chỉ số quan trắc môi trường theo từng tháng trong năm 2022")
mysubtitle <- "Đồ thị được code bởi Duc Nguyen | www.tuhocr.com"
mtext(line = 0.25, mysubtitle)

# library(png) ## dùng đề chèn file ảnh
# library(grid) ## canh chỉnh vị trí ảnh
image_tuhocr_package <- readPNG("img/tuhocr.png")
# # rasterImage(image_tuhocr,5,5,7,7)
grid.raster(image_tuhocr_package, x = 0.23, y = 0.76, width = 0.2)

Tham khảo

  1. Crawley, M. J. (2013). The R book (2nd edition). Wiley. (page 952)

  2. http://www.sthda.com/english/wiki/add-legends-to-plots-in-r-software-the-easiest-way

  3. https://stackoverflow.com/questions/49263821/generate-a-sequence-and-include-the-last-number-in-r

Sơ kết

Trên đây là hướng dẫn vẽ đồ thị hai trục tung. Để học R bài bản từ A đến Z, thân mời Bạn tham gia khóa học “HDSD R để xử lý dữ liệu” để có nền tảng vững chắc về R nhằm tự tay làm các câu chuyện dữ liệu của riêng mình!

ĐĂNG KÝ NGAY: https://www.tuhocr.com/register

Hướng dẫn cài đặt package tuhocr https://tuhocr.github.io/