如何在R中的ggplot2中躲避点

时间:2023-02-09 21:34:39
df = data.frame(subj=c(1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10), block=factor(rep(c(1,2),10)), acc=c(0.75,0.83,0.58,0.75,0.58,0.83,0.92,0.83,0.83,0.67,0.75,0.5,0.67,0.83,0.92,0.58,0.75,0.5,0.67,0.67))
ggplot(df,aes(block,acc,group=subj)) + geom_point(position=position_dodge(width=0.3)) + ylim(0,1) + labs(x='Block',y='Accuracy')

How do I get points to dodge each other uniformly in the horizontal direction? (I grouped by subj in order to get it to dodge at all, which might not be the correct thing to do...)

如何在水平方向上均匀地相互闪避? (我按照subj进行分组,以便让它完全躲闪,这可能不是正确的事情......)

2 个解决方案

#1


1  

I think this might be what you were looking for, although no doubt you have solved it by now. Hopefully it will help someone else with the same issue.

我想这可能就是你想要的,虽然毫无疑问你现在已经解决了。希望它能帮助其他人解决同样的问题。

A simple way is to use geom_dotplot like this:

一个简单的方法是使用geom_dotplot,如下所示:

ggplot(df,aes(x=block,y=acc)) + 
geom_dotplot(binaxis = "y", stackdir = "center", binwidth = 0.03)  + ylim(0,1) + labs(x='Block',y='Accuracy')

This looks like this:

这看起来像这样:

如何在R中的ggplot2中躲避点

Note that x (block in this case) has to be a factor for this to work.

请注意,x(在这种情况下为块)必须是此工作的一个因素。

#2


0  

If they don't have to be perfectly aligned horizontally, here's one quick way of doing it, using geom_jitter. You don't need to group by subj.

如果他们不必完全水平对齐,这里有一个快速的方法,使用geom_jitter。您不需要按subj分组。

Method 1 [Simpler]: Using geom_jitter()

ggplot(df,aes(x=block,y=acc)) + geom_jitter(position=position_jitter(0.05)) + ylim(0,1) + labs(x='Block',y='Accuracy')

Play with the jitter width for greater degree of jittering.

使用抖动宽度进行播放,以获得更大程度的抖动。

which produces:

如何在R中的ggplot2中躲避点

Method 2: Deterministically calculating the jitter value for each row

We first use aggregate to count the number of duplicated entries. Then in a new data frame, for each duplicated value, move it horizontally to the left by an epsilon distance.

我们首先使用聚合来计算重复条目的数量。然后在新的数据框中,对于每个重复的值,将其水平向左移动一个epsilon距离。

df$subj <- NULL #drop this so that aggregate works.

#a new data frame that shows duplicated values
agg.df <- aggregate(list(numdup=seq_len(nrow(df))), df, length)
agg.df$block <- as.numeric(agg.df$block) #block is not a factor
#      block  acc numdup
#1     2      0.50      2
#2     1      0.58      2
#3     2      0.58      1
#4     1      0.67      2
#...    
epsilon <- 0.02 #jitter distance

new.df <- NULL #create an expanded dataframe, with block value jittered deterministically
r <- 0
for (i in 1:nrow(agg.df)) {
  for (j in 1:agg.df$numdup[i]) {
    r <- r+1 #row counter in the expanded df
    new.df$block[r] <- agg.df$block[i]
    new.df$acc[r] <- agg.df$acc[i]
    new.df$jit.value[r] <- agg.df$block[i] - (j-1)*epsilon    
  }
}
new.df <- as.data.frame(new.df)
ggplot(new.df,aes(x=jit.value,y=acc)) + geom_point(size=2) + ylim(0,1)  + labs(x='Block',y='Accuracy') + xlim(0,3)

which produces:

如何在R中的ggplot2中躲避点

#1


1  

I think this might be what you were looking for, although no doubt you have solved it by now. Hopefully it will help someone else with the same issue.

我想这可能就是你想要的,虽然毫无疑问你现在已经解决了。希望它能帮助其他人解决同样的问题。

A simple way is to use geom_dotplot like this:

一个简单的方法是使用geom_dotplot,如下所示:

ggplot(df,aes(x=block,y=acc)) + 
geom_dotplot(binaxis = "y", stackdir = "center", binwidth = 0.03)  + ylim(0,1) + labs(x='Block',y='Accuracy')

This looks like this:

这看起来像这样:

如何在R中的ggplot2中躲避点

Note that x (block in this case) has to be a factor for this to work.

请注意,x(在这种情况下为块)必须是此工作的一个因素。

#2


0  

If they don't have to be perfectly aligned horizontally, here's one quick way of doing it, using geom_jitter. You don't need to group by subj.

如果他们不必完全水平对齐,这里有一个快速的方法,使用geom_jitter。您不需要按subj分组。

Method 1 [Simpler]: Using geom_jitter()

ggplot(df,aes(x=block,y=acc)) + geom_jitter(position=position_jitter(0.05)) + ylim(0,1) + labs(x='Block',y='Accuracy')

Play with the jitter width for greater degree of jittering.

使用抖动宽度进行播放,以获得更大程度的抖动。

which produces:

如何在R中的ggplot2中躲避点

Method 2: Deterministically calculating the jitter value for each row

We first use aggregate to count the number of duplicated entries. Then in a new data frame, for each duplicated value, move it horizontally to the left by an epsilon distance.

我们首先使用聚合来计算重复条目的数量。然后在新的数据框中,对于每个重复的值,将其水平向左移动一个epsilon距离。

df$subj <- NULL #drop this so that aggregate works.

#a new data frame that shows duplicated values
agg.df <- aggregate(list(numdup=seq_len(nrow(df))), df, length)
agg.df$block <- as.numeric(agg.df$block) #block is not a factor
#      block  acc numdup
#1     2      0.50      2
#2     1      0.58      2
#3     2      0.58      1
#4     1      0.67      2
#...    
epsilon <- 0.02 #jitter distance

new.df <- NULL #create an expanded dataframe, with block value jittered deterministically
r <- 0
for (i in 1:nrow(agg.df)) {
  for (j in 1:agg.df$numdup[i]) {
    r <- r+1 #row counter in the expanded df
    new.df$block[r] <- agg.df$block[i]
    new.df$acc[r] <- agg.df$acc[i]
    new.df$jit.value[r] <- agg.df$block[i] - (j-1)*epsilon    
  }
}
new.df <- as.data.frame(new.df)
ggplot(new.df,aes(x=jit.value,y=acc)) + geom_point(size=2) + ylim(0,1)  + labs(x='Block',y='Accuracy') + xlim(0,3)

which produces:

如何在R中的ggplot2中躲避点