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

OTS*_*ats 5 r ggplot2

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

我每个GEOM(内调整参数binsbinwidthcenterboundary),并一直无法对齐这些分布。关于SO也有类似的问题(在geom_histogram或stat_bin上覆盖geom_points),但似乎没有一个类似的问题可以挖掘或提供解决方案。

这是我的几何图层不对齐的情况:

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)
Run Code Online (Sandbox Code Playgroud)

这是图p,我的基本直方图: 在此处输入图片说明

p + stat_bin(geom = "step")
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

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

eip*_*i10 5

这些条形不会自然对齐,因为 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))
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

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

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

如果这是您经常想要做的事情,您可以将其转换为具有某种逻辑的函数,以自动使用假数据扩展数据框并适当设置图的箱和 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))
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

这是没有额外行黑客的相同情节的样子:

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))
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明