#Create Dataset
<-seq(7000,3400,-200)
time<-c(200,400,450,500,300,100,400,700,830,1200,400,350,200,700,370,800,200,100,120)
pop<-c(2,5,8,3,2,2,4,7,9,4,4,2,2,7,5,12,5,4,4)
grp<-c(1.2,1.3,1.2,0.9,2.1,1.4,2.9,3.4,2.1,1.1,1.2,1.5,1.2,0.9,0.5,3.3,2.2,1.1,1.2)
med
#Define Margins. The trick is to use give as much space possible on the left margin (second value)
par(mar=c(5, 12, 4, 4) + 0.1)
#Plot the first time series. Notice that you don't have to draw the axis nor the labels
plot(time, pop, axes=F, ylim=c(0,max(pop)), xlab="", ylab="",type="l",col="black", main="",xlim=c(7000,3400))
points(time,pop,pch=20,col="black")
axis(2, ylim=c(0,max(pop)),col="black",lwd=2)
mtext(2,text="Population",line=2)
#Plot the second time series. The command par(new=T) is handy here.
#If you just need to plot two timeseries, you could also use the right vertical axis as well.
#In that case you have to substitute "2" with "4" in the functions axis() and mtext().
#Notice that in both functions lines is increased so that the new axis and
#its label is placed to the left of the first one.
#You don't need to increase the value if you use the right vertical axis.
par(new=T)
plot(time, med, axes=F, ylim=c(0,max(med)), xlab="", ylab="",
type="l",lty=2, main="",xlim=c(7000,3400),lwd=2)
axis(2, ylim=c(0,max(med)),lwd=2,line=3.5)
points(time, med,pch=20)
mtext(2,text="Median Group Size",line=5.5)
#Plot the third time series. Again the line parameter are both further increased.
par(new=T)
plot(time, grp, axes=F, ylim=c(0,max(grp)), xlab="", ylab="",
type="l",lty=3, main="",xlim=c(7000,3400),lwd=2)
axis(2, ylim=c(0,max(grp)),lwd=2,line=7)
points(time, grp,pch=20)
mtext(2,text="Number of Groups",line=9)
#We can now draw the X-axis, which is of course shared by all the three time-series.
axis(1,pretty(range(time),10))
mtext("cal BP",side=1,col="black",line=2)
#And then plot the legend.
legend(x=7000,y=12,legend=c("Population","Median Group Size","Number of Groups"),lty=c(1,2,3))
4 Hướng dẫn vẽ đồ thị nhiều trục Y
Nguyên tắc chung khi vẽ nhiều trục Y hay X là ta sẽ set par(new = TRUE)
để tạo ra 1 plot mới dán đè lên plot hiện tại với scale trục Y mới, ta thay đổi vị trí các trục Y bằng lệnh axis()
.
4.1 Tham khảo
https://evolvingspaces.blogspot.com/2011/05/multiple-y-axis-in-r-plot.html
4.2 Vẽ đồ thị nhiều trục Y
Sử dụng dataset airquality
. Daily readings of the following air quality values for May 1, 1973 (a Tuesday) to September 30, 1973.
Ozone: Mean ozone in parts per billion from 1300 to 1500 hours at Roosevelt Island
Solar.R: Solar radiation in Langleys in the frequency band 4000–7700 Angstroms from 0800 to 1200 hours at Central Park
Wind: Average wind speed in miles per hour at 0700 and 1000 hours at LaGuardia Airport
Temp: Maximum daily temperature in degrees Fahrenheit at La Guardia Airport.
A data frame with 153 observations on 6 variables.
[,1] Ozone numeric Ozone (ppb)
[,2] Solar.R numeric Solar R (lang)
[,3] Wind numeric Wind (mph)
[,4] Temp numeric Temperature (degrees F)
[,5] Month numeric Month (1–12)
[,6] Day numeric Day of month (1–31)
Source: The data were obtained from the New York State Department of Conservation (ozone data) and the National Weather Service (meteorological data).
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
-> df
airquality
$year <- 1973
df
$date <- paste0(df$year, "-", df$Month, "-", df$Day)
df
$date <- as.Date(df$date)
df
$time <- row.names(df)
df
$time <- as.numeric(df$time)
df
# options(max.print = 100000)
# windows(width = 18, height = 6) # vẽ chuẩn trên này
# save chuẩn, nếu không khớp cần chỉnh trực tiếp lại
png(width = 18,
height = 6,
units = "in",
res = 300,
filename = "do_thi_nhieu_truc_tung.png")
# oldpar <- par(no.readonly = TRUE)
par(oma = c(0, 0, 0, 0))
par(mar = c(10, 20, 4, 4))
par(xpd = TRUE)
# par(bg = "aliceblue")
plot(formula = Ozone ~ time,
data = na.omit(df[, c("Ozone", "time")]), # nối liền NA
axes = FALSE,
ylim = c(0, max(df$Ozone, na.rm = TRUE)*3),
xaxs = "i",
yaxs = "i",
xaxt = "n",
yaxt = "n",
xlab = "",
ylab = "",
lty = 2,
lwd = 2,
type = "l",
col = "blue",
main = "",
xlim = c(1, max(df$time))
)
# Change the plot region color
rect(par("usr")[1], par("usr")[3],
par("usr")[2], par("usr")[4],
col = "lightyellow") # Color
###
par(new = TRUE)
plot(formula = Ozone ~ time,
data = na.omit(df[, c("Ozone", "time")]), # nối liền NA
axes = FALSE,
ylim = c(0, max(df$Ozone, na.rm = TRUE)*3),
xaxs = "i",
yaxs = "i",
xaxt = "n",
yaxt = "n",
xlab = "",
ylab = "",
lty = 2,
lwd = 2,
type = "l",
col = "blue",
main = "",
xlim = c(1, max(df$time))
)
box(which = "plot")
box(which = "figure")
box(which = "inner")
box(which = "outer")
# points(formula = Ozone ~ time,
# data = na.omit(df[, c("Ozone", "time")]),
# pch = 20,
# col = "black")
## trục Y1
axis(side = 2,
# ylim = c(0, max(df$Ozone, na.rm = TRUE)*3),
at = c(0, 50, 100, 150, 200),
labels = c(0, 50, 100, 150, 200),
col = "blue",
col.axis = "blue",
font = 2,
lwd = 2,
las = 2)
mtext(side = 2,
text = "Ozone (ppb)",
line = 3,
font = 2,
col = "blue",
adj = 0)
## trục X1
# axis(side = 1,
# at = pretty(range(df$time), 10) # tự chia khoảng cho hợp lý
# )
## scale X1
<- c(1, 10, 20, 30, 40, 50,
time_1 60, 70, 80, 90, 100, 110,
120, 130, 140, 153)
axis(side = 1,
at = time_1,
labels = time_1,
font = 2,
lwd = 2
)
mtext(side = 1,
text = "Tính theo ngày",
line = 3,
font = 2)
###
par(new = TRUE)
plot(formula = Ozone ~ date,
data = na.omit(df[, c("Ozone", "date")]), # nối liền NA
axes = FALSE,
ylim = c(0, max(df$Ozone, na.rm = TRUE)),
xaxs = "i",
yaxs = "i",
xaxt = "n",
yaxt = "n",
xlab = "",
ylab = "",
type = "n",
col = "black",
main = ""
)
## scale X2 (vì là datetime nên phải plot riêng cái mới,
# do R vẽ datetime theo numeric tính từ 1970-01-01)
axis(side = 1,
at = c(seq.Date(from = df$date[1], to = df$date[153], by = "months"), df$date[153]),
line = 5,
labels = c(seq.Date(from = df$date[1], to = df$date[153], by = "months"), df$date[153]),
font = 2,
lwd = 2,
col = "darkgreen",
col.axis = "darkgreen",
)
mtext(side = 1,
text = "Thời gian thực đo (YYYY-MM-DD)",
line = 8,
col = "darkgreen",
font = 2)
### VẼ TRỤC Y2
par(new = TRUE)
plot(formula = Solar.R ~ time,
data = na.omit(df[, c("Solar.R", "time")]), # nối liền NA
axes = FALSE,
ylim = c(0, max(df$Solar.R, na.rm = TRUE)*2),
xaxs = "i",
yaxs = "i",
xaxt = "n",
yaxt = "n",
xlab = "",
ylab = "",
type = "l",
col = "red",
main = "",
xlim = c(1, max(df$time))
)
## trục Y2
axis(side = 2,
# ylim = c(0, max(df$Solar.R, na.rm = TRUE)*2),
at = c(0, 100, 200, 300, 400),
labels = c(0, 100, 200, 300, 400),
col = "red",
col.axis = "red",
font = 2,
lwd = 2,
las = 2,
line = 5)
mtext(side = 2,
text = "Solar radiation (lang)",
line = 8,
font = 2,
col = "red",
adj = 0)
### VẼ TRỤC Y3
par(new = TRUE)
plot(formula = Wind ~ time,
data = na.omit(df[, c("Wind", "time")]), # nối liền NA
axes = FALSE,
ylim = c(0, max(df$Wind, na.rm = TRUE)*1.1),
xaxs = "i",
yaxs = "i",
xaxt = "n",
yaxt = "n",
xlab = "",
ylab = "",
type = "l",
col = "black",
lwd = 1,
lty = 1,
main = "",
xlim = c(1, max(df$time))
)
## trục Y3
axis(side = 2,
ylim = c(0, max(df$Wind, na.rm = TRUE)*1.1),
col = "black",
col.axis = "black",
font = 2,
lwd = 2,
las = 2,
line = 10)
mtext(side = 2,
text = "Wind (mph)",
line = 12,
font = 2,
adj = 0,
col = "black")
### VẼ TRỤC Y4
par(new = TRUE)
plot(formula = Temp ~ time,
data = na.omit(df[, c("Temp", "time")]), # nối liền NA
axes = FALSE,
ylim = c(0, max(df$Temp, na.rm = TRUE)*1.2),
xaxs = "i",
yaxs = "i",
xaxt = "n",
yaxt = "n",
xlab = "",
ylab = "",
type = "l",
lwd = 2,
lty = 1,
col = "cyan2",
main = "",
xlim = c(1, max(df$time))
)
## trục Y4
axis(side = 2,
ylim = c(0, max(df$Temp, na.rm = TRUE)*1.2),
col = "cyan2",
col.axis = "cyan2",
font = 2,
lwd = 2,
las = 2,
line = 14)
mtext(side = 2,
text = "Temperature (\u00B0F)",
line = 17,
font = 2,
adj = 0,
col = "cyan2")
title(main = "Diễn tiến chất lượng không khí theo thời gian | Nguồn: dataset airquality in R")
###
library(png)
library(grid)
<- readPNG("logor.png")
logor grid.raster(logor, x = 0.05, y = 0.9, width = 0.05)
###
library(unikn)
library(showtext)
par(lheight = 1.15)
###
# https://cran.r-project.org/web/packages/unikn/vignettes/text.html
<- function (labels, x = 0, y = 0.55, x_layout = NA, y_layout = "even",
mark_v1 col = "black", col_bg = Seeblau, cex = 2, font = 2, new_plot = "none", ...)
{if (new_plot == FALSE || tolower(new_plot) == "false" ||
substr(tolower(new_plot), 1, 2) == "no") {
<- "none"
new_plot
}:::plot_text(labels = labels, x = x, y = y, x_layout = x_layout,
unikny_layout = y_layout, col = col, col_bg = col_bg, cex = cex,
font = font, new_plot = new_plot, col_bg_border = NA,
pos = 4, mark = TRUE, ...)
}###
rect(-43, -68,
-7, -24,
col = "gold") # Color
mark_v1(labels = c("Thực hiện: Duc Nguyen",
"Website: www.tuhocr.com",
"Chuyên đào tạo R căn bản",
"Welcome to Tự Học R ;)"),
x = -40,
y = -30,
family = "mono",
y_layout = "flush",
col_bg = "transparent",
col = "#0000b3",
cex = 1.2)
# par(oldpar)
dev.off()
::include_graphics("do_thi_nhieu_truc_tung.png") knitr
Full-size: https://thongkesinhhoc.com/do_thi_nhieu_truc_tung.png