本文介绍了position_dodge中的宽度参数是多少?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! $ b $所以(1)谁是宽度是在 position_dodge 和(2)单位是什么? 在?position_dodge 我们可以阅读: 出现一个新问题:分辨率是多少?让我们来看看?ggplot2 :: resolution : $ b 我们尝试: 分辨率(df $ x)#[1] 1 因此,本例中的默认栏宽度是 0.9 * 1 = 0.9 我们可以通过查看数据 ggplot 用来使用 ggplot_build 。我们用一个堆叠的barplot创建一个绘图对象,并带有默认宽度的条。 p2 geom_bar(stat =identity, position =stack ) 对象中的相关位置是 $ data ,它是图中每个图层的一个元素的列表,其顺序与它们在代码中的显示顺序相同。在这个例子中,我们只有一层,即 geom_bar ,所以让我们看看第一个槽: ggplot_build(p2)$ data [[1]] #fill xy label PANEL group ymin ymax xmin xmax color 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)稍宽。在 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( set ,位于 geom_bar )。 如果我们使用默认的闪避值,则会根据 p + geom_bar(stat =identity,width = 1, position =dodge,alpha = 0.8)#或:position = position_dodge(width = NULL) 接下来,我们尝试使用 geom_text 添加一些文本到我们的图中。我们从默认闪避宽度(ie position_dodge(width = NULL))开始,即闪避是基于默认元素尺寸。 pre $ p p2 geom_bar(stat =identity,position = position_dodge(width = NULL))+ geom_text(size = 10,position = position_dodge(width = NULL))#或position =闪避 p2 #警告信息:#未定义宽度。设置为`position_dodge(width =?)` 文字的闪避失败。那么警告信息呢? 宽度未定义?。有点神秘。我们需要查阅的详细信息部分?geom_text : $ b 因此对于 geom_text ,各个元素的宽度为零。这也是您的第二个问题的第一个'官方ggplot参考': width 的单位在数据单位 。 让我们看看用于渲染图上文本元素的数据: ggplot_build(p3)$ data [[2]] #填充xy标签PANEL组xmin xmax ymax颜色大小angle hjust vjust alpha family fontface lineheight #1#F8766D 1 1 A 1 1 1 1 1黑色10 0 0.5 0.5 NA 1 1.2 #2#00BFC4 1 1 B 1 2 1 1 1黑色10 0 0.5 0.5 NA 1 1.2 确实, xmin == xmax ;因此,数据单元中文本元素的宽度为零。 如何实现宽度为零的文本元素的正确闪避?从中的例子:因此,为了让闪避使用在计算新位置时, geom_text 元素的宽度与 geom_bar 元素的宽度相同,我们需要 set 文本元素的数据单位的虚拟闪避宽度与条形的宽度相同。我们使用 width 参数 position_dodge 来将文本元素的虚拟宽度设置为 0.9(即上例中的条宽): p2 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]] #填充xy标签PANEL组xmin xmax ymax颜色大小angle hjust vjust alpha family fontface lineheight #1#F8766D 0.775 1 A 1 1 0.55 1.00 1黑色10 0 0.5 0.5 NA 1 1.2 #2#00BFC4 1.225 1 B 1 2 1.00 1.45 1黑色10 0 0.5 0.5 NA 1 1.2 现在文本元素具有以数据为单位的宽度: xmax - xmin = 0.9 ,即t他和酒吧的宽度一样。因此,闪避计算现在将被制作为,就好像文本元素具有一定的宽度,这里是0.9。渲染图: p2 文字正确闪避! 与文本类似,点( geom_point )和误差线(例如 geom_errorbar )为零。因此,如果您需要躲避这些元素,则需要指定一个相关的虚拟宽度,然后根据这些宽度进行闪避计算。见例如的示例部分?geom_errorbar : 下面是一个连续的x值示例: df y = 1, grp = c(A, B)) 假设我们希望创建一个闪动的条形图,每个条上方都有一些文字。首先,仅使用默认的避让宽度检查barplot: p p + geom_bar(stat =identity,position = position_dodge(width = NULL)) #或position =闪避 它按预期工作。然后,添加文本。我们尝试将文本元素的虚拟宽度设置为与上例中的横条宽度相同,即我们猜测横条宽度仍为0.9,并且我们需要避开文本元素 as well 它们的宽度也是0.9: p + geom_bar(stat = identity,position =dodge)+ geom_text(position = position_dodge(width = 0.9),size = 10) 显然,这些酒吧的闪避计算现在基于不同的宽度超过0.9并且将文本元素的虚拟宽度设置为0.9是一个糟糕的猜测。那么在这里是栏宽?同样,条宽为默认设置为数据分辨率的90%。检查分辨率: 分辨率(df $ x)#[1] 10 $ b因此,计算其 新的闪避位置的(默认堆叠)条的宽度,现在 0.9 * 10 = 9 。因此,为了避免条和它们相应的文本'手拉手',我们需要设置文本元素的虚拟宽度为9: p + geom_bar(stat =identity,position =dodge)+ geom_text(position = position_dodge(width = 9),size = 10) 在我们的最后一个例子中,我们有一个分类x轴,就是上面x值的一个因子版本。 y = 1, grp = c(A,B)) 具有levels属性的整数代码。并从?resolution :现在,我们知道当分辨率是1,条的默认宽度是0.9。因此,在分类x轴上, geom_bar 的默认宽度为0.9,我们需要设置闪烁宽度因为: 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)#或:position = position_dodge(width = 0.9) geom_text(position = position_dodge(width = 0.9),size = 10) The documentation does not explain what exactly is this width argumentWhose width does it specify?What's the "unit"?What's the default value?The default value is width = NULL, but trial and error shows that width = 0.9 seems to produce the default effect (see postscript). However, I couldn't find where such default value is set in ggplot2 source code. Thus,Could you explain how the default dodge is implemented in ggplot2 code?The spirit of the question is to allow ggplot2 users to find appropriate width values without trial and error.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") 解决方案 I will first give very brief answers to your three main questions. Then I walk through several examples to illustrate the answers more thoroughly.Whose width does it specify?The width of the elements to be dodged.What's the "unit"?The actual or the virtual width in data units of the elements to be dodged.What's the default value?If you don't set the dodging width explicitly, but rely on the default value, position_dodge(width = NULL) (or just position = "dodge"), the dodge width which is used is the actual width in data units of the element to be dodged.I believe your fourth question is too broad for SO. Please refer to the code of collide and dodge and, if needed, ask a new, more specific question.Based on the dodge width of the element (together with its original horizontal position and the number of elements which are stacked), new center positions (x) of each element, and new widths (xmin, xmax positions) are calculated. The elements are shifted horizontally just far enough not to overlap with adjacent elements. Obviously, wide elements needs to be shifted more than narrow elements in order to avoid overlap.To get a better feeling for dodging in general and the use of the width argument in particular, I show some examples. We start with a simple dodged bar plot, with default dodging; we can use either position = "dodge" or the more explicit position = position_dodge(width = NULL) # some toy datadf <- 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))So (1) who's width is it in position_dodge and (2) what is the unit?In ?position_dodge we can read:Thus, if we use the default width, i.e. NULL, the dodging calulations are base on the width of the individual elements.So a trivial answer to your first question, "Whose width does it specify?, would be: the width of the individual elements.But of course we then wonder, what is "the width of the individual elements"? Let's start with the bars. From ?geom_bar: A new question arises: what is resolution? Let's check ?ggplot2::resolution:We try:resolution(df$x)# [1] 1Thus, the default bar width in this example is 0.9 * 1 = 0.9We may check this by looking at the data ggplot uses to render the bars on the plot using ggplot_build. We create a plot object with a stacked barplot, with bars of default width. p2 <- p + geom_bar(stat = "identity", position = "stack")The relevant slot in the object is $data, which is a list with one element for each layer in the plot, in the same order as they appear in the code. In this example, we only have one layer, i.e. geom_bar, so let's look at the first slot: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 NAEach row contains data to 'draw' a single bar. As you can see, the width of the bars are all 0.9 (xmax - xmin = 0.9). Thus, the width of the stacked bars, to be used in the calculations of the new dodged positions and widths, is 0.9.In the previous example, we used the default bar width, together with the default dodge width. Now let's make the bar slightly wider than the default width above (0.9). Use the width argument in geom_bar to explicitly set the (stacked) bar width to e.g 1. We try to use the same dodge width as above (position_dodge(width = 0.9)). Thus, while we have set the actual bar width to be 1, the dodge calculations are made as if the bars are 0.9 wide. Let's see what happens:p + geom_bar(stat = "identity", width = 1, position = position_dodge(width = 0.9), alpha = 0.8)pThe bars are overlapping because ggplot shifts bars horizontally as if they have a (stacked) width of 0.9 (set in position_dodge), while in fact the bars have a width of 1 (set in geom_bar).If we use the default dodge values, the bars are shifted horizontally accurately according to the set bar width: p + geom_bar(stat = "identity", width = 1, position = "dodge", alpha = 0.8) # or: position = position_dodge(width = NULL)Next we try to add some text to our plot using geom_text. We start with the default dodging width (i.e. position_dodge(width = NULL)), i.e. dodging is based on default element size. 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 = ?)`The dodging of the text fails. What about the warning message? "Width is not defined?". Slightly cryptic. We need to consult the Details section of ?geom_text:So for geom_text, the width of the individual elements is zero. This is also the first 'official ggplot reference' to your second question: The unit of width is in data units.Let's look at the data used to render the text elements on the plot: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.2Indeed, xmin == xmax; Thus, the width of the text element in data units is zero.How to achieve correct dodging of the text element with width zero? From Examples in ?geom_text:Thus, in order for dodge to use the same width for geom_text elements as for the geom_bar elements when new positions are calculated, we need to set "the virtual dodging width in data units" of the text element to the same width as the bars. We use the width argument of position_dodge to set the virtual width of the text element to 0.9 (i.e. the bar width in the example above):p2 <- p + geom_bar(stat = "identity", position = position_dodge(width = NULL)) + geom_text(position = position_dodge(width = 0.9), size = 10)Check the data used for rendering 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.2Now the text elements have a width in data units: xmax - xmin = 0.9, i.e. the same width as the bars. Thus, the dodge calculations will now be made as if the text elements have a certain width, here 0.9. Render the plot:p2The text is dodged correctly!Similar to text, the width in data units of points (geom_point) and error bars (e.g. geom_errorbar) is zero. Thus, if you need to dodge such elements, you need to specify a relevant virtual width, on which dodge calculations then are based. See e.g. the Example section of ?geom_errorbar:Here is an example with several x values on a continuous scale:df <- data.frame(x = rep(c(10, 20, 50), each = 2), y = 1, grp = c("A", "B"))Let's say we wish to create a dodged barplot with some text above each bar. First, just check a barplot only using the default dodging width: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"It works as expected. Then, add the text. We try to set the virtual width of the text element to the same as the width of the bars in the example above, i.e. we "guess" that the bars still have width of 0.9, and that we need to dodge the text elements as if they have a width of 0.9 as well:p + geom_bar(stat = "identity", position = "dodge") + geom_text(position = position_dodge(width = 0.9), size = 10)Clearly, the dodging calculation for the bars is now based on a different width than 0.9 and setting the virtual width to 0.9 for the text element was a bad guess. So what is bar width here? Again, bar width is "[b]y default, set to 90% of the resolution of the data". Check the resolution:resolution(df$x)# [1] 10Thus, the width of the (default stacked) bars, on which their new, dodged position is calculated, is now 0.9 * 10 = 9. Thus, to dodge the bars and their corresponding text 'hand in hand', we need to set the virtual width of also the text elements to 9: p + geom_bar(stat = "identity", position = "dodge") + geom_text(position = position_dodge(width = 9), size = 10)In our final example, we have a categorical x axis, just a 'factor version' of the x values from above.df <- data.frame(x = factor(rep(c(10, 20, 50), each = 2)), y = 1, grp = c("A", "B"))In R, factors are internally a set of integer codes with a "levels" attribute. And from ?resolution:By now, we know that when resolution is 1, the default width of the bars is 0.9. Thus, on a categorical x axis, the default width for geom_bar is 0.9, and we need to set the dodging width for geom_text accordingly: 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) 这篇关于position_dodge中的宽度参数是多少?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
07-31 02:20