Home > Back-end >  Consistent y-axis for insetting plots with different heights
Consistent y-axis for insetting plots with different heights

Time:02-02

I'm trying to inset several plots on the same graph with different heights but have the same y scales. In the example below I have two plots with different heights. When I plot them the y-axis don't correspond to one another. How can I programmatically 'align' these two graphs?

Thanks

library(dplyr)
library(gridExtra)

plot_1 = data.frame(x = 1:250,
                    y = 1:250) %>% 
  ggplot(aes(x = x, y = y))  geom_point()  scale_y_continuous(limits=c(0,250), expand = c(0, 0))  
  theme(legend.position="none",axis.title.x=element_blank(),axis.text.x=element_blank(),axis.ticks.x=element_blank()) 
plot_2 = data.frame(x = 1:250,
                    y = 1:250*3) %>% 
  ggplot(aes(x = x, y = y))  geom_point()  scale_y_continuous(limits=c(0,750), expand = c(0, 0))   
  theme(legend.position="none",axis.title.x=element_blank(),axis.text.x=element_blank(),axis.ticks.x=element_blank()) 

base <- ggplot(data.frame(x = 1:1000,
                          y = 1:1000), aes(x, y))  
  geom_blank()  
  theme_bw()

base = base   
  annotation_custom(grob = ggplotGrob(plot_1),
                    ymin = 0,
                    ymax = 250,
                    xmin = 0,
                    xmax = 200) 

base = base   
  annotation_custom(grob = ggplotGrob(plot_2),
                    ymin = 0,
                    ymax = 750,
                    xmin = 300,
                    xmax = 500) 


base

Note that the graph below shows the y-axis aren't on the same scale.

output

CodePudding user response:

OP notes the y axes are not on the same scale in the inset plot - presumably, they mean compared to the original plot. The reasoning behind this is that the plot itself is not defined only by the size of the area used for plotting, but also includes all the border elements around the plot a margin. The inset plots have no x axis labels, so to have the y axes align, all that is needed is to remove the margin around the plot which is added by default:

base <-
  ggplot(data.frame(x = 1:1000, y = 1:1000), aes(x, y))  
  geom_blank()  
  theme_bw()  
  annotation_custom(
    grob = ggplotGrob(plot_1   theme(plot.margin = margin())),
      ymin = 0, ymax = 250,
      xmin = 0, xmax = 200)  
  annotation_custom(
    grob = ggplotGrob(plot_2   theme(plot.margin = margin())),
      ymin = 0, ymax = 750,
      xmin = 300, xmax = 500) 
base

enter image description here

If you notice... it's not perfect. There's a bit of space below each inset plot, so the 0 values do not align completely. What's going on here? Well, even though OP applied theme(axis.ticks.x = element_blank()), "blanking" basically means "drawing them as nothing". The ticks are actually still there, just not drawn. This means, the total plot area includes the size of the ticks. To remove this little space below the plot, we have to set the size of the axis ticks to zero:

base <-
  ggplot(data.frame(x = 1:1000, y = 1:1000), aes(x, y))  
  geom_blank()  
  theme_bw()  
  annotation_custom(
    grob = ggplotGrob(plot_1   theme(plot.margin = margin(), axis.ticks.length.x = unit(0,'pt'))),
      ymin = 0, ymax = 250,
      xmin = 0, xmax = 200)  
  annotation_custom(
    grob = ggplotGrob(plot_2   theme(plot.margin = margin(), axis.ticks.length.x = unit(0,'pt'))),
      ymin = 0, ymax = 750,
      xmin = 300, xmax = 500) 
base

enter image description here

That fixes it.

CodePudding user response:

This isn't perfect but might work with some tweaking.

base <- ggplot(data.frame(x = 1:1000,
                          y = 1:1000), aes(x, y))  
  geom_blank()  
  theme_bw()

y_scaling <- 0.8
y_border <- 50
y_max <- function(plot) {
  (diff(range(plot$data$y))   y_border) * y_scaling
}
y_max(plot_1)


base = base   
  annotation_custom(grob = ggplotGrob(plot_1),
                    ymin = 0,
                    ymax = y_max(plot_1),
                    xmin = 0,
                    xmax = 200) 

base = base   
  annotation_custom(grob = ggplotGrob(plot_2),
                    ymin = 0,
                    ymax = y_max(plot_2),
                    xmin = 300,
                    xmax = 500) 


base

enter image description here

  •  Tags:  
  • Related