Geom_dotplot () loses the trick after applying color aesthetics

I want to arrange my data in one category along the X axis, but in a different way, as in this example:

Chart 1 without coloring:

require(ggplot2) nocolor <- ggplot(mtcars, aes(x=as.factor(cyl), y=disp)) + geom_dotplot(binaxis="y", stackdir = "center") print(nocolor) 

Chart 2 with coloring:

 nododge <- ggplot(mtcars, aes(x=as.factor(cyl), y=disp, fill=as.factor(gear))) + geom_dotplot(binaxis="y", stackdir = "center") print(nododge) 

One of the problems that occurs after the introduction of color, is that the points belonging to different groups will no longer deviate from each other. This causes problems with my real data, as I get points that have the same meaning and completely hide each other.

Then I tried this, but it distorted my data:

Chart 3:

 garbled <- ggplot(mtcars, aes(x=as.factor(cyl), y=disp)) + geom_dotplot(binaxis="y", stackdir = "center", fill=as.factor(mtcars$gear)) print(garbled) 

The points deviate from each other, but the coloring is just random and not true.

I was expecting an answer to this question to solve my problem, but the coloration remained random:

Chart 4:

 graphdata <- mtcars graphdata$colorname <- as.factor(graphdata$gear) levels(graphdata$colorname) <- c("red", "blue", "black") jalapic <- ggplot(graphdata, aes(x=as.factor(cyl), y=disp)) + geom_dotplot(binaxis="y", stackdir = "center", fill=as.character(graphdata$colorname)) print(jalapic) 

Does anyone have an idea how to get points on graph number 2 in order to avoid each other, or how to fix the coloring on graphs 3 or 4? I would really appreciate any help, thanks.

+7
colors r ggplot2 fill
source share
2 answers

Using binpositions = "all" and stackgroups = TRUE :

 ggplot(mtcars, aes(x=as.factor(cyl), y=disp, fill=as.factor(gear))) + geom_dotplot(binaxis="y", stackdir = "center", binpositions="all", stackgroups=TRUE) 

gives:

enter image description here

A possible alternative is to use stackdir = "up" :

 ggplot(mtcars, aes(x=as.factor(cyl), y=disp, fill=as.factor(gear))) + geom_dotplot(binaxis="y", stackdir = "up", binpositions="all", stackgroups=TRUE) 

which gives:

enter image description here

+5
source share

Here's another option that may work better than point-to-point, depending on your needs. We draw individual points, but we separate them so that each point is visible.

In my original answer, I used position_jitterdodge , but the randomness of this method led to overlapping points and little control over the placement of the points. Below is an updated approach that directly controls the placement of points to prevent a match.

In the example below, we have cyl as the variable x, disp as the variable y and gear as the color aesthetics.

  • Inside each cyl we want the points to cyl gear .
  • In each gear we want the points with the same disp values ​​to be divided horizontally so that they do not overlap.

We do this by adding the appropriate increments to the cyl value to shift the horizontal placement of the points. We control these two parameters: dodge splits the groups of points into gear , and sep controls the separation of points inside each gear that have the same disp value. We define "similar disp values" by creating a grouping variable called dispGrp , which simply disp rounded to the nearest ten (although this, of course, can be adjusted, depending on the scale of the data, the size of the plotted points and the physical size of the graph).

To determine the x value of each point, we start with the value of cyl , add the deviation to gear and finally decompose the points in each combination of gear and dispGrp into sums that depend on the number of points in each group.

All these data conversions are performed in the dplyr chain, and the resulting data frame is then fed to ggplot . The sequence of data transformations and plotting could be generalized to a function, but only the specific case in the question was considered in the encoder below.

 library(dplyr) library(ggplot2) dodge = 0.3 # Controls the amount dodging sep = 0.05 # Within each dodge group, controls the amount of point separation mtcars %>% # Round disp to nearest 10 to identify groups of points that need to be separated mutate(dispGrp = round(disp, -1)) %>% group_by(gear, cyl, dispGrp) %>% arrange(disp) %>% # Within each cyl, dodge by gear, then, within each gear, separate points # within each dispGrp mutate(cylDodge = cyl + dodge*(gear - mean(unique(mtcars$gear))) + sep*seq(-(n()-1), n()-1, length.out=n())) %>% ggplot(aes(x=cylDodge, y=disp, fill=as.factor(gear))) + geom_point(pch=21, size=2) + theme_bw() + scale_x_continuous(breaks=sort(unique(mtcars$cyl))) 

enter image description here

Here is my original answer, using position_jitterdodge to dodge the color and then shiver in each color group to separate the overlapping dots:

 set.seed(3521) ggplot(mtcars, aes(x=factor(cyl), y=disp, fill=as.factor(gear))) + geom_point(pch=21, size=1.5, position=position_jitterdodge(jitter.width=1.2, dodge.width=1)) + theme_bw() 

enter image description here

+2
source share

All Articles