在 R 中使用嵌套分类变量和纹理填充生成堆积条形图

3
我正在尝试创建一个堆叠条形图,其中包含三个分类变量和一个离散变量,其中一个分类变量是另一个“嵌套”的。 “嵌套”分类变量将通过不同的纹理(斜线,点等)进行可视化,而“嵌套”的分类变量将通过颜色进行可视化。结果将看起来像这里的图片: https://istack.dev59.com/vVm9q.webp 在R中,我遇到了两个主要挑战:1)将一个分类变量嵌套在另一个分类变量中,2)用纹理表示类别。最接近“嵌套”一个分类变量的解决方案是下面的脚本。但是,我希望使用ggplot通过纹理区分“性别”类别,而不是轮廓颜色。我也希望将离散变量放在x轴上,而不是y轴上。这个问题表明“gridSVG”包可能有用,但我不确定如何将其与ggplot结合使用。
# This  sample dataset is taken from https://stackoverflow.com/questions/31173931/point-plot-with-se-for-3-categorical-1-continuous-variable-in-r:
library(ggplot2)
library(tibble)

df <- tibble(
  mea = rep(c("PO_P", "Melaniz"), each = 6),
  tre = rep(c("a", "a", "b", "b", "c", "c"), 2),
  sex = rep(c("Male", "Female"), 6),
  len = c(10.66154, 10.58077, 10.29200, 10.60000, 10.28519, 10.65185,
          11.47857, 11.71538, 11.70833, 11.50000, 11.62143, 11.89231)
)

ggplot(df, aes(x = factor(mea), y = len, color = sex, fill = tre)) + 
  geom_bar(stat = "identity", size = 2)

reprex package (v0.3.0)于2019年9月4日创建

2个回答

2
您可以使用ggtextures软件包来完成这个操作。但是,您需要拥有合适的纹理图像以进行平铺。创建这样的图像超出了本答案的范围。我在这里使用简单的动物图标。
library(ggplot2)
library(tibble)
library(magick)
#> Linking to ImageMagick 6.9.9.39
#> Enabled features: cairo, fontconfig, freetype, lcms, pango, rsvg, webp
#> Disabled features: fftw, ghostscript, x11
library(ggtextures) # devtools::install_github("clauswilke/ggtextures")

textures = list(
  Male = image_read_svg("http://steveharoz.com/research/isotype/icons/horse.svg"),
  Female = image_read_svg("http://steveharoz.com/research/isotype/icons/fish.svg")
)

df <- tibble(
  mea = rep(c("PO_P", "Melaniz"), each = 6),
  tre = rep(c("a", "a", "b", "b", "c", "c"), 2),
  sex = rep(c("Male", "Female"), 6),
  len = c(10.66154, 10.58077, 10.29200, 10.60000, 10.28519, 10.65185,
          11.47857, 11.71538, 11.70833, 11.50000, 11.62143, 11.89231)
)

ggplot(df) +
  aes(
    x = mea, y = len, image = sex, fill = tre,
    group = interaction(sex, tre) # determines which variable should be stacked first, sex or tre
  ) + 
  geom_textured_bar(
    stat = "identity",
    img_width = unit(20, "pt") # adjust for appropriate scaling of textures, or remove
  ) +
  scale_image_manual(values = textures) +
  coord_flip() +
  theme(legend.position = "bottom")

reprex package(v0.3.0)于2019年09月04日创建


1

ggplot没有纹理选项,但您仍然可以使用一些代码选项(一些有用的链接 这里)来获得所需的效果。在我看来,这太麻烦了,我更喜欢将图形分面并比较结果(使用fill = tre并添加facet_wrap(~sex)或者反过来,具体取决于您认为哪个更有意义)。


1
谢谢您的回复。这个图是为了一篇被审稿人评论退回给我们的手稿而制作的,其中一位审稿人要求以非常特定的方式绘制结果。在我的示例中,只有2个“mea”级别(PO_P和Melaniz),但对于我们的数据,实际上有40个级别。因此,我担心使用facet_wrap()方法会使图表过于拥挤,尽管我同意通常它将是一个非常好的替代方案。我想这需要很多代码才能生成,但我想知道是否有人在以前的项目中做过这件事? - Ellie
很遗憾听到评审人员的要求很高。从我的了解来看,实现纹理图案非常具有挑战性,特别是对于堆叠条形图而言更是如此。如果您不想使用 facet_wrap,那么可以像这个例子中一样将 sex 编码为 alpha 级别,例如这里 - Arienrhod
是的,这个着色选项看起来像是一个可能的解决方案!谢谢! - Ellie
@Arienrhod 这可以轻松完成,参见这里 - Claus Wilke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接