绕过交叉问题可能更为直接:在360/0点进行插值,并将每次旋转绘制为自己的部分。以下是它的工作原理:
library(dplyr) library(ggplot2) # sample data n <- 100 df <- data.frame( angle.from.ref = seq(0, 800, length.out = n), time.step = seq(Sys.time(), by = "min", length.out = n) ) df %>% interpolate.revolutions() %>% ggplot(aes(x = angle.from.ref, y = time.step, group = revolution)) + geom_line(aes(color = factor(revolution)), size = 1) + # color added for illustration scale_x_continuous(limits = c(0, 360), breaks = seq(0, 360, 45)) + coord_polar()
代码 interpolate.revolutions 功能:
interpolate.revolutions
interpolate.revolutions <- function(df, threshold = 360){ # where df is a data frame with angle in the first column & radius in the second res <- df # add a label variable such that each span of 360 degrees belongs to # a different revolution res$revolution <- res[[1]] %/% threshold # keep only the angle values within [0, 360 degrees] res[[1]] <- res[[1]] %% threshold # if there are multiple revolutions (i.e. the path needs to cross the 360/0 threshold), # calculate interpolated values & add them to the data frame if(n_distinct(res$revolution) > 1){ split.res <- split(res, res$revolution) res <- split.res[[1]] for(i in seq_along(split.res)[-1]){ interp.res <- rbind(res[res[[2]] == max(res[[2]]), ], split.res[[i]][split.res[[i]][[2]] == min(split.res[[i]][[2]]), ]) interp.res[[2]] <- interp.res[[2]][[1]] + (threshold - interp.res[[1]][1]) / (threshold - interp.res[[1]][1] + interp.res[[1]][2]) * diff(interp.res[[2]]) interp.res[[1]] <- c(threshold, 0) res <- rbind(res, interp.res, split.res[[i]]) } } return(res) }
该方法也可以应用于图中的多个线。只需将功能分别应用于每一行:
# sample data for two lines, for different angle values taken at different time points df2 <- data.frame( angle.from.ref = c(seq(0, 800, length.out = 0.75 * n), seq(0, 1500, length.out = 0.25 * n)), time.step = c(seq(Sys.time(), by = "min", length.out = 0.75 * n), seq(Sys.time(), by = "min", length.out = 0.25 * n)), line = c(rep(1, 0.75*n), rep(2, 0.25*n)) ) df2 %>% tidyr::nest(-line) %>% mutate(data = purrr::map(data, interpolate.revolutions)) %>% tidyr::unnest() %>% ggplot(aes(x = angle.from.ref, y = time.step, group = interaction(line, revolution), color = factor(line))) + geom_line(size = 1) + scale_x_continuous(limits = c(0, 360), breaks = seq(0, 360, 45)) + coord_polar()