0

I have reading all post about scaling the y-axis and in all of them there are some extra steps in order to control the y-axis limits when using sec.axis in ggplot.

I have the following df.

structure(list(day = c(1, 3, 5, 7, 9), mean = c(0.000452620431539136, 
0.000244953967091816, 0.000409529176828165, 0.000621566432113383, 
0.000975471413145951), sd = c(0.000145928952108396, 7.48403498938327e-05, 
8.70694523628839e-05, 0.000265199022927143, 0.00076194983870935
), group = c("pi", "pi", "pi", "pi", "pi")), row.names = c(NA, 
-5L), class = c("tbl_df", "tbl", "data.frame"))

and

structure(list(day = c(1, 3, 5, 7), mean = c(NaN, 5.85880255563636, 
4.16535426125, 3.22060147866667), sd = c(NaN, 0.363838291664683, 
0.980379999667707, 1.17101416465057), group = c("Equi", "Equi", 
"Equi", "Equi")), row.names = c(NA, -4L), class = c("tbl_df", 
"tbl", "data.frame"))

I run the following code:

-ggplot(data=DI.pi.sum, aes(x=day, y=mean)) + geom_bar(stat = "identity", fill = "grey", size = 1.5) +
       geom_errorbar(aes(ymin=mean-sd, ymax=mean+sd), size = 0.1, width=.3,
                     position=position_dodge(1)) +
       geom_line(data=DI.Equi.sum, aes(x=day, y=mean/10000))  +
       geom_ribbon(data = DI.Equi.sum, 
                   aes(x=day, y = mean/10000, ymin=mean/10000-sd/10000, ymax=mean/10000+sd/10000),
                   alpha=0.2, fill = "grey40") +
       theme(panel.grid.major =  element_blank(),
             panel.grid.minor = element_blank(),
             panel.background = element_blank(),
             axis.line = element_line(colour = "black"),
             axis.text.x = element_text(face = "bold", size = 7),
             axis.title.y = element_text(face = "bold", size = 10),
             legend.direction = "vertical", legend.box = "horizontal") +
       scale_size(range = c(5, 15)) +
       scale_x_continuous(breaks = c(1, 3, 5, 7, 9), limits = c(0,10))  +
       scale_y_continuous(limits=c(0, 0.0020), sec.axis = sec_axis(~ . * 10000), name = "pi")  

Producing the following plot:

enter image description here

I do not need the sec axis to go up to 40. I would be great to get it to just 20.

Suggestions?

Thanks in advance.

genferreri
  • 123
  • 7

1 Answers1

1

The range of the mean which you want to plot with the secondary axis is only 3-6. I've adjusted your call to ggplot with a scaling factor variable so you can play around with how you want the secondary axis to look. A scaling factor of 10,000 gets you a secondary axis range from 0-20.


library(ggplot2)

scaling_factor = 10000

ggplot(data=DI.pi.sum, aes(x=day, y=mean)) + geom_bar(stat = "identity", fill = "grey", size = 1.5) +
  geom_errorbar(aes(ymin=mean-sd, ymax=mean+sd), size = 0.1, width=.3,
                position=position_dodge(1)) +
  geom_line(data=DI.Equi.sum, aes(x=day, y=mean/scaling_factor))  +
  geom_ribbon(data = DI.Equi.sum, 
              aes(x=day, y = mean/scaling_factor, ymin=mean/scaling_factor-sd/scaling_factor, ymax=mean/scaling_factor+sd/scaling_factor),
              alpha=0.2, fill = "grey40") +
  theme(panel.grid.major =  element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        axis.line = element_line(colour = "black"),
        axis.text.x = element_text(face = "bold", size = 7),
        axis.title.y = element_text(face = "bold", size = 10),
        legend.direction = "vertical", legend.box = "horizontal") +
  scale_size(range = c(5, 15)) +
  scale_x_continuous(breaks = c(1, 3, 5, 7, 9), limits = c(0,10))  +
  scale_y_continuous(limits=c(0, 0.0020), sec.axis = sec_axis(~ . * scaling_factor, name =  "secondary axis"), name = "pi")  


Comment

Using dual scaled y-axis especially with bars is generally considered inappropriate and should be discouraged. (Paraphrased from the Few article noted below)

See this for discussion on the issue: How can I plot with 2 different y-axes?, ggplot with 2 y axes on each side and different scales and the linked article by Stephen Few: http://www.perceptualedge.com/articles/visual_business_intelligence/dual-scaled_axes.pdf

Created on 2020-05-25 by the reprex package (v0.3.0)

Community
  • 1
  • 1
Peter
  • 11,500
  • 5
  • 21
  • 31
  • Thanks Peter for taking the time. For what I see it literally erased the ticks from the scale but did not rescale. What I am looking for is for rescaling so I can display more clear the drop for the values in the lines. – genferreri May 25 '20 at 13:14
  • Have a look at the revised answer; secondary axis now rescaled with a range 0-20. – Peter May 25 '20 at 13:38
  • thanks you very much for the articles. Question, why didn't the line (mean and sd) change? is it because of the conversion? – genferreri May 25 '20 at 14:13
  • Because the scaling factor is constant across the call to ggplot: i.e. in `geom_line` and `geom_ribbon` as well as `sec_axis`. If you want the line in the plot to have a greater y range you need to adjust the scaling factor in the `sec_axis` And when you do that you begin to understand why plotting with dual axis can be such a misleading way to present data! – Peter May 25 '20 at 14:23
  • Try with a scaling factor of 3500 and see what happens. If this answers your question please click the accept tick – Peter May 25 '20 at 14:26
  • Even though the dual plotting may not be the best choice as you mentioned, this will be discuss properly when shown the plot. Thanks @Peter the answer above + the rescaling factor did the trick. – genferreri May 25 '20 at 15:05