应用色彩美学后,geom_dotplot()失去闪避

时间:2023-02-09 21:43:08

I want to organize my data by one category on the X-axis, but color it by another category as in this example:

我想在X轴上按一个类别组织我的数据,但是按照另一个类别对其进行着色,如下例所示:

Graph 1, without coloring:

图1,没有着色:

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

Graph 2, with coloring:

图2,带着色:

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

One problem that occurs after introducing coloring is that the dots belonging to different groups wont dodge one another anymore. This causes problems with my real data, as I get dots that happen to have the same value and completely obscure one another.

引入着色后发生的一个问题是属于不同组的点不再相互闪避。这会导致我的实际数据出现问题,因为我得到的点恰好具有相同的值并且完全相互模糊。

Then I tried this, but it garbled my data:

然后我尝试了这个,但它弄乱了我的数据:

Graph 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 dots dodge one another, but the the coloring is just random and is not true to the actual data.

点相互闪避,但着色只是随机的,并不符合实际数据。

I expected the answer to this question to solve my problem, but the coloring remained random:

我期望这个问题的答案可以解决我的问题,但着色仍然是随机的:

Graph 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 the dots in Graph #2 to dodge one another, or how to fix the coloring in graphs 3 or 4? I would really appreciate any help, thanks.

有没有人知道如何让图#2中的点相互躲闪,或者如何修复图3或图4中的着色?我非常感谢任何帮助,谢谢。

2 个解决方案

#1


5  

Using binpositions = "all" and stackgroups = TRUE:

使用binpositions =“all”和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:

应用色彩美学后,geom_dotplot()失去闪避

A possible alternative is using stackdir = "up":

可能的替代方法是使用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:

应用色彩美学后,geom_dotplot()失去闪避

#2


2  

Here's another option that might work better than a dotplot, depending on your needs. We plot the individual points, but we separate them so that each point is visible.

这是另一个可能比dotplot更好的选项,具体取决于您的需求。我们绘制各个点,但我们将它们分开,以便每个点都可见。

In my original answer, I used position_jitterdodge, but the randomness of that method resulted in overlapping points and little control over point placement. Below is an updated approach that directly controls point placement to prevent overlap.

在我的原始答案中,我使用了position_jitterdodge,但该方法的随机性导致重叠点并且对点放置几乎没有控制。以下是一种更新方法,可直接控制点位置以防止重叠。

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

在下面的例子中,我们将cyl作为x变量,disp作为y变量,齿轮作为颜色美学。

  • Within each cyl, we want points to be dodged by gear.
  • 在每个气缸内,我们希望通过齿轮躲避点。

  • Within each gear we want points with similar values of disp to be separated horizontally so that they don't overlap.
  • 在每个齿轮内,我们希望具有相似disp值的点水平分离,以使它们不重叠。

We do this by adding appropriate increments to the value of cyl in order to shift the horizontal placement of the points. We control this with two parameters: dodge separates groups of points by gear, while sep controls the separation of points within each gear that have similar values of disp. We determine "similar values of disp" by creating a grouping variable called dispGrp, which is just disp rounded to the nearest ten (although this can, of course, be adjusted, depending on the scale of the data, size of the plotted points, and physical size of the graph).

我们通过向cyl的值添加适当的增量来实现这一点,以便移动点的水平放置。我们用两个参数控制它:闪避通过齿轮分离点组,而sep控制每个齿轮内具有相似值disp的点的分离。我们通过创建一个名为dispGrp的分组变量来确定“disp的相似值”,这个变量只是四舍五入到最接近的十(当然,这可以调整,具体取决于数据的规模,绘制点的大小,和图的物理尺寸)。

To determine the x-value of each point, we start with the value of cyl, add dodging by gear, and finally spread the points within each gear and dispGrp combination by amounts that depend on the number of points within the each grouping.

为了确定每个点的x值,我们从cyl的值开始,按齿轮添加躲避,最后在每个齿轮和dispGrp组合中扩展点数,这取决于每个分组中的点数。

All of these data transformations are done within a dplyr chain, and the resulting data frame is then fed to ggplot. The sequence of data transformations and plotting could be generalized into a function, but the code below addressed only the specific case in the question.

所有这些数据转换都在dplyr链中完成,然后将得到的数据帧提供给ggplot。数据转换和绘图的顺序可以推广到一个函数中,但下面的代码只解决了问题中的特定情况。

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)))

应用色彩美学后,geom_dotplot()失去闪避

Here's my original answer, using position_jitterdodge to dodge by color and then jitter within each color group to separate overlapping points:

这是我的原始答案,使用position_jitterdodge按颜色躲闪,然后在每个颜色组内抖动以分隔重叠点:

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()

应用色彩美学后,geom_dotplot()失去闪避

#1


5  

Using binpositions = "all" and stackgroups = TRUE:

使用binpositions =“all”和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:

应用色彩美学后,geom_dotplot()失去闪避

A possible alternative is using stackdir = "up":

可能的替代方法是使用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:

应用色彩美学后,geom_dotplot()失去闪避

#2


2  

Here's another option that might work better than a dotplot, depending on your needs. We plot the individual points, but we separate them so that each point is visible.

这是另一个可能比dotplot更好的选项,具体取决于您的需求。我们绘制各个点,但我们将它们分开,以便每个点都可见。

In my original answer, I used position_jitterdodge, but the randomness of that method resulted in overlapping points and little control over point placement. Below is an updated approach that directly controls point placement to prevent overlap.

在我的原始答案中,我使用了position_jitterdodge,但该方法的随机性导致重叠点并且对点放置几乎没有控制。以下是一种更新方法,可直接控制点位置以防止重叠。

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

在下面的例子中,我们将cyl作为x变量,disp作为y变量,齿轮作为颜色美学。

  • Within each cyl, we want points to be dodged by gear.
  • 在每个气缸内,我们希望通过齿轮躲避点。

  • Within each gear we want points with similar values of disp to be separated horizontally so that they don't overlap.
  • 在每个齿轮内,我们希望具有相似disp值的点水平分离,以使它们不重叠。

We do this by adding appropriate increments to the value of cyl in order to shift the horizontal placement of the points. We control this with two parameters: dodge separates groups of points by gear, while sep controls the separation of points within each gear that have similar values of disp. We determine "similar values of disp" by creating a grouping variable called dispGrp, which is just disp rounded to the nearest ten (although this can, of course, be adjusted, depending on the scale of the data, size of the plotted points, and physical size of the graph).

我们通过向cyl的值添加适当的增量来实现这一点,以便移动点的水平放置。我们用两个参数控制它:闪避通过齿轮分离点组,而sep控制每个齿轮内具有相似值disp的点的分离。我们通过创建一个名为dispGrp的分组变量来确定“disp的相似值”,这个变量只是四舍五入到最接近的十(当然,这可以调整,具体取决于数据的规模,绘制点的大小,和图的物理尺寸)。

To determine the x-value of each point, we start with the value of cyl, add dodging by gear, and finally spread the points within each gear and dispGrp combination by amounts that depend on the number of points within the each grouping.

为了确定每个点的x值,我们从cyl的值开始,按齿轮添加躲避,最后在每个齿轮和dispGrp组合中扩展点数,这取决于每个分组中的点数。

All of these data transformations are done within a dplyr chain, and the resulting data frame is then fed to ggplot. The sequence of data transformations and plotting could be generalized into a function, but the code below addressed only the specific case in the question.

所有这些数据转换都在dplyr链中完成,然后将得到的数据帧提供给ggplot。数据转换和绘图的顺序可以推广到一个函数中,但下面的代码只解决了问题中的特定情况。

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)))

应用色彩美学后,geom_dotplot()失去闪避

Here's my original answer, using position_jitterdodge to dodge by color and then jitter within each color group to separate overlapping points:

这是我的原始答案,使用position_jitterdodge按颜色躲闪,然后在每个颜色组内抖动以分隔重叠点:

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()

应用色彩美学后,geom_dotplot()失去闪避