`geom_histogram`和`stat_bin()`不对齐

时间:2019-09-19 15:29:43

标签: r ggplot2

构建直方图后,我想在绘图中添加上边界/轮廓。我不想使用geom_bargeom_col,因为我不想每个容器的垂直边界。
我的尝试包括使用geom_histogramstat_bin(geom = "bin"),但是垃圾箱无法对齐。

我已经调整了每个几何区域内的参数(binsbinwidthcenterboundary),但无法对齐这些分布。关于SO(Overlaying geom_points on a geom_histogram or stat_bin)也有类似的问题,但似乎没有一个类似的问题可以解决或提供解决方案。

在这种情况下,我的几何图层不对齐:

set.seed(2019)
library(ggplot2)
library(ggthemes)
df <- data.frame(x = rnorm(100), 
                 y = rep(c("a", "b"), 50))

p <- df %>% 
    ggplot(aes(x, fill = y)) + 
    geom_histogram() + 
    facet_wrap(vars(y)) + 
    theme_fivethirtyeight() + 
    guides(fill = F)

这是情节p,我的基本直方图: enter image description here

p + stat_bin(geom = "step")

enter image description here

我希望得到两个几何对齐的图。我已经测试了各种虚拟数据,但这仍然是一个问题。这些几何体为什么不自然对齐?如何调整这些层中的任何一层以对齐?有没有比结合直方图和统计盒更好的替代方案来实现我想要的图了?

1 个答案:

答案 0 :(得分:3)

这些条不能自然对齐,因为geom_step似乎是使用每个直方图条的中间(由x返回的数据框中的layer_data(p)列)作为每个更改点的位置。因此,要对齐步骤,请使用position_nudge将geom_step移动一半binwidth:

library(tidyverse)

p <- df %>% 
  ggplot(aes(x, fill = y)) + 
  geom_histogram(bins=20) + 
  facet_wrap(vars(y)) + 
  theme_fivethirtyeight() + 
  guides(fill = F)

binwidth = layer_data(p) %>% mutate(w=xmax-xmin) %>% pull(w) %>% median

p + stat_bin(geom = "step", binwidth=binwidth, position=position_nudge(x=-0.5*binwidth))

enter image description here

但是,请注意,在上图中,步骤边框停在左侧面板中最后一个栏的中间,并且未限制右侧面板中第一个栏的左边缘。以下是使geom_step完全绑定所有直方图条的技巧。

我们在真实数据范围之外添加两行伪数据,然后将绘图的x范围设置为仅包含真实数据范围。在这种情况下,我设置了binwidth(而不是bin的数量),因为扩展数据范围将增加任何固定数量的bin的binwidth,并且还添加了一个center参数,该参数并不是必须的,但是可以根据需要用于确保垃圾箱位于特定位置的中心。

如果这是您经常要执行的操作,则可以将其转换为具有某种逻辑的函数,以使用假数据自动扩展数据框,并适当设置图的bin和x范围。

p <- df %>% 
  add_row(x=range(df$x) + c(-1,1), y="a") %>% 
  ggplot(aes(x, fill = y)) + 
  geom_histogram(binwidth=0.2, center=0) + 
  facet_wrap(vars(y)) + 
  theme_fivethirtyeight() + 
  guides(fill = F)

binwidth = layer_data(p) %>% mutate(xmax-xmin) %>% pull() %>% median

p + 
  stat_bin(geom = "step", binwidth=binwidth, position=position_nudge(x=-0.5*binwidth)) +
  coord_cartesian(xlim=range(df$x[1:(nrow(df)-2)]) + c(-0.2,0.2))

enter image description here

这是没有多余行黑客的情况下相同情节的样子:

p <- df %>% 
  ggplot(aes(x, fill = y)) + 
  geom_histogram(binwidth=0.2, center=0) + 
  facet_wrap(vars(y)) + 
  theme_fivethirtyeight() + 
  guides(fill = F)

binwidth = layer_data(p) %>% mutate(xmax-xmin) %>% pull() %>% median

p + 
  stat_bin(geom = "step", binwidth=binwidth, position=position_nudge(x=-0.5*binwidth))

enter image description here