Custom y-axis scale and secondary y-axis labels in ggplot2 3.1.0

a 夏天 提交于 2019-12-04 00:26:28

Here is a solution that works with ggplot2 version 3.1.0 using sec_axis(), and which only requires creating a single plot. We still use sec_axis() as before, but rather than scaling the transform by 1/2 for the secondary axis, we inverse scale the breaks on the secondary axis instead.

In this particular case we have it fairly easy, as we simply have to multiply the desired breakpoint positions by 2. The resulting breakpoints are then correctly positioned for both the logarithmic and linear portions of your graph. After that, all we have to do is to relabel the breaks with their desired values. This sidesteps the problem of ggplot2 getting confused by the break placement when it has to scale a mixed transform, as we do the scaling ourselves. Crude, but effective.

Unfortunately, at the present moment there don't appear to be any other alternatives to sec_axis() (other than dup_axis() which will be of little help here). I'd be happy to be corrected on this point, however! Good luck, and I hope this solution proves helpful for you!

Here's the code:

# Vector of desired breakpoints for secondary axis
sec_breaks <- c(0.001, 0.01, 0.1, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5)
# Vector of scaled breakpoints that we will actually add to the plot
scaled_breaks <- 2 * sec_breaks

ggplot(data = dat, aes(x = x, y = y)) +
  geom_line(size = 1) +
  scale_y_continuous(trans = magnify_trans_log(interval_low = 0.5,
                                               interval_high = 1,
                                               reducer = 0.5,
                                               reducer2 = 8),
                     breaks = c(0.001, 0.01, 0.1, 0.5, 0.6, 0.7, 0.8, 0.9, 1),
                     sec.axis = sec_axis(trans = ~.,
                                         breaks = scaled_breaks,
                                         labels = sprintf("%.3f", sec_breaks))) +
  theme_bw() +
  theme(axis.text.y=element_text(colour = "black", size=15))

And the resulting plot:

Can you create two separate plots for the different y-axis ranges, & stack them together? The following works for me, on ggplot2 3.1.0:

library(cowplot)

theme_set(theme_bw())

p.bottom <- ggplot(dat, aes(x = x, y = y)) +
  geom_line(size = 1) +
  scale_y_log10(breaks = c(0.001, 0.01, 0.1, 0.5),
                expand = c(0, 0),
                sec.axis = sec_axis(trans = ~ . * (1/2),
                                    breaks = c(0.001, 0.01, 0.1, 0.25))) +
  coord_cartesian(ylim = c(0.001, 0.5)) + # limit y-axis range
  theme(axis.text.y=element_text(colour = "black", size=15),
        axis.title.y = element_blank(),
        axis.ticks.length = unit(0, "pt"),
        plot.margin = unit(c(0, 5.5, 5.5, 5.5), "pt")) #remove any space above plot panel

p.top <- ggplot(dat, aes(x = x, y = y)) +
  geom_line(size = 1) +
  scale_y_continuous(breaks = c(0.6, 0.7, 0.8, 0.9, 1),
                     labels = function(y) sprintf("%.3f", y), #ensure same label format as p.bottom
                expand = c(0, 0),
                sec.axis = sec_axis(trans = ~ . * (1/2),
                                    breaks = c(0.3, 0.35, 0.4, 0.45, 0.5),
                                    labels = function(y) sprintf("%.3f", y))) +
  coord_cartesian(ylim = c(0.5, 1)) + # limit y-axis range
  theme(axis.text.y=element_text(colour = "black", size=15),
        axis.text.x = element_blank(),       # remove x-axis labels / ticks / title &
        axis.ticks.x = element_blank(),      # any space below the plot panel
        axis.title.x = element_blank(),
        axis.ticks.length = unit(0, "pt"),
        plot.margin = unit(c(5.5, 5.5, 0, 5.5), "pt"))

plot_grid(p.top, p.bottom, 
          align = "v", ncol = 1)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!