R 同时使用宽度和减淡时,几何图形栏的位置问题

R 同时使用宽度和减淡时,几何图形栏的位置问题,r,ggplot2,errorbar,R,Ggplot2,Errorbar,我有以下数据框 group1 = c('a', 'b') group2 = c('1', '1', '2', '2') mean = 1:4 sd = c(0.2, 0.3, 0.5, 0.8) df = data.frame(group1, group2, mean, sd) 我想用geom\u errorbar()在图形上绘制sd。这非常有效: ggplot(data = df, aes(x=group1, y = mean))+ geom_col(position = 'dodge'

我有以下数据框

group1 = c('a', 'b')
group2 = c('1', '1', '2', '2')
mean = 1:4
sd = c(0.2, 0.3, 0.5, 0.8)
df = data.frame(group1, group2, mean, sd)
我想用
geom\u errorbar()
在图形上绘制sd。这非常有效:

ggplot(data = df, aes(x=group1, y = mean))+
  geom_col(position = 'dodge') + 
  geom_errorbar(aes(ymin = mean - sd, ymax = mean + sd),
                position = 'dodge')
由于我想减少错误条的宽度,我运行:

ggplot(data = df, aes(x=group1, y = mean))+
  geom_col(position = 'dodge') + 
  geom_errorbar(aes(ymin = mean - sd, ymax = mean + sd), width = 0.2,
                position = 'dodge')
到目前为止还不错。但后来我想由第二组来填补空缺

ggplot(data = df, aes(x=group1, y = mean, fill = group2))+
  geom_col(position = 'dodge') + 
  geom_errorbar(aes(ymin = mean - sd, ymax = mean + sd), width = 0.2,
                position = 'dodge')
问题是误差线不再在杆的中间。我不知道为什么。我查看了文档,但没有找到关于这个问题的任何信息。我看了这个问题 这一个,但没有人解释为什么会发生这种情况。一个建议的解决方案是添加位置_减淡(0.9)


它起了作用,但我不知道它为什么起作用,也不知道它起了什么作用。有人能解释一下发生了什么事吗?为什么我不能添加width=0.2来减小错误条的宽度?道奇(0.9)的位置是什么?为什么我需要它?为什么只有在添加fill=group2时才会出现问题

TL;DR:从一开始,
position=“dodge”
(或
position=position\u dodge()
)就没有做你认为它在做的事情

潜在直觉
position_dodge
是ggplot2软件包中提供的位置调整功能之一。如果有多个元素属于不同的组占据同一位置,
position\u identity
将毫无作用,
position\u dodge
将元素水平并排放置,
position\u stack
将它们垂直放置在彼此的顶部,
position\u fill
将它们垂直放置在彼此的顶部,并按比例拉伸以适合整个绘图区域,等等

以下是不同职位调整职能部门行为的总结,来自:

请注意,要回避的元素/等必须属于不同的组。如果在绘图中明确指定了
group=
,则该值将用作分组变量,用于确定哪些元素应相互回避等。如果
aes()
中没有显式的组映射,但是有一个或多个
color=
/
fill=
/
linetype=
/等等,那么将使用所有离散变量的交互。从
?aes\u group\u order

默认情况下,组设置为所有离散对象的交互 绘图中的变量。这通常会正确地划分数据,但是 如果没有,或者在绘图中没有使用离散变量, 您需要通过映射显式定义分组结构 分组到每个组具有不同值的变量

逐块细分 让我们从你最初的情节开始。由于在情节的美学映射中没有任何类型的分组变量,
position=“dodge”
没有做任何事情

我们可以用两个geom层的
position=“identity”
来替换它(事实上,
position=“identity”
geom\u errorbar
的默认位置,因此无需详细说明),结果图是相同的

增加透明度可以明显看出,这两条线占据着同一个位置,一条在另一条的后面

我猜这个原始情节不是你真正想要的?真的很少有像这样一个酒吧在另一个酒吧后面的场景是有意义的

ggplot(data = df, aes(x=group1, y = mean))+
  geom_col(position = 'dodge') + 
  geom_errorbar(aes(ymin = mean - sd, ymax = mean + sd),
                position = 'dodge') +
  ggtitle("original plot")

ggplot(data = df, aes(x=group1, y = mean))+
  geom_col(position = "identity") + 
  geom_errorbar(aes(ymin = mean - sd, ymax = mean + sd)) +
  ggtitle("remove position dodge")

ggplot(data = df, aes(x=group1, y = mean))+
  geom_col(position = "identity", alpha = 0.5) + 
  geom_errorbar(aes(ymin = mean - sd, ymax = mean + sd)) +
  ggtitle("increase transparency")

我将跳过第二个绘图,因为添加
width=0.2
不会改变任何基本情况

在第三个图中,我们最终使用了
position=“dodge”
,因为现在有一个组变量。条形图和误差条形图根据各自的宽度相应移动。如果使用
position=“dodge”
而不是
position=position\u dodge(width=,…)
,则这是预期的行为,其中默认情况下,减淡的距离跟随几何图层的宽度,除非它被
position\u dodge(width=…)
中的特定值覆盖

如果
geom\u errorbar
层保持其默认宽度(与
geom\u col
的默认宽度相同),则两个层的元素将被相同数量的回避

ggplot(data = df, aes(x=group1, y = mean, fill = group2))+
  geom_col(position = 'dodge') + 
  geom_errorbar(aes(ymin = mean - sd, ymax = mean + sd), width = 0.2,
                position = 'dodge') +
  ggtitle("third plot")

ggplot(data = df, aes(x=group1, y = mean, fill = group2))+
  geom_col(position = 'dodge') + 
  geom_errorbar(aes(ymin = mean - sd, ymax = mean + sd), 
                position = 'dodge') +
  ggtitle("with default width")

旁注:我们知道
geom_errorbar
geom_col
具有相同的默认宽度,因为它们以相同的方式设置数据。以下代码行可在
GeomErrorbar$setup\u data
/
geomercol$setup\u data
中找到:

data$width <- data$width %||% params$width %||% (resolution(data$x, FALSE) * 0.9)
# i.e. if width is specified as one of the aesthetic mappings, use that;
#      else if width is specified in the geom layer's parameters, use that;
#      else, use 90% of the dataset's x-axis variable's resolution.        <- default value of 0.9

相关:
data$width <- data$width %||% params$width %||% (resolution(data$x, FALSE) * 0.9)
# i.e. if width is specified as one of the aesthetic mappings, use that;
#      else if width is specified in the geom layer's parameters, use that;
#      else, use 90% of the dataset's x-axis variable's resolution.        <- default value of 0.9
ggplot(data = df, aes(x=group1, y = mean, fill = group2))+
  geom_col(position = position_dodge(0.6), width = 0.5) + 
  geom_errorbar(aes(ymin = mean - sd, ymax = mean + sd), width = 0.9,
                position = position_dodge(0.6)) +
  ggtitle("another example")