我可以使用相同的x轴(例如,年份)绘制一个ggplot2
图,但是使用不同的y轴(比例非常不同。可以使用gganimate
来为两条线设置动画) ,每个都对应于自己的y轴?我已经能够使用相同的y轴创建两条线,但无法弄清楚如何使用两个轴。
我认为在我的特定情况下,该问题可能与我的y轴变量为POSIX格式有关。
假设我按如下方式创建a
数据集:
library(ggplot2)
library(gganimate)
library(htmltab)
library(lubridate)
#marathon
data0 <- htmltab("https://en.wikipedia.org/wiki/Marathon_world_record_progression",1)
data <- data0[,c(1,4)]
#remove ones that are ARRS only
data <- data[-c(9,12,13,22,27,33,34,35,36,51),]
#data <- data %>% mutate(time = Time %>% hms())
data$time2 <- as.POSIXct(data$Time, format = "%H:%M:%S")
data$date <- mdy(data$Date)
data$race <- "Marathon"
#mile
mile0 <- htmltab("https://en.wikipedia.org/wiki/Mile_run_world_record_progression",4)
mile <- mile0[,c(1,4)]
#mile <- mile0 %>% mutate(time = Time %>% ms())
mile$time2 <- as.POSIXct(mile$Time, format = "%M:%S")
mile$date <- dmy(mile$Date)
mile$race <- "Mile"
marathon <- data[,c(3,4)]
names(marathon)[1]<-"marathon"
mile2 <- mile[,c(3,4)]
names(mile2)[1]<-"mile"
a <- merge(marathon, mile2, by="date", all=TRUE)
然后我可以制作一个gganimate
动画,如下所示:
ggplot(a) +
geom_point(aes(x=date, y=marathon, group=date, color="blue")) +
geom_point(aes(x=date, y=mile, group=date, color="red")) +
scale_y_continuous(sec.axis = sec_axis(~./152, name = "CDF"), breaks=seq(0,150,25))
transition_reveal(date)
问题在于两者的比例截然不同(一个约为2-3小时,而另一个约为2.5-3.5分钟)。如何获得相同规模的产品?如果它们使用的是正常格式,则我可以执行以下操作:
ggplot(a) +
geom_point(aes(x=date, y=marathon, group=date, color="blue")) +
geom_point(aes(x=date, y=mile*65, group=date, color="red")) +
scale_y_continuous(sec.axis = sec_axis(~./65, name = "Mile"), breaks=seq(0,150,25)) +
transition_reveal(date)
但是,由于y变量所处的POSIX格式,我得到了一个错误。我该怎么办? (理想情况下,我想按比例缩放它们,以便每个变量的垂直范围基本上能填充垂直距离。)
作为参考,这是我要修复的绘图结果:
我担心这不可能。参见https://ggplot2.tidyverse.org/reference/sec_axis.html:
“从v3.1开始,日期和日期时间刻度具有有限的辅助轴功能。与其他连续刻度不同,日期和日期时间刻度的辅助轴转换必须遵循其主要POSIX数据结构。这意味着只能通过加法转换或减法,例如〜。+ hms :: hms(days = 8),或〜。-8 * 60 * 60。非线性变换将返回错误。在这种情况下,要生成时间自事件的辅助轴,用户可以考虑修改辅助轴标签。”
答案 0 :(得分:1)
一种方法是将时间转换为十进制小时(或分钟等)并调整比例尺标签:
library(dplyr); library(lubridate)
a %>%
# tidyr::gather(type, time, -date) %>%
tidyr::pivot_longer(-date, "type", "time") %>% # Preferred syntax since tidyr 1.0.0
mutate(time_dec = hour(value) + minute(value)/60 + second(value)/3600,
time_scaled = time_dec * if_else(type == "mile", 30, 1)) %>%
ggplot() +
geom_point(aes(x=date, y=time_scaled, group=value, color = type)) +
scale_y_continuous(breaks = 0:3,
labels = c("0", "1:00", "2:00", "3:00"),
name = "Marathon",
sec.axis = sec_axis(~./30,
name = "Mile",
breaks = (1/60)*0:100,
labels = 0:100)) +
expand_limits(y = c(1.5,3)) +
transition_reveal(date)