1

我很难在描绘密度的山脊线图中添加 y 轴。如果我做对了,山脊线图就是一种密度图。我用它代替了箱线图,还包括了分位数线。我喜欢它的方式,但是我的主管没有看到与箱线图相比的好处,并且一直希望我在密度中包含一个 y 轴。是否可以添加它,或者我是否必须使用密度图,我是否有可能将它们安排得一样漂亮 geom_density_ridges ?这是我的情节之一: 在此处输入图像描述 这是一个可复制的示例:

ggplot(diamonds, aes(x = price, y = cut, fill = cut)) +
  geom_density_ridges(scale = 0.9) +
  theme_ridges() + 
  theme(legend.position = "none")

非常感谢!

4

2 回答 2

2

我只是要继续说这是一个可怕而骇人听闻的解决方案,但是我已经花时间了,为什么不发布呢?谁知道; 这样的黑客可能对其他人很方便。

计划是:我们将半手动复制 ggridges 所做的事情,但在原版 ggplot2 中并以连续规模进行。为此,我们将滥用该after_stat()功能来 (1) 用密度填充色带,以及 (2) 为自己指定最大密度,我们将使用它作为偏移量。

library(ggplot2)

g <- ggplot(diamonds, aes(x = price, fill = cut)) +
  stat_density(
    geom = "ribbon", position = "identity",
    aes(ymax = after_stat(density + (group - 1) * max(density)),
        ymin = after_stat((group - 1) * {yoffset <<- max(density)}))
  )

整个计划的缺陷是我们事先不知道偏移量,所以我们需要至少构建一次情节才能真正使用它。

build <- ggplot_build(g)

最后,我们将非常手动地在秤上分配正确的值。我们将主要用于离散标签,次要用于连续标签。您可以查看yoffset现在应该在您的全局环境中的值,以了解正确的中断和标签是什么。

g + scale_y_continuous(
    breaks = yoffset * (4:0), labels = levels(diamonds$cut),
    sec.axis = dup_axis(
      breaks = rep(yoffset * (0:4), 4) + rep(seq(0, 0.0003, by = 0.0001), each = 5),
      labels = rep(seq(0, 0.0003, by = 0.0001), each = 5)
    )
  )

reprex 包于 2021-07-15 创建(v1.0.0)

设置中断/标签的更通用的方法:

levels <- levels(diamonds$cut)
labels <- scales::extended_breaks(3)(c(0, yoffset * 0.8))
offsets <- yoffset * (seq(length(levels), 1) - 1)

g + scale_y_continuous(
    breaks = offsets, labels = levels,
    sec.axis = dup_axis(
      breaks = rep(offsets, length(labels)) + rep(labels, each = length(offsets)),
      labels = rep(labels, each = length(offsets))
    )
  )
于 2021-07-15T16:39:29.927 回答
1

一种选择是让你通过facet_grid_wrap加上一些额外的样式来绘制,比如去掉条形文本和面板之间的间距:

library(ggplot2)
library(ggridges)

ggplot(diamonds, aes(x = price, fill = cut)) +
  geom_density() +
  scale_y_continuous(expand = expansion(mult = c(0, .2))) +
  facet_grid(cut~., switch = "y") +
  xlim(-1000, NA) +
  theme_ridges() + 
  theme(legend.position = "none", 
        strip.text.x = element_blank(),
        strip.text.y.left = element_text(angle = 0, vjust = 0.01),
        strip.background.y = element_rect(fill = NA),
        strip.placement = "outside",
        panel.grid.major.y = element_blank(),
        panel.spacing.y = unit(0, "pt"))

于 2021-07-15T14:30:05.807 回答