辅助/双轴 - ggplot

时间:2016-01-12 10:24:47

标签: r ggplot2

我打开这个问题有三个原因:第一,用ggplot重新开启双轴讨论。其次,要问是否有一种非折磨的通用方法来做到这一点。最后,请求您提供有关解决方案的帮助。

我意识到关于如何将辅助轴添加到ggplot有多个讨论和问题。这些通常最终得出两个结论之一:

  1. 这很糟糕,不要这样做:Hadley Wickham回答了同样的问题here,得出结论认为这是不可能的。他有一个非常好的论据,"使用单独的y尺度(不是彼此变换的y尺度)从根本上是有缺陷的"

  2. 如果您坚持,过度复杂化您的生活并使用网格:例如herehere


  3. 然而,这里有一些我经常遇到的情况,其中可视化将极大地受益于双轴。我抽象了下面的概念。

    1. 图是宽的,因此重复右侧的y轴有助于(或顶部的x轴)方便解释。 (我们都偶然发现了其中一个我们需要在屏幕上使用标尺的图,因为轴太远了) enter image description here

    2. 我需要在原始轴上添加一个转换的新轴(例如:百分比,分位数,......)。 (我目前面临的问题是。下面的可重复示例) enter image description here

    3. 最后,添加分组/元信息:当我使用多级别的分类数据时,我偶然发现了这种情况(例如:Categories = {1,2,x, y,z},它们被"元分割成字母和数字。)即使对元级别进行颜色编码并添加图例或甚至分面解决问题,事情也会得到使用辅助轴稍微简单一点,用户不需要将条形图的颜色与图例的颜色相匹配。 enter image description here


    4. 一般问题:鉴于新的可扩展性功能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")) 
      

1 个答案:

答案 0 :(得分:4)

回应#1

  

我们都偶然发现了其中一个我们需要在屏幕上使用标尺的图,因为轴太远了

cowplot

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