6

I have to plot data with very different range values. I am using the facet design of ggplot2 with the option facet_grid(variable ~ ., scales = "free"). However, I would like to set the values of the breaks on the y axis such that for all variables the breaks are c(0, max(variable)/2, max(variable)). I tried using scale_y_continuous, but it did not work.

Reproducible example:

v1 <- sample(rnorm(100, 10, 1), 30)
v2 <- sample(rnorm(100, 20, 2), 30)
v3 <- sample(rnorm(100, 50, 5), 30)
fac1 <- factor(rep(rep(c("f1", "f2", "f3"), each = 10), 3))

library(reshape2)
library(ggplot2)
df1 <- melt(data.frame(fac1, v1, v2, v3))
ggplot(df1, aes(fac1, value, group = variable)) +
  geom_point() +
  facet_grid(variable ~ ., scales = "free") +
  theme_bw()
Henrik
  • 65,555
  • 14
  • 143
  • 159
user34771
  • 455
  • 1
  • 4
  • 15
  • The ggplot issue [Specify xlim and ylim for each facet separately](https://github.com/hadley/ggplot2/issues/187) suggests that it is not possible. See also @hadley's comment from 24 Feb 2014: "_This sounds like a great feature, but unfortunately we don't currently have the development bandwidth to support it_". – Henrik Feb 26 '16 at 15:35
  • Related SO posts: [How do you set different scale limits for different facets?](http://stackoverflow.com/questions/4276218/how-do-you-set-different-scale-limits-for-different-facets) and [Is it yet possible to have different axis breaks / limits for individual facets in ggplot with free scale?](http://stackoverflow.com/questions/18819333/is-it-yet-possible-to-have-different-axis-breaks-limits-for-individual-facets) – Henrik Feb 26 '16 at 15:36
  • Thank you. I will try to find another solution, maybe with grid.arrange? – user34771 Feb 26 '16 at 15:46
  • Yes, `grid.arrange` is certainly a nice way. You may also check `cowplot::plot_grid` (see e.g. [the vignette](https://cran.r-project.org/web/packages/cowplot/vignettes/introduction.html)) – Henrik Feb 26 '16 at 15:51
  • I manage to arrange the plots using grid.arrange. However, I do not manage to have for each plot a tick at y=0. – user34771 Feb 26 '16 at 16:24

1 Answers1

2

This draws the three separate plots, with the y breaks set to 0, 0.5*max(value), and max(value). The three plots are combined using the gtable rbind function, then drawn.

v1 <- sample(rnorm(100, 10, 1), 30)
v2 <- sample(rnorm(100, 20, 2), 30)
v3 <- sample(rnorm(100, 50, 5), 30)
fac1 <- factor(rep(rep(c("f1", "f2", "f3"), each = 10), 3))

library(reshape2)
library(ggplot2)
library(grid)
library(gridExtra)

df1 <- melt(data.frame(fac1, v1, v2, v3))

# Draw the three charts, each with a facet strip.
# But drop off the bottom margin material
dfp1 = subset(df1, variable == "v1")
p1 = ggplot(dfp1, aes(fac1, value, group = variable)) +
  geom_point() +
  facet_grid(variable ~ .) +
  scale_y_continuous(limits = c(0, ceiling(max(dfp1$value))),
      breaks = c(0, ceiling(max(dfp1$value))/2, ceiling(max(dfp1$value)))) +
  theme_bw()
g1 = ggplotGrob(p1)
pos = g1$layout[grepl("xlab-b|axis-b", g1$layout$name), "t"]
g1 = g1[-pos, ]

# Drop off the bottom margin material
dfp2 = subset(df1, variable == "v2")
p2 = ggplot(dfp2, aes(fac1, value, group = variable)) +
  geom_point() +
  facet_grid(variable ~ .) +
  scale_y_continuous(limits = c(0, ceiling(max(dfp2$value))), 
     breaks = c(0, ceiling(max(dfp2$value))/2, ceiling(max(dfp2$value)))) +
  theme_bw()
g2 = ggplotGrob(p2)
g2 = g2[-pos,]

dfp3 = subset(df1, variable == "v3")
p3 = ggplot(dfp3, aes(fac1, value, group = variable)) +
  geom_point() +
  facet_grid(variable ~ .) +
  scale_y_continuous(limits = c(0, ceiling(max(dfp3$value))), 
     breaks = c(0, ceiling(max(dfp3$value))/2, ceiling(max(dfp3$value)))) +
  theme_bw()
g3 = ggplotGrob(p3)

# Combine the three gtables
g = rbind.gtable(g1, g2, size = "max") 
g = rbind.gtable(g, g3, size = "max")

# Draw the plot
grid.newpage()
grid.draw(g)

enter image description here

Sandy Muspratt
  • 31,719
  • 12
  • 116
  • 122