目录
方法一:ggplot中的sec.axis函数
方法二:plotrix包中的twoord.plot()函数和twoord.stackplot()函数
方法一:ggplot中的sec.axis函数
ggplot2支持直接显示在辅助轴上的数据的1:1转换。 在创建辅助轴时,需重新计算第二个右侧轴上显示的参数,并将其添加到绘图中。 以下示例说明了如何利用它显示两个参数,且每个参数都有其唯一的数据范围。
library(ggplot2) # must be version > 2.2.0
library(ReadAxfBOM)
# 数据导入
obs <- ReadAxfBOM("http://www.bom.gov.au/fwo/IDV60901/IDV60901.94866.axf")
# show first observations
head(obs)
## Timestamp wmo name history_product
## 1 2016-11-15 12:30:00 94866 Melbourne Airport IDV60901
## 2 2016-11-15 12:00:00 94866 Melbourne Airport IDV60901
## 3 2016-11-15 11:30:00 94866 Melbourne Airport IDV60901
## 4 2016-11-15 11:00:00 94866 Melbourne Airport IDV60901
## 5 2016-11-15 10:30:00 94866 Melbourne Airport IDV60901
## 6 2016-11-15 10:00:00 94866 Melbourne Airport IDV60901
## local_date_time local_date_time_full aifstime_utc lat lon apparent_t
## 1 15/12:30pm 20161115123000 2.016112e+13 -37.7 144.8 9.9
## 2 15/12:00pm 20161115120000 2.016112e+13 -37.7 144.8 10.6
## 3 15/11:30am 20161115113000 2.016112e+13 -37.7 144.8 9.9
## 4 15/11:00am 20161115110000 2.016112e+13 -37.7 144.8 9.8
## 5 15/10:30am 20161115103000 2.016111e+13 -37.7 144.8 10.1
## 6 15/10:00am 20161115100000 2.016111e+13 -37.7 144.8 9.3
## cloud cloud_base_m cloud_oktas cloud_type_id cloud_type delta_t
## 1 Mostly clear 660 1 7 Stratus 3.4
## 2 Mostly cloudy 600 7 35 <NA> 3.5
## 3 Mostly clear 570 1 7 Stratus 3.1
## 4 Mostly clear 570 1 7 Stratus 2.9
## 5 Mostly clear 630 1 7 Stratus 3.2
## 6 Mostly clear 630 2 7 Stratus 2.5
## gust_kmh gust_kt air_temp dewpt press press_qnh press_msl press_tend
## 1 32 17 14.9 8.1 1020.1 1020.3 1020.1 <NA>
## 2 32 17 15.2 8.3 1020.2 1020.4 1020.2 R
## 3 28 15 14.2 8.0 1020.1 1020.3 1020.1 <NA>
## 4 30 16 14.0 8.2 1020.1 1020.3 1020.1 <NA>
## 5 26 14 14.4 8.0 1020.0 1020.2 1020.0 <NA>
## 6 26 14 13.3 8.3 1020.0 1020.2 1020.0 <NA>
## rain_trace rel_hum sea_state swell_dir_worded swell_height swell_period
## 1 0 64 NA NA -9999 -9999
## 2 0 63 NA NA -9999 -9999
## 3 0 66 NA NA -9999 -9999
## 4 0 68 NA NA -9999 -9999
## 5 0 65 NA NA -9999 -9999
## 6 0 72 NA NA -9999 -9999
## vis_km weather wind_dir wind_spd_kmh wind_spd_kt extreme_event
## 1 10 <NA> SW 24 13 FALSE
## 2 30 Fine SW 22 12 FALSE
## 3 10 <NA> SW 20 11 FALSE
## 4 10 <NA> SW 20 11 FALSE
## 5 10 <NA> SSW 20 11 FALSE
## 6 10 <NA> SW 19 10 FALSE
# 绘制气候温度图
p <- ggplot(obs, aes(x = Timestamp))
p <- p + geom_line(aes(y = air_temp))
p
# 增加湿度
p <- p + geom_line(aes(y = rel_hum))
p
由于辅助轴只能显示右y轴的一对一转换,因此我们必须转换辅助轴上显示的数据。 在这种情况下,相对湿度除以5。
p <- ggplot(obs, aes(x = Timestamp))
p <- p + geom_line(aes(y = air_temp, colour = "Temperature"))
# adding the relative humidity data, transformed to match roughly the range of the temperature
p <- p + geom_line(aes(y = rel_hum/5, colour = "Humidity"))
# now adding the secondary axis, following the example in the help file ?scale_y_continuous
# and, very important, reverting the above transformation
p <- p + scale_y_continuous(sec.axis = sec_axis(~.*5, name = "Relative humidity [%]"))
# modifying colours and theme options
p <- p + scale_colour_manual(values = c("blue", "red"))
p <- p + labs(y = "Air temperature [°C]",
x = "Date and time",
colour = "Parameter")
p <- p + theme(legend.position = c(0.8, 0.9))
p
scales包提供了一个重新校正的函数,scales:rescale(), 可以将辅助参数转换为任何所需范围,然后,将主要的y轴刻度线与次要的刻度线进行匹配是一个手动过程。
在这个例子中,可以说相对湿度和空气温度通过众所周知的水蒸气压和饱和蒸气压函数相互关联。 因此,在这种情况下,即使在所有温度下都不是1:1的线性关系,也可以以相同的比例将它们显示在变换的比例尺上。
rescale函数应用
lct <- Sys.getlocale("LC_TIME")
#备份本地默认日期显示格式
Sys.setlocale("LC_TIME", "C")
#指定标准日期显示格式
Sys.setlocale("LC_TIME",lct)
#这一句是恢复默认系统日期显示格式
#(记得要在使用完下面的month函数之后再运行这一句,否则月份返回的是中文)
加载包:
library("lubridate")
library("ggplot2")
library("scales")
library("magrittr")
library("tidyr")
data1 <- data.frame(
Month = seq(from = as.Date('2017-01-01'),to=as.Date('2017-06-01'),by='1 month') %>% month(label=TRUE),
Value = runif(6,10,50) %>% round()
)
data2 <- data.frame(
Month = seq(from = as.Date('2017-01-01'),to=as.Date('2017-06-01'),by='1 month') %>% month(label=TRUE),
Categroy1 = runif(6,0.1,0.5) %>% round(2),
Categroy2 = runif(6,0.1,0.5) %>% round(2)
) %>% gather(Category,Value,-1)
ggplot() +
geom_col( data = data1,aes(x = Month,y = Value),fill="#6794a7") +
geom_line(data = data2,aes(x = Month,y = rescale(Value,c(0,55)),colour=Category,group=Category),size=1.5) +#将折线图的数据源量级(0.0~0.5)放大到0~55的区间上
geom_point(data = data2,aes(x = Month,y = rescale(Value,c(0,55)),colour=Category),shape=21,fill="white",size=4)+
scale_y_continuous(breaks=pretty_breaks(5),sec.axis = sec_axis( ~rescale(.,c(0,0.5)),name = "Categroy",labels=sprintf("%d%%",(0:5)*10)))+ #将之前已经被标准化到0~50区间内的原始度量标签通过rescale函数再次标准化到0~0.5区间内
scale_color_manual(label = c("Categroy1", "Categroy2"),values = c("#ee8f71","#C10534")) +
labs(
title="This is a Title!",
subtitle="This is a Subtitle",
caption="This is a Caption"
)+
theme_minimal(base_size=16) %+replace%
theme(
plot.caption = element_text(hjust=0),
plot.margin = unit(c(1,0.5,1,0.5), "lines")
)
本例子中
p <- ggplot(obs, aes(x = Timestamp))
p <- p + geom_line(aes(y = air_temp, colour = "Temperature"))
# adding the relative humidity data, transformed to match roughly the range of the temperature
p <- p + geom_line(aes(y = rescale(rel_hum,c(0,30)), colour = "Humidity"))
# now adding the secondary axis, following the example in the help file ?scale_y_continuous
# and, very important, reverting the above transformation
p <- p + scale_y_continuous(sec.axis = sec_axis(~rescale(.,c(40,110),
name = "Relative humidity [%]")))
#sec.axis = sec_axis( ~rescale(.,c(0,0.5))
# modifying colours and theme options
p <- p + scale_colour_manual(values = c("blue", "red"))
p <- p + labs(y = "Air temperature [°C]",
x = "Date and time",
colour = "Parameter")
p <- p + theme(legend.position = c(0.8, 0.9))
p
方法二:plotrix包中的twoord.plot()函数和twoord.stackplot()函数
library(plotrix)
# NOT RUN {
xval1 <- seq.Date(as.Date("2017-01-02"),
as.Date("2017-01-10"), by="day")
xval2 <- seq.Date(as.Date("2017-01-01"),
as.Date("2017-01-15"), by="day")
going_up<-seq(3,7,by=0.5)+rnorm(9)
going_down<-rev(60:74)+rnorm(15)
twoord.plot(2:10,going_up,1:15,going_down,xlab="Sequence",
ylab="Ascending values",rylab="Descending values",lcol=4,
main="Plot with two ordinates - points and lines",
do.first="plot_bg();grid(col=\"white\",lty=1)")
axis.Date(1,xval2)
# separate the lines
twoord.plot(2:10,going_up,1:15,going_down,xlab="Sequence",
lylim=range(going_up)+c(-1,10),rylim=range(going_down)+c(-10,2),
ylab="Ascending values",ylab.at=5,rylab="Descending values",
rylab.at=65,lcol=4,main="Plot with two ordinates - separated lines",
lytickpos=3:7,rytickpos=seq(55,75,by=5),
do.first="plot_bg();grid(col=\"white\",lty=1)")
twoord.plot(2:10,going_up,1:15,going_down,xlab="Sequence",
lylim=range(going_up)+c(-1,10),rylim=range(going_down)+c(-10,2),
type=c("bar","l"),ylab="Ascending values",ylab.at=5,
rylab="Descending values",rylab.at=65,
main="Bars on left axis, lines on right axis",
lytickpos=3:7,rytickpos=seq(55,75,by=5),
lcol=3,rcol=4,do.first="plot_bg()")
time <- 0:25
A <- 1+1/2*sin(time/2)
B <- A + rnorm(length(A), sd=1/10)
B <- B + rnorm(length(A), sd=1/10)
sizeA <- floor(450*(1 + 1/4*sin(time/2+2))*(1+.1))
sizeB <- 1000-sizeA
C <- (A*sizeA + B*sizeB)/(sizeA+sizeB)
twoord.stackplot(lx=time, rx=time, ldata=cbind(sizeA, sizeB),
rdata=cbind(A, B, C), lcol=c("grey80", "white"),
rcol=c("blue", "red","black"), ltype="bar", rtype=c("l","p","o"),
border="grey80", lylab="Size", rylab="A,B,C", xlab="Time",
main="a plot", incrylim=2/100)
#reverse the order of plotting
twoord.stackplot(lx=time, rx=time, ldata=cbind(sizeA, sizeB),
rdata=cbind(A, B, C), lcol=c("grey80", "white"),
rcol=c("blue", "red","black"), ltype="bar", rtype=c("l","p","o"),
border="grey80", lylab="Size", rylab="A,B,C", xlab="Time",
main="a plot", incrylim=2/100, leftfront=TRUE)
参考资料:
https://rpubs.com/MarkusLoew/226759
https://rdrr.io/cran/plotrix/man/twoord.stackplot.html
https://www.rdocumentation.org/packages/plotrix/versions/3.7-8/topics/twoord.plot
https://zhuanlan.zhihu.com/p/31872309