简体   繁体   English

用于插入具有不同高度的图的一致 y 轴

[英]Consistent y-axis for insetting plots with different heights

I'm trying to inset several plots on the same graph with different heights but have the same y scales.我试图在同一张图上插入几个不同高度但具有相同 y 比例的图。 In the example below I have two plots with different heights.在下面的示例中,我有两个高度不同的图。 When I plot them the y-axis don't correspond to one another.当我 plot 时,它们的 y 轴彼此不对应。 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.请注意,下图显示 y 轴的比例不同。

输出

OP notes the y axes are not on the same scale in the inset plot - presumably, they mean compared to the original plot. OP 指出,插图 plot 中的 y 轴的比例不同——大概是指与原始 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.这背后的原因是 plot 本身不仅由用于绘图的区域大小定义,还包括 plot 周围的所有边框元素 + 边距。 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:插图没有 x 轴标签,因此要使 y 轴对齐,只需删除默认添加的 plot 周围的边距:

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

在此处输入图像描述

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.每个插图 plot 下方都有一点空间,因此 0 值不完全对齐。 What's going on here?这里发生了什么? Well, even though OP applied theme(axis.ticks.x = element_blank()) , "blanking" basically means "drawing them as nothing".好吧,即使 OP 应用theme(axis.ticks.x = element_blank()) ,“空白”基本上意味着“将它们绘制为空”。 The ticks are actually still there , just not drawn.刻度线实际上仍然存在,只是没有绘制。 This means, the total plot area includes the size of the ticks .这意味着,总的 plot 区域包括刻度的大小 To remove this little space below the plot, we have to set the size of the axis ticks to zero:要删除 plot 下方的这个小空间,我们必须将轴刻度的大小设置为零:

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

在此处输入图像描述

That fixes it.这解决了它。

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

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM