title: Secondary / Dual axis - ggplot
body: <p>I am opening this question for three reasons : First, to re-open the dual-axis discussion with ggplot. Second, to ask if there is a non-torturing generic approach to do that. And finally to ask for your help with respect to a work-around. </p>
  
  <p>I realize that there are multiple discussions and questions on how to add a secondary axis to a ggplot. Those usually end up in one of two conclusions:</p>
  
  <ol>
  <li><p><strong>It's bad, don't do it</strong>: Hadley Wickham answered the same question <a href="https://stackoverflow.com/questions/3099219/plot-with-2-y-axes-one-y-axis-on-the-left-and-another-y-axis-on-the-right">here</a>, concluding that it is not possible. He had a very good argument that <em>"using separate y scales (not y-scales that are transformations of each other) are fundamentally flawed"</em>.</p></li>
  <li><p><strong>If you insist, over-complicate your life and use grids</strong> : for example <a href="https://stackoverflow.com/questions/26727741/how-to-show-a-legend-on-dual-y-axis-ggplot">here</a> and <a href="https://stackoverflow.com/questions/22701606/how-to-plot-bars-and-one-line-on-two-y-axes-in-the-same-chart-with-r-ggplot/22734987">here</a></p></li>
  </ol>
  
  <p><br></p>
  
  <p>However, here are some situations that I often face, in which the visualization would greatly benefit from dual-axis. I abstracted the concepts below. </p>
  
  <ol>
  <li><p>The plot is wide, hence <strong>duplicating</strong> the y-axis on the right side would help (or x-axis on the top) would ease interpretation. <em>(We've all stumbled across one of those plots where we need to use a ruler on the screen, because the axis is too far)</em>
  <a href="https://i.stack.imgur.com/0cZ99.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/0cZ99.png" alt="enter image description here"></a></p></li>
  <li><p>I need to add a new axis that is a <strong>transformation</strong> to the original axes (eg: percentages, quantiles, .. ). <em>(I am currently facing a problem with that. Reproducible example below)</em>
  <a href="https://i.stack.imgur.com/UIig6.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/UIig6.png" alt="enter image description here"></a></p></li>
  <li><p>And finally, adding <strong>Grouping/Meta information</strong>: I stumble across that when using categorical data with multiple-level, <em>(e.g.: Categories = {1,2,x,y,z}, which are "meta-divided" into letters and numerics.)</em>   Even though color-coding the meta-levels and adding a legend or even facetting solve the issue, things get a little bit simpler with a secondary axis, where the user won't need to match the color of the bars to that of the legend.
  <a href="https://i.stack.imgur.com/1eut7.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/1eut7.png" alt="enter image description here"></a></p></li>
  </ol>
  
  <p><br> <strong>General question:</strong> Given the new extensibility features <a href="http://blog.rstudio.org/2015/12/21/ggplot2-2-0-0/" rel="nofollow noreferrer">ggplot 2.0.0</a>, is there a more-robust no-torture way to have dual-axis without using grids?</p>
  
  <p>And one final comment: I absolutely agree that the wrong use of dual-axis can be dangerously misleading... But, isn't that the case for information visualization and data science in general? </p>
  
  <hr>
  
  <p><br>
  <strong>Work-around question</strong>:</p>
  
  <p>Currently, I need to have a percentage-axis (2nd case). I used <code>annotate</code> and <code>geom_hline</code> as a workaround. However, I can't move the text outside the main plot. <code>hjust</code> also didn't seem to work with me. </p>
  
  <p>Reproducible example: </p>
  
  <pre><code>library(ggplot2)
  
  # Random values generation - with some manipulation : 
  maxVal = 500
  value = sample(1:maxVal, size = 100, replace = T)
  value[value &lt; 400] = value[value &lt; 400] * 0.2
  value[value &gt; 400] = value[value &gt; 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")) 
  </code></pre>