我想绘制一个时间过程x,其中y值经常重复(整数得分1-4),并且我想一次可视化许多对象。
因为有太多的重叠,所以理想的是垂直位置躲闪,例如ggstance包中的position_dodgev
。但是,当我尝试将点与geom_line连接时,连接顺序混乱了,并基于y值而不是x值进行连接。
我尝试了一次坐标翻转解决方法,但未成功。将geom_line
替换为geom_path
(确保按x比例排序)也无效。
以下是可重现的示例:
#data
df<-tibble(x=c(1,2,3,4,5,1,2,3,4,5,1,2,3,4,5),
y=c(1,2,3,7,7,1,2,3,7,7,2,1,6,7,7),
group=c('a','a','a','a','a','b','b','b','b','b','c','c','c','c','c'))
#horizontal dodge masks groups
ggplot(df, aes(x=x, y=y,col=group,group=group)) +
geom_point(position=position_dodge(width=0.3))+
geom_line(position=position_dodge(width=0.3))
#line connection error with vertical dodge
library(ggstance)
ggplot(df, aes(x=x, y=y,col=group,group=group)) +
geom_point(position=position_dodgev(height=0.3))+
geom_line(position=position_dodgev(height=0.3))
水平闪避按预期工作,但不允许在重复的y值范围内可视化所有重叠的组。来自ggstance
的垂直闪避以错误的顺序连接了c组中的点。
答案 0 :(得分:2)
我不确定是什么导致了此问题。知道position_dodge
不打算与geoms
和it's been called a bug一起使用时,我对此感到很惊讶,而不是同时使用。
但是无论如何,我找到了一种解决方法,方法是使用ggplot_build
分解图,重新排列对象中geom_line
的点,然后重新组装图。看下面:
g <- ggplot(df, aes(x=x, y=y,col=group,group=group)) +
geom_point(position=position_dodgev(height=0.3)) +
geom_line(position=position_dodgev(height=0.3))
gg <- ggplot_build(g)
# -- look at gg$data to understand following lines --
#gg$data[[2]]: data associated with geom_line as it is the 2nd geom
#c(1,2) & c(2,1): I have $group==3 ...
# ... so just need to flip 1st and 2nd datapoints within that group
gg$data[[2]][gg$data[[2]]$group==3,][c(1,2),] <-
gg$data[[2]][gg$data[[2]]$group==3,][c(2,1),]
gt <- ggplot_gtable(gg)
plot(gt)
答案 1 :(得分:0)
我怀疑问题是由于PositionDodgev
的{{1}}函数引起的,该函数接收按x值排序的数据集,并在创建后返回按y值排序的数据集(在每个组中)进行垂直位置躲避的必要转换。
以下变通办法定义了一个新的ggproto对象,该对象继承自compute_panel
,但是在返回数据集之前对PositionDodgev
中的数据集进行了重新排序:
compute_panel
用法:
# new ggproto based on PositionDodgev
PositionDodgeNew <- ggproto(
"PositionDodgeNew",
PositionDodgev,
compute_panel = function (data, params, scales){
result <- ggstance:::collidev(data, params$height,
name = "position_dodgev",
strategy = ggstance:::pos_dodgev,
n = params$n,
check.height = FALSE)
result <- result[order(result$group, result$x), ] # reordering by group & x
result
})
# position function that uses PositionDodgeNew instead of PositionDodgev
position_dodgenew <- function (height = NULL, preserve = c("total", "single")) {
ggproto(NULL, PositionDodgeNew, height = height, preserve = match.arg(preserve))
}