是否有可能以同样的方式抖动两个ggplot geom?

时间:2010-07-02 11:46:02

标签: r ggplot2

使用position_jitter可以创建随机抖动,以防止数据点过度绘制。

在下面我用棒球统计的例子来说明我的问题。当我用两个图层绘制相同的数据时,相同的抖动调用会使geoms有点不同。 这是有道理的,因为它可能会在两次调用中独立生成随机抖动,但会产生您在下面的图表中看到的问题。

p=ggplot(baseball,aes(x=round(year,-1),y=sb,color=factor(lg))) 
p=p+stat_summary(fun.data="mean_cl_normal",position=position_jitter(width=3,height=0))+coord_cartesian(ylim=c(0,40))
p+stat_summary(fun.y=mean,geom="line",position=position_jitter(width=3,height=0))

虽然错误条指向并且线条引用相同的数据,但它们是脱节的 - 线条和点不连接。

有解决办法吗?我认为位置闪避可能是答案,但它似乎不适用于这些类型的情节。或者,也许有一些方法可以让mean_cl_normal调用也添加行? alt text http://img339.imageshack.us/img339/1807/screenshot20100702at943.png

3 个答案:

答案 0 :(得分:9)

我是这么认为的,通过在两个实例中将种子设置为相同:

p=ggplot(baseball,aes(x=round(year,-1),y=sb,color=factor(lg)))
myseed = 2010
set.seed(myseed)
p=p+stat_summary(fun.data="mean_cl_normal",
  position=position_jitter(width=3,height=0))+coord_cartesian(ylim=c(0,40))
set.seed(myseed)
p+stat_summary(fun.y=mean,geom="line",
           position=position_jitter(width=3,height=0))

这可确保将随机数生成器发送回与初始调用中使用的相同的起始位置。但是我不知道如何提取添加到值中的随机增量。

答案 1 :(得分:7)

这是当前ggplot2语法的一个弱点 - 除了自己添加抖动之外,没办法解决它。

或者你可以这样做:

ggplot(baseball, aes(round(year,-1) + as.numeric(factor(lg)), sb, color = factor(lg))) +
  stat_summary(fun.data="mean_cl_normal") +
  stat_summary(fun.y=mean,geom="line") +
  coord_cartesian(ylim=c(0,40))

答案 2 :(得分:1)

我最终生成了统一分布来解决这个问题。

我今天必须解决同样的根本问题。我创建一个绘图,抖动点,然后我创建第二个绘图,基本上放大第一个的子部分。如果点数四处移动,那就是不和谐和分散注意力。

以下是问题和我的解决方案的演示。我没有在这个情节中使用ggplot,但同样的概念适用。我进行了均匀分布,每个值需要抖动一个值。我将它添加到源数据帧中,这样每次我获取一个子集时,抖动值对应于相同的原始数据值。

data(airquality)
someDataset= airquality 
someDataset$color="black"
someDataset$color[someDataset$Month==8 & someDataset$Wind==9.7]="red"
## jitter gives different results each time it's run
for (fZoom in c(TRUE, FALSE)){
    if (fZoom) myAirQuality = someDataset[someDataset $Wind >7.5 & someDataset $Wind < 11.5,] 
    else myAirQuality = someDataset[someDataset $Wind >8.5 & someDataset $Wind < 10.5,]
    quartz("Using Jitter")
    plot(myAirQuality $Wind ~ jitter(myAirQuality $Month), col= myAirQuality$color)
    }

someDataset$MonthJit=runif(nrow(someDataset), min=-0.2, max=0.2)
for (fZoom in c(TRUE, FALSE)){
    if (fZoom) myAirQuality = someDataset[someDataset $Wind >7.5 & someDataset $Wind < 11.5,] 
    else myAirQuality = someDataset[someDataset $Wind >8.5 & someDataset $Wind < 10.5,]
    quartz("Using runif")
    plot(myAirQuality $Wind ~ c(myAirQuality $Month + myAirQuality $MonthJit), col= myAirQuality$color)
    }