次要/双轴 - ggplot

12
我将为您翻译以下内容,这是有关编程的:

我开这个问题是有三个原因:首先,重新讨论使用ggplot实现双轴图。其次,询问是否有一种不太繁琐的通用方法可以做到这一点。最后,请求您的帮助,以解决此问题。

我意识到有多个关于如何向ggplot添加次要轴的讨论和问题。它们通常得出以下两个结论之一:

  1. 这样做不好:Hadley Wickham在这里回答了同样的问题,并得出结论,这是不可能的。他有一个很好的观点:"使用分离的y轴(而不是彼此转换的y轴)是根本上有缺陷的"

  2. 如果你坚持,会让生活变得更加复杂并使用网格:例如这里这里


然而,以下是我经常遇到的一些情况,这些情况中双轴可视化将会极大地受益。我在下面概括了这些概念。

  1. 图表宽度较大,因此在右侧复制y轴(或在顶部复制x轴)可以帮助解释。 (我们都曾经遇到过需要在屏幕上使用尺子的图表,因为坐标轴太远了)enter image description here

  2. 我需要添加一个新的坐标轴,作为原始坐标轴的转换(例如:百分比、分位数等)。(我目前面临这个问题。下面是可重现的例子)enter image description here

  3. 最后,添加分组/元信息:当使用具有多级分类数据时,我会遇到这个问题,(例如:类别={1,2,x,y,z},这些类别被“元分成”字母和数字。)即使通过对元级别进行颜色编码并添加图例甚至进行面板化可以解决问题,但使用第二个坐标轴会更简单,用户不需要将条形图的颜色与图例的颜色匹配。enter image description here


一般问题: 鉴于新的可扩展性特点ggplot 2.0.0, 是否有更稳健的无需使用网格的双轴方式?

最后一个评论:我完全同意错误使用双轴可能会产生严重误导...但是,这不是信息可视化和数据科学的一般情况吗?



解决问题的方法:

目前,我需要一个百分比轴(第二种情况)。我使用annotategeom_hline作为解决方法。然而,我无法将文本移动到主图外部。hjust也似乎对我无效。

可重现的示例:

library(ggplot2)

# Random values generation - with some manipulation : 
maxVal = 500
value = sample(1:maxVal, size = 100, replace = T)
value[value < 400] = value[value < 400] * 0.2
value[value > 400] = value[value > 400] * 0.9


# Data Frame prepartion : 
labels = paste0(sample(letters[1:3], replace = T, size = length(value)), as.character(1:length(value)))
df = data.frame(sample = factor(labels, levels = labels), value = sort(value, decreasing = T))


# Plotting : Adding Percentages/Quantiles as lines  
ggplot(data = df, aes(x = sample, y = value)) + 
  geom_bar(stat = "identity", fill = "grey90", aes(y = maxVal )) + 
  geom_bar(stat = "identity",  fill = "#00bbd4") + 
  geom_hline(yintercept = c(0, maxVal)) + # Min and max values
  geom_hline(yintercept = c(maxVal*0.25, maxVal*0.5, maxVal*0.75), alpha = 0.2) +  # Marking the 25%, 50% and 75% values 
  annotate(geom = "text", x = rep(100,3), y = c(maxVal*0.25, maxVal*0.5, maxVal*0.75), 
           label = c("25%", "50%", "75%"), vjust = 0, hjust = 0.2) +  
  theme(axis.text.x = element_text(angle = 90, hjust = 1)) +
  theme(panel.background = element_blank()) + 
  theme(plot.background = element_blank()) + 
  theme(plot.margin = unit(rep(2,4), units = "lines")) 

如果你真的想要有第二个y轴,你可以使用latticeExtra。 - MLavoie
@MLavoie,有点令人沮丧的是,由于一个如此简单的原因,有人会从ggplot转换到lattice。 - user5363218
我记得 Hadley 在某处写道,将主轴转换为次轴是可以接受的,他可能会接受添加此功能的拉取请求。 - Roland
1个回答

4

针对 #1 的回应:

我们都遇到过那种需要在屏幕上使用尺子的图表,因为坐标轴距离太远了。

cowplot

# Assign your original plot to some variable, `gpv` <- ggplot( ... )
ggdraw(switch_axis_position(gpv, axis="y", keep="y"))

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