gpt4 book ai didi

r - geom_path() 拒绝跨越 coord_polar() 中的 0/360 线

转载 作者:行者123 更新时间:2023-12-02 01:40:40 25 4
gpt4 key购买 nike

我试图绘制一个物体(假设它是一个风向标)随时间变化的角度。我想将其绘制在极坐标系上,并通过路径连接时间点,显示角度如何随时间变化。我只是有一个数据框,其中一列是角度(以度为单位)(数字),然后是记录角度时的时间步长(整数)。

但是当我运行以下代码时:

ggplot(df, aes(x = angle.from.ref, y = time.step)) +
coord_polar() +
geom_path() +
geom_point() +
scale_x_continuous(limits = c(0, 360), breaks = seq(0, 360, 45))

我得到的东西看起来像这样:

like this

geom_path() 创建的路径拒绝跨越 0/360 度线。如果值 359 后跟值 1,则路径将不会创建穿过 x=0/360 点的短链接。相反,路径绕着圆一路向后弯曲,从另一侧到达 x=1。

我曾希望使用coord_polar()能够解决这个问题,但显然没有。有什么方法可以告诉 ggplot 值 0 和 360 是相邻/连续的吗?

最佳答案

绕过交叉问题可能更直接:在 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()

plot

代码 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()

plot

关于r - geom_path() 拒绝跨越 coord_polar() 中的 0/360 线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55132352/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com