Peter
Peter

Reputation: 31

Misaligned dots in ggplot2's dotplot in R

I don't understand why the dots for ID 2,6,8,10 won't align vertically like they do in 1,3,4,7,9.

The offset is affected by stackratio, but why doesn't it affect all the groups?

ggplot(sleep, 
       aes(x=ID,fill=group,y=extra))+
  geom_dotplot(binaxis = 'y',
               method="histodot",
               stackgroups = TRUE,
               binpositions="bygroup",
               stackratio=1,
               binwidth=0.1, 
               stackdir = "center",
               dotsize = 3)

plot

Another example is

ggplot(mtcars, aes(x = factor(am),fill = factor(cyl), y = mpg)) +
  geom_dotplot(binaxis = "y",stackgroups = TRUE, stackdir = "center", binpositions="all")

Here stackgroups = TRUE makes everything offset weirdly.

img

Can something be done here, or is there another way to get the samme?

Upvotes: 2

Views: 2696

Answers (2)

ogustavo
ogustavo

Reputation: 586

I cannot tell you what's the issue when using the geom_dotplot function, but you can get what you want by using geom_point and the option position = position_dodge2(). Inside the function position_dodge2() you can use width to control the position of each point. See the full code below:

library(ggplot2)

ggplot(sleep, 
       aes(x=ID,fill=group,y=extra))+
  geom_point(
    size=3,
    pch = 21,
    position = position_dodge2(width=c(rep(0.00001,4),
                                       0.2,
                                       rep(0.00001,5)))
  ) + 
  scale_y_continuous(limits = c(-2,6)) +
  theme_classic() + 
  theme(panel.grid.major.x = element_line(color="gray",
                                          linetype = "dashed"))

The result:

enter image description here


Update

We can have different alignments within the same X. For instance, when ID=1 I can move the point for group 2 while maintaining the point for group 1:

enter image description here

Code:

library(ggplot2)

ggplot(sleep, 
       aes(x=ID,fill=group,y=extra))+
  geom_point(
    size=3,
    pch = 21,
    position = position_dodge2(width=c(0.7,
                                       rep(0.00001,3),
                                       0.2,
                                       rep(0.00001,5),
                                       0.00001,
                                       rep(0.00001,3),
                                       0.2,
                                       rep(0.00001,5)))
  ) + 
  scale_y_continuous(limits = c(-2,6)) +
  theme_classic() + 
  theme(panel.grid.major.x = element_line(color="gray",
                                          linetype = "dashed"))

Upvotes: 0

Peter
Peter

Reputation: 31

It seems that geom_dotplot calculates "dodge" positions as if all the dots were in one group and then plots them in each group.

I found work around. Here i make a plot and color the dots myself. This ggplot can not make a legend for, so I make another plot that was the right legend. Then use plot_grid to make my final plot. It is important to setkey right, or the plot will be colored incorrect.

mycars <- as.data.table(mtcars)
mycars[cyl=="4",mycol:="red"][cyl=="6",mycol:="green"][cyl=="8",mycol:="blue"]
setkey(mycars,am,mpg)
myplot <- ggplot(mycars, aes(x = factor(am), y = mpg)) +
  geom_dotplot(binaxis = "y",
               fill=mycars$mycol,
               stackratio=1,
               binwidth=0.7, drop=FALSE,
               stackdir = "center",
               dotsize = 1)

lplot <- ggplot(mtcars, aes(x = factor(am),fill = factor(cyl), y = mpg))+
  geom_dotplot(binaxis = "y",stackgroups = TRUE)+
  scale_fill_manual(values=c("red","green", "blue"))
mylegend <- get_legend(lplot)

plot_grid(myplot,mylegend,ncol=2,rel_widths =  c(6,1))

Plot

Upvotes: 1

Related Questions