如何在R中使用ggplot2绘制重叠部分具有纵向分裂条的两组直方图

qzlgjiam  于 2023-06-19  发布在  其他
关注(0)|答案(1)|浏览(114)

我希望直方图的重叠部分显示被对角线分割的条形图,例如,我创建了以下代码:

set.seed(1)
grupo1 <- round(rnorm(100, mean = 20, sd = 2.2))
grupo2 <- round(rnorm(100, mean = 10, sd = 2))

df <- data.frame(
  valores = c(grupo1, grupo2),
  grupo = c(rep("grupo1", length(grupo1)), rep("grupo2", length(grupo2)))
)

# Crear histograma
ggplot(df, aes(x = valores, fill = grupo)) +
  geom_histogram(binwidth = 1, color = "black", position = "identity", alpha=0.6) +
  labs(x = "Valores", y = "Frecuencia", fill = "Grupo") +
  scale_fill_manual(values = c("grupo1" = "blue", "grupo2" = "red")) +
  theme_minimal()

此代码导致以下图:result, note that the part that overlaps is a different color
但我希望情节是这样画的(我在油漆中修改了它):what I want, note that shows both colors有谁知道如何绘制最后一张图片显示的直方图吗?
第二个例子,遵循相同的代码:

df2 <- rbind(df, data.frame(valores = c(15,15), grupo = c("grupo1", "grupo1")))

结果如下:2° example但是我想要这个(修改在paint):what i want
我已经尝试了一些'geom_histogram'参数,如改变'位置',但不工作,我希望代码,解决我的问题,提前感谢

i34xakig

i34xakig1#

ggplot2不能很好地处理这种事情。This question是关于向条形图添加纹理,类似于你想要的东西,它来了很大的困难。
我想出了一些非常奇怪的解决方案,可能有一种更简单的方法,我不知道。
Obs:末尾的伪数据(df2)。

选项1-组合颜色但不组合高度的条形

这基本上是你说你不想要的,但有一个改进:组合杆不具有高度之和。如果我们做了:

ggplot(df2, aes(valores, fill = grupo)) +
  geom_histogram(binwidth = 1, color = "black", alpha=0.6)

位于valores = 15的条形图将具有count = 3 + 1,但我们可能更喜欢count = 3条形图,下面还有一个更小的count = 1条形图。我们可以使用position_dodge()来实现,但不请求实际的dodge:

ggplot(df2, aes(valores, fill = grupo)) +
  geom_histogram(position = position_dodge(0), binwidth = 1, color = "black", alpha=0.6)

但我们也可以加入少量的dogge。使用position_dodge(0.3)

这种解决方案的问题是它在条形图之间添加了空白。可能有一个选项geom_histogram删除它,但我不知道。如果你愿意,你可以打开一个新的问题。

选项2-使用geom_area + geom_segment伪造条形图

您可以使用直方图的值构建新的数据集,然后您可以更灵活地自定义条形图。你可以用hist()来做,但是由于我们使用ggplot,我为每个组做了单独的直方图,并用ggplot_build()来获取他们的数据。可能有更好的方法来做到这一点,重要的是在最后你有一个数据集,其中包含每个组的直方图值。

df_area <- df2 %>%
  group_split(grupo) %>% #for each group
  map_dfr(function(df_group){ #apply the following function
    g <- ggplot(df_group, aes(valores)) +
      geom_histogram(binwidth = 1) #build a histogram
    
    ggplot_build(g)$data[[1]] %>% #get it's data
      select(c(x, xmin, xmax, y)) %>% #select these columns
      mutate(grupo = unique(df_group$grupo)) %>% #and add a 'grupo' column
      pivot_longer(c(xmin, xmax), values_to = "x_area") #pivot the data in order to build columns with geom_area
  })

现在,我们可以用geom_area构建直方图的面积,用geom_segment构建线条。我们再次使用position_dodge(0),但这次没有空格!:

ggplot(df_area, aes(x_area, y, fill = grupo)) +
  geom_area(position = position_dodge(0), alpha = 0.6, color = "black") +
  geom_segment(aes(y = 0, yend = y, x = x_area, xend = x_area))

这可能会在区域轮廓和线段之间产生奇怪的边界。此外,不能将position_dodge(k)k != 0一起使用。

选项3-geom_area + geom_segment带自定义数据

这是最接近你想要的。想法是改变数据:

df_area2 <- df_area %>%
  mutate(y = case_when(grupo == "grupo1" ~ ifelse(name == "xmin", y, 0),
                       grupo == "grupo2" ~ ifelse(name == "xmax", y, 0)))

以这样的方式生产倾斜杆:

然后,我们将其添加到最后一张图像的基础图的顶部:

ggplot(df_area, aes(x_area, y, fill = grupo)) +
  geom_area(position = position_dodge(0), color = "black") +
  geom_area(data = df_area2) + #on top of the base area, but below the lines
  geom_segment(aes(y = 0, yend = y, x = x_area, xend = x_area))

在这里使用alpha将使倾斜条可见。您可以将“洗掉”的颜色传递给fill,以便与之前的色调相匹配。
最后,我们可以在半条的末尾添加线条:

binwidth <- 1

ggplot(df_area, aes(x_area, y, fill = grupo)) +
  geom_area(position = position_dodge(0), color = "black") +
  geom_area(data = df_area2) +
  geom_segment(aes(y = 0, yend = y, x = x_area, xend = x_area)) +
  geom_segment(aes(y = y, yend = y, x = x - 0.5*binwidth, xend = x + 0.5*binwidth))

这里,binwidth与创建直方图数据时使用的相同。

虚拟数据

set.seed(1)
grupo1 <- round(rnorm(100, mean = 20, sd = 2.2))
grupo2 <- round(rnorm(100, mean = 10, sd = 2))

df <- data.frame(valores = c(grupo1, grupo2),
                 grupo = c(rep("grupo1", length(grupo1)), rep("grupo2", length(grupo2))))

df2 <- rbind(df, data.frame(valores = c(15,15), grupo = c("grupo1", "grupo1")))

相关问题