0

As ggplot2 prevents users from using two y-axes with different scalings, I tried to circumvent the issue by overlaying a ggplot with a grob. But the positioning seems counterintuitive and unstable. Can you elucidate some technical aspects of relevance to me? Many thanks in advance.

According to this info, it should be a piece of cake, but it only seems to apply to grobs generated by functions of the grid package: https://ggplot2.tidyverse.org/reference/annotation_custom.html

PS: I am not interested in debating the why. Thank you.

Code:

library(ggplot2)
data_D <- structure(list(width = c(20, 6, 2, 1, 4, 0.6, 0.7484218, 0.9335587, 
1.1644929, 1.4525532, 1.8118708, 2.2600728, 2.8191464, 3.5165178, 
4.3863979, 5.4714599, 6.8249334, 8.5132152, 10.619127, 13.245977, 
16.522631, 20.60983, 25.708077, 32.067477, 40), unit = structure(c(1L, 
1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("shear_stress", "velocity"
), class = "factor"), value = c(0.00174, 0.01622, 0.16065, 0.65696, 
0.02312, 0.01726544, 0.01507592, 0.02141866, 0.02538495, 0.04250598, 
0.03747275, 0.05833458, 0.07434515, 0.09323235, 0.12565372, 0.11249062, 
0.19224849, 0.21529261, 0.2861165, 0.29305465, 0.42021676, 0.55698482, 
0.76004248, 0.783903, 0.83415913)), class = "data.frame", row.names = c(NA, 
-25L))

panel_D1 <- ggplot(data=subset(data_D,data_D$unit=="shear_stress"),
                   aes(x=width,y=value)) + 
  geom_point(color="red") +
  scale_x_log10(expand=c(0,0),
  breaks=c(0.5,1,2,5,10,20,50),labels=c(0.5,1,2,5,10,20,50), 
  limits=c(0.5,50)) + 
  scale_y_log10( expand = c(0, 0),
                 labels = scales::trans_format('log10', math_format(10^.x)),
                 breaks=c(0.001,0.01,0.1,1),
                 limits = c(0.001,1) 
                 ) + 
  annotation_logticks(sides = "l") +
  theme_classic() +
  theme(axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank(),
        axis.line.x = element_blank(),
        axis.title.y = element_text(vjust = -5)
        )



# The final plot, you'll see that the left y-axis is off
panel_D <- 
  ggplot(data=subset(data_D,data_D$unit=="velocity"),
         aes(x=width,y=value))+ 
  # Now comes the actual positioning:
  annotation_custom(ggplotGrob(panel_D1),xmin=-0.4,xmax=2,ymin=-0.01,ymax=1.013) + # Inf didn't work
  geom_point(color="blue") + 
  scale_x_log10(expand=c(0,0),
                breaks=c(0.5,1,2,5,10,20,50),
                labels=c(0.5,1,2,5,10,20,50), 
                limits=c(0.5,50)) + 
  annotation_logticks(sides = "b") + 
  scale_y_continuous(position = "right",
                   expand = c(0,0),
                   breaks = seq(0,1,0.1),
                   limits = c(0,1)
                   )  +
  theme_classic() +
  theme(axis.text.y.right = element_text(margin = margin(10,10,10,10)),
        axis.title.y.right = element_text(vjust = 5,angle = 90),
        axis.title.x = element_text(vjust = 3),
        plot.margin = unit(c(0.2,0,0,1), "cm")
        )
  • You may want to look at [this question/answers](https://stackoverflow.com/q/26917689/6478701) – RoB Dec 09 '19 at 12:27
  • @RoB Thanks, but I am avoiding facets for a manifold of reasons, but maybe I'll learn sth about grob manipulations and how ggplot manipulations affect the grob. –  Dec 09 '19 at 12:53
  • Ok, where does the `trans_format` function come from ? – RoB Dec 09 '19 at 12:56
  • 1
    @RoB From the `scales` package. Sorry for not highlighting dependencies. Will edit the question accordingly. –  Dec 09 '19 at 12:57
  • 1
    See here, last example: https://wilkelab.org/cowplot/articles/aligning_plots.html – Claus Wilke Dec 11 '19 at 05:13

1 Answers1

0

FINALLY. The magic ingredient is using theme_void() and inserting axis labelling as textGrob together with the option coord_cartesian(clip = "off"). This guarantees that nothing shifts the grob in a weird way.

Will update/edit this answer when I have the code ready and clean.