文档没有解释这个width论点到底是什么
默认值为width = NULL,但试验和错误显示width = 0.9似乎产生默认效果(请参阅postscript).但是,我找不到ggplot2源代码中设置此类默认值的位置.从而,
ggplot2代码中实现默认闪避吗?问题的精神是允许ggplot2用户在width没有反复试验的情况下找到合适的值.PS:
ggplot(data = df) +
  geom_bar(aes(x, y, fill = factor(group)), 
           position = position_dodge(), stat = "identity")
ggplot(data = df) +
  geom_bar(aes(x, y, fill = factor(group)), 
           position = position_dodge(0.9), stat = "identity")
Hen*_*rik 66
我将首先简要回答你的三个主要问题.然后,我将通过几个例子来更全面地说明答案.
width,但依赖于默认值position_dodge(width = NULL)(或仅position = "dodge"),则使用的闪避宽度是要躲避的元素的数据单位的实际宽度.
我相信你的第四个问题对于SO来说过于宽泛.请参考的代码collide和dodge和,如果需要的话,问一个新的,更具体的问题.
基于元件的躲避宽度(连同其原始水平位置和堆叠的元件的数量),x计算每个元件的新中心位置()和新宽度(xmin,xmax位置).元素水平移动到足够远,不与相邻元素重叠.显然,宽元素需要比窄元素更多地移位以避免重叠.
为了更好地感受一般的躲避和width特别是论证的使用,我展示了一些例子.我们从一个简单的躲避条形图开始,默认躲避; 我们可以使用任何一个position = "dodge"或更明确的position = position_dodge(width = NULL)  
# some toy data
df <- data.frame(x = 1,
                 y = 1,
                 grp = c("A", "B"))
p <- ggplot(data = df, aes(x = x, y = y, fill = grp)) + theme_minimal()
p + geom_bar(stat = "identity",
             position = "dodge")
           # which is the same as:
           # position = position_dodge(width = NULL))
因此,(1)谁的width是它在position_dodge与(2)是什么单位?
在?position_dodge我们可以看到:
width:闪躲宽度,当不同的各个元件的宽度
因此,如果我们使用默认值 width,即NULL,躲避计算基于各个元素的宽度.
因此,对你的第一个问题" 它指定的宽度是多少?"的一个简单回答是:各个元素的宽度.
但当然我们想知道,"单个元素的宽度"是什么?让我们从酒吧开始吧.来自?geom_bar:
width:条宽.默认情况下,设置为数据分辨率的90%
出现了一个新问题:决议是什么?我们来看看?ggplot2::resolution:
分辨率是相邻值之间的最小非零距离.如果只有一个唯一值[如我们的示例中所示],则将分辨率定义为1.
我们试图:
resolution(df$x)
# [1] 1
因此,此示例中的默认条宽度为 0.9 * 1 = 0.9
我们可以通过查看ggplot使用的数据用于渲染图上的条来检查这一点ggplot_build.我们创建了一个带有堆积条形图的绘图对象,其中包含默认宽度的条形图.
p2 <- p +
  geom_bar(stat = "identity",
           position = "stack")
对象中的相关插槽$data是一个列表,其中包含绘图中每个图层的一个元素,其顺序与它们在代码中出现的顺序相同.在这个例子中,我们只有一个图层,即geom_bar让我们看看第一个插槽:
ggplot_build(p2)$data[[1]]
#      fill x y label PANEL group ymin ymax xmin xmax colour size linetype alpha
# 1 #F8766D 1 1     A     1     1    0    1 0.55 1.45     NA  0.5        1    NA
# 2 #00BFC4 1 2     B     1     2    1    2 0.55 1.45     NA  0.5        1    NA
每行包含"绘制"单个条形的数据.如您所见,条的宽度均为0.9(xmax - xmin = 0.9).因此,用于计算新的躲避位置和宽度的堆叠条的宽度是0.9.  
在前面的示例中,我们使用默认的条形宽度和默认的闪避宽度.现在让我们使条形略宽于上面的默认宽度(0.9).使用width参数将(堆叠)条宽geom_bar显式设置为例如1.我们尝试使用与上面相同的闪避宽度(position_dodge(width = 0.9)).因此,虽然我们已经设定了实际条宽为1,闪避的计算是由仿佛酒吧是0.9宽.让我们看看发生了什么:
p +
  geom_bar(stat = "identity", width = 1, position = position_dodge(width = 0.9), alpha = 0.8)
p
杆是重叠的,因为ggplot水平移动杆就好像它们具有0.9的(堆叠的)宽度(设置在position_dodge),而实际上杆具有1的宽度(设置在geom_bar).
如果我们使用默认的减淡值,则根据设置的条宽度精确水平移动条:
p +
  geom_bar(stat = "identity", width = 1, position = "dodge", alpha = 0.8)
                                   # or: position = position_dodge(width = NULL)
接下来我们尝试使用添加一些文本到我们的情节geom_text.我们从默认躲避width(即position_dodge(width = NULL))开始,即躲避基于默认元素大小.
p <- ggplot(data = df, aes(x = x, y = y, fill = grp, label = grp)) + theme_minimal()
p2 <- p +
  geom_bar(stat = "identity", position = position_dodge(width = NULL)) +
  geom_text(size = 10, position = position_dodge(width = NULL))
                  # or position = "dodge"    
p2
# Warning message:
#  Width not defined. Set with `position_dodge(width = ?)`
文本的躲避失败了.警告信息怎么样?"宽度未定义?".有点神秘.我们需要查看以下详细信息部分?geom_text:
请注意,文本元素的"宽度"和"高度"为0,因此默认情况下堆叠和躲避文本不起作用[...]显然,标签确实有高度和宽度,但它们是物理单位,而不是数据单位.
因此geom_text,各个元素的宽度为零.这也是第二个问题的第一个"官方ggplot参考":单位width是数据单位.
让我们看看用于渲染图上文本元素的数据:
ggplot_build(p3)$data[[2]]
#       fill x y label PANEL group xmin xmax ymax colour size angle hjust vjust alpha family fontface lineheight
# 1 #F8766D 1 1     A     1     1    1    1    1  black   10     0   0.5   0.5    NA               1        1.2
# 2 #00BFC4 1 1     B     1     2    1    1    1  black   10     0   0.5   0.5    NA               1        1.2
的确,xmin == xmax; 因此,数据单元中文本元素的宽度为零.
如何实现宽度为零的文本元素的正确躲避?来自以下示例?geom_text:
ggplot2不知道你想给标签提供与条形码相同的虚拟宽度[...]所以告诉它:
因此,为了使闪避在计算新位置时使用与geom_text元素相同的宽度geom_bar,我们需要将文本元素的"数据单位的虚拟闪避宽度" 设置为与条形相同的宽度.我们使用width参数position_dodge来将文本元素的虚拟宽度设置为0.9(即上例中的条宽):
p2 <- p +
  geom_bar(stat = "identity", position = position_dodge(width = NULL)) +
  geom_text(position = position_dodge(width = 0.9), size = 10)
检查用于渲染的数据geom_text:
ggplot_build(p2)$data[[2]]
#      fill     x y label PANEL group xmin xmax ymax colour size angle hjust vjust alpha family fontface lineheight
# 1 #F8766D 0.775 1     A     1     1 0.55 1.00    1  black   10     0   0.5   0.5    NA               1        1.2
# 2 #00BFC4 1.225 1     B     1     2 1.00 1.45    1  black   10     0   0.5   0.5    NA               1        1.2
现在文本元素具有在数据单元的宽度:xmax - xmin = 0.9,即,在相同的宽度条.因此,现在将进行闪避计算,就好像文本元素具有一定的宽度,这里为0.9.渲染情节:
p2
文本被正确躲闪!
与文本类似,点(geom_point)和误差条(例如geom_errorbar)的数据单位宽度为零.因此,如果你需要躲避这些元素,你需要指定一个相关的虚拟宽度,然后根据闪避计算.参见例如以下的示例部分?geom_errorbar:
如果你想躲避条形和错误条,你需要手动指定躲避宽度[...]因为条形和错误条具有不同的宽度,我们需要指定我们躲避的对象有多宽
以下是连续刻度上具有多个x值的示例:
df <- data.frame(x = rep(c(10, 20, 50), each = 2),
                 y = 1,
                 grp = c("A", "B"))
假设我们希望创建一个躲避的条形图,每个条形图上方都有一些文字.首先,只使用默认的躲避宽度检查一个条形图:
p <- ggplot(data = df, aes(x = x, y = y, fill = grp, label = grp)) + theme_minimal()
p + 
  geom_bar(stat = "identity", position = position_dodge(width = NULL))
                         # or position = "dodge"
它按预期工作.然后,添加文本.我们尝试将文本元素的虚拟宽度设置为与上面示例中的条形宽度相同,即我们"猜测"条形仍然具有0.9的宽度,并且我们需要躲避文本元素,就好像它们的宽度也是0.9:
p +
  geom_bar(stat = "identity", position = "dodge") +
  geom_text(position = position_dodge(width = 0.9), size = 10)
显然,条形的躲避计算现在基于不同的宽度而不是0.9,并且将文本元素的虚拟宽度设置为0.9是一个糟糕的猜测.那么这里的条宽是多少?同样,条宽为"[b] y默认,设置为数据分辨率的90%".检查分辨率:
resolution(df$x)
# [1] 10
因此,现在计算其新的躲避位置的(默认堆叠)条的宽度0.9 * 10 = 9.因此,为了躲避条形图及其相应的文本"手拉手",我们需要将文本元素的虚拟宽度设置为9:
p +
  geom_bar(stat = "identity", position = "dodge") +
  geom_text(position = position_dodge(width = 9), size = 10)
在我们的最后一个例子中,我们有一个分类的x轴,只是上面x值的'因子版本'.
df <- data.frame(x = factor(rep(c(10, 20, 50), each = 2)),
                 y = 1,
                 grp = c("A", "B"))
在R中,因子在内部是一组具有"levels"属性的整数代码.来自?resolution:
如果x是整数向量,则假定它表示离散变量,并且分辨率为1.
到目前为止,我们知道当resolution为1时,条形的默认宽度为0.9.因此,上一个绝对x轴,默认宽度geom_bar是0.9,并且我们需要设置在闪避width为geom_text相应:
ggplot(data = df, aes(x = x, y = y, fill = grp, label = grp)) +
  theme_minimal() +
  geom_bar(stat = "identity", position = "dodge") +
  # or: position = position_dodge(width = NULL)
  # or: position = position_dodge(width = 0.9)
  geom_text(position = position_dodge(width = 0.9), size = 10)