ggplot2 geom_bar位置失败

时间:2018-05-30 11:55:53

标签: r ggplot2 histogram stacked

我在..count..中使用geom_bar转换并获得警告 当某些类别的计数很少时, position_stack需要不重叠的x区间

最好使用一些模拟数据解释(我的数据涉及方向和风速,我保留与之相关的名称)

#make data
set.seed(12345)
FF=rweibull(100,1.7,1)*20  #mock speeds
FF[FF>60]=59
dir=sample.int(10,size=100,replace=TRUE) # mock directions

#group into speed classes
FFcut=cut(FF,breaks=seq(0,60,by=20),ordered_result=TRUE,right=FALSE,drop=FALSE)

# stuff into data frame & plot
df=data.frame(dir=dir,grp=FFcut)
ggplot(data=df,aes(x=dir,y=(..count..)/sum(..count..),fill=grp)) + geom_bar()

这很好用,结果图显示了根据速度分组的方向的频率。具有最小计数的速度等级(此处为“[40,60”“)将具有5个计数是相关的。 Three categories of size 20 each

然而,更多速度等级会导致警告。例如,

FFcut=cut(FF,breaks=seq(0,60,by=15),ordered_result=TRUE,right=FALSE,drop=FALSE)

具有最少计数的速度等级(现在为“[45,60)”)将只有3个计数,而ggplot2将警告

position_stack需要不重叠的x区间

并且该图将显示沿x轴展开的此类别中的数据。 Four categories of size 15 each. Now the last one with three elements is not added on top of the corresponding bar 似乎5是一个组正常工作的最小大小。

我很想知道这是stat_bin中的一个功能或错误(geom_bar正在使用)还是我只是在滥用geom_bar

此外,任何建议如何解决这个问题将不胜感激。

真诚

2 个答案:

答案 0 :(得分:5)

这是因为df$dir是数字,因此ggplot对象假设一个连续的x轴,而美学参数group基于唯一已知的离散变量(fill = grp)。 / p>

因此,当dir中的grp = [45,60)值不是很多时,ggplot会对每个条的宽度感到困惑。如果我们将情节分成不同的方面,这在视觉上会变得更加明显:

ggplot(data=df,
            aes(x=dir,y=(..count..)/sum(..count..),
                fill = grp)) + 
  geom_bar() + 
  facet_wrap(~ grp)

facet view

> for(l in levels(df$grp)) print(sort(unique(df$dir[df$grp == l])))
[1]  1  2  3  4  6  7  8  9 10
[1]  1  2  3  4  5  6  7  8  9 10
[1]  2  3  4  5  7  9 10
[1] 2 4 7

我们还可以手动检查排序的df$dir值之间的最小差异对于前三个grp值是1,而对于最后一个值是2。因此,默认条宽度更宽。

以下解决方案都应达到相同的效果:

<强> 1。为geom_bar() 中的所有群组明确指定相同的条形宽度:

ggplot(data=df,
       aes(x=dir,y=(..count..)/sum(..count..),
           fill = grp)) + 
  geom_bar(width = 0.9)

<强> 2。将dir转换为分类变量,然后再将其传递给aes(x = ...)

ggplot(data=df,
       aes(x=factor(dir), y=(..count..)/sum(..count..),
           fill = grp)) + 
  geom_bar()

第3。指定group参数应基于df$dir和&amp; df$grp

ggplot(data=df,
       aes(x=dir,
           y=(..count..)/sum(..count..),
           group = interaction(dir, grp),
           fill = grp)) + 
  geom_bar()

plot

答案 1 :(得分:1)

这并没有直接解决问题,因为我也没有得到重叠值的结果,但它是一个dplyr驱动的解决方法,无论如何可能会变得更灵活。 / p>

不是依靠geom_bar来获取削减因子并通过..count../sum(..count..)为您提供分享,您可以轻松地预先自己计算这些份额,然后绘制条形图。我个人喜欢对我的数据进行这种控制,以及我正在绘制的内容。

首先,我将dirFF放入数据框/ tbl_df,然后剪切FF。然后count允许我按dirgrp对数据进行分组,并计算这两个变量的每个组合的观察数,然后计算每个n的份额n的总和。我正在使用geom_col,就像geom_bar,但当y中有aes值时。

library(tidyverse)

set.seed(12345)
FF <- rweibull(100,1.7,1) * 20  #mock speeds
FF[FF > 60] <- 59
dir <- sample.int(10, size = 100, replace = TRUE) # mock directions

shares <- tibble(dir = dir, FF = FF) %>%
  mutate(grp = cut(FF, breaks = seq(0, 60, by = 15), ordered_result = T, right = F, drop = F)) %>%
  count(dir, grp) %>%
  mutate(share = n / sum(n))

shares
#> # A tibble: 29 x 4
#>      dir grp         n share
#>    <int> <ord>   <int> <dbl>
#>  1     1 [0,15)      3  0.03
#>  2     1 [15,30)     2  0.02
#>  3     2 [0,15)      4  0.04
#>  4     2 [15,30)     3  0.03
#>  5     2 [30,45)     1  0.01
#>  6     2 [45,60)     1  0.01
#>  7     3 [0,15)      6  0.06
#>  8     3 [15,30)     1  0.01
#>  9     3 [30,45)     2  0.02
#> 10     4 [0,15)      6  0.06
#> # ... with 19 more rows

ggplot(shares, aes(x = dir, y = share, fill = grp)) +
  geom_col()