【问题标题】:How to order bars in faceted ggplot2 bar chart如何在多面 ggplot2 条形图中排序条形图
【发布时间】:2011-07-21 13:17:45
【问题描述】:

如果我想将 ggplot2 条形图中的条形从大到小排序,那么我通常会更新条形类别的因子水平,就像这样

one_group <- data.frame(
  height   = runif(5),
  category = gl(5, 1)
)

o <- order(one_group$height, decreasing = TRUE)
one_group$category <- factor(one_group$category, levels = one_group$category[o])

p_one_group <- ggplot(one_group, aes(category, height)) +
  geom_bar(stat = "identity")
p_one_group

如果有几组我想要在不同方面的条形图,每个方面都有从最大到最小排列的条形(以及不同的 x 轴),那么该技术就会失效。

给定一些样本数据

two_groups <- data.frame(
  height   = runif(10),
  category = gl(5, 2),
  group    = gl(2, 1, 10, labels = letters[1:2])
)

和绘图代码

p_two_groups <- ggplot(two_groups, aes(category, height)) +
  geom_bar(stat = "identity") +
  facet_grid(. ~ group, scales = "free_x")
p_two_groups

我需要做什么才能正确订购酒吧?

如果有帮助,需要解决的等效问题是:在完成分面后如何更新因子水平?

【问题讨论】:

  • 好问题。我无法立即想到答案,只有替代方案。 1) 在 ggExtra 包中使用 align.plots。 2) 构建单独的图形并使用网格视口组合它们 - ggExtra 中的 vplayout 简化了这一点。如果这看起来有用,我可以在答案中发布一个示例。

标签: r ggplot2 data-visualization bar-chart


【解决方案1】:

这是一个技巧:

two_groups <- transform(two_groups, category2 = factor(paste(group, category)))
two_groups <- transform(two_groups, category2 = reorder(category2, rank(height)))

ggplot(two_groups, aes(category2, height)) +
  geom_bar(stat = "identity") +
  facet_grid(. ~ group, scales = "free_x") +
  scale_x_discrete(labels=two_groups$category, breaks=two_groups$category2)
  1. 为所有条目(类别 2)制作 UNIQUE 因子变量
  2. 根据高度对变量重新排序
  3. 在变量上绘图:aes(x=category2)
  4. 使用 scale_x_discrete 中变量 (category2) 的原始值 (category) 重新标记轴。

【讨论】:

  • 不错的一个kohske。这将进入我的代码 sn-ps 文件夹!
【解决方案2】:

这里有一个 hack 来实现你想要的。我无法弄清楚如何获得刻度线下方的类别值。因此,如果有人可以帮助解决这个问题,那就太好了。让我知道这是否有效

# add a height rank variable to the data frame
two_groups = ddply(two_groups, .(group), transform, hrank = rank(height));

# plot the graph

p_two_groups <- ggplot(two_groups, aes(-hrank, height)) +
  geom_bar(stat = "identity") +
  facet_grid(. ~ group, scales = "free_x") +
  opts(axis.text.x = theme_blank()) +
  geom_text(aes(y = 0, label = category, vjust = 1.5))

【讨论】:

  • 不错的ddply/transform 组合。我不认为geom_text 在绘图面板之外工作。根据 kohske 的回答覆盖规模是更清洁的解决方案。
  • 是的。我无法弄清楚如何克服这一限制。来自 kohske 的伟大 hack。