9

I would like to produce a plot using facet_wrap that has a different y scale for each row of the wrap. In other words, with fixed scales on the same row, free scales on different rows, with a fixed x scale. Free scales doesn't give me exactly what I'm looking for, nor does facet_grid. If possible, I'd like to avoid creating 2 separate plots and then pasting them together. I'm looking for a result like the plot below, but with a y scale max of 300 for the first row, and an y scale max of 50 in the second row. Thanks for any help!

Here is my code:

library(ggplot2)
library(reshape)

# set up data frame
dat <- data.frame(jack = c(150,160,170),
              surgeon = c(155,265,175),
              snapper = c(10,15,12),
              grouper = c(5,12,50))
dat$island<-c("Oahu","Hawaii","Maui")
df<-melt(dat)

# plot
ggplot(df, aes(fill=variable, y=value, x=island)) + 
  geom_bar(width = 0.85, position= position_dodge(width=0.5),stat="identity", colour="black") +
  facet_wrap(~variable, scales = "free_y",ncol=2) + 
  theme_bw() +
  theme(strip.text = element_text(size=15, face="bold"))+
  theme(legend.position="none")+
  theme(panel.grid.major  = element_line(colour = "white", size = 0.2))+
  theme(panel.grid.minor  = element_line(colour = "white", size = 0.5))+
  theme(axis.text.x = element_text(angle = 90, hjust =1, vjust =0.5, size=18))+
  labs(y = expression(paste("Yearly catch (kg)")))

enter image description here

Sandy Muspratt
  • 31,719
  • 12
  • 116
  • 122
kmccoy
  • 93
  • 1
  • 4

1 Answers1

13

Drawing on one of the lower ranked answers from the link Eric commented, you can add a layer that blends into the background to enforce the axes.

Here I created a second data frame (df2) that puts a single point at "Hawaii" and the max value you wanted (300 or 50) for the four variable/fish types. By manually setting the color of the geom_point white, it fades into the background.

library(ggplot2)
library(reshape)

# set up data frame
dat <- data.frame(jack = c(150,160,170),
                  surgeon = c(155,265,175),
                  snapper = c(10,15,12),
                  grouper = c(5,12,50))
dat$island<-c("Oahu","Hawaii","Maui")
df<-melt(dat)
#> Using island as id variables

df2 <- data.frame(island = rep("Hawaii",4), variable = c("jack","surgeon","snapper","grouper"),value = c(300,300,50,50))

ggplot(df, aes(fill=variable, y=value, x=island)) + 
  geom_bar(width = 0.85, position= position_dodge(width=0.5),stat="identity", colour="black") +
  geom_point(data = df2, aes(x = island, y = value), colour = "white") +
  facet_wrap(~variable, scales = "free_y",ncol=2) + 
  theme_bw() +
  theme(strip.text = element_text(size=15, face="bold"))+
  theme(legend.position="none")+
  theme(panel.grid.major  = element_line(colour = "white", size = 0.2))+
  theme(panel.grid.minor  = element_line(colour = "white", size = 0.5))+
  theme(axis.text.x = element_text(angle = 90, hjust =1, vjust =0.5, size=18))+
  labs(y = expression(paste("Yearly catch (kg)")))

Community
  • 1
  • 1
Laura Wiley
  • 233
  • 2
  • 6
  • 2
    Note a better way to add the non-visable point is to use alpha = 0. This makes the point completely transparent, so it doesn't matter what is behind the point. Thus just replace the third line of the plot: `geom_point(data = df2, aes(x = island, y = value), alpha = 0)` – Laura Wiley Oct 31 '15 at 19:34
  • 1
    Thank you Laura! This is amazing. I can now stop beating my head against the wall. – kmccoy Nov 02 '15 at 18:35
  • A generic way of finding place of Min and Max (in case numbers change): ... + `geom_point(data = . %>% group_by(variable) %>% dplyr::summarise(MAX = max(value, na.rm = T)) %>% ungroup(), aes(x = "Maui", y = MAX), colour = "white", alpha = 0)` + `geom_point(data = . %>% group_by(variable) %>%dplyr::summarise(MIN = min(value, na.rm = T)) %>% ungroup(), aes(x = "Maui", y = MIN), colour = "white", alpha = 0)` – AnnaZ Mar 24 '22 at 14:25