Соответствие ширины двух графиков с ggplot2/gtable
Я пытаюсь сопоставить ширину области построения двух графиков, расположенных вертикально (диапазон данных на обоих графиках одинаков). Я попытался собрать их вместе, используя gtable, а затем манипулируя полями, чтобы внести коррективы. Кажется, что, поскольку нижний график не имеет отметок или меток на оси, установка одинаковых полей делает графики слегка смещенными. Мне не понятно, как рассчитывается общая ширина области слева от области графика. Кажется, что ширина текстовых меток как-то добавлена к нему, и я не могу определить, насколько он широк. (Я мог подбирать ширину экспериментальным путем, но мне нужно создать много таких графиков, и я хотел бы, чтобы решение работало с произвольными данными.) Я экспериментировал с различными комбинациями plot.margin
, panel.margin
, margin
собственностью axis.text.y
и (не рекомендуется) axis.ticks.margin.y
но безрезультатно. Вот минимальный рабочий пример:
library(ggplot2)
library(grid)
library(gtable)
ex <- data.frame(xmin=1, xmax=100, ymin=0, ymax=15)
p <- ggplot(ex, aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax)) +
theme_minimal() +
theme(plot.margin=margin(l=2.0, unit="cm"),
panel.margin=margin(l=2.0, r=0, unit="cm"),
panel.grid.major.x=element_blank(), panel.grid.minor.x=element_blank(),
panel.border=element_blank(), panel.background = element_blank(),
axis.text.y=element_text(margin=margin(l=0.0, r=0.0, unit="cm")),
axis.ticks=element_line(size = 0.25),
axis.ticks.x=element_line(), axis.ticks.y=element_line(),
axis.ticks.length=unit(0.1, units="cm")) +
scale_x_continuous(expand = c(0, 0)) +
scale_y_continuous(expand = c(0, 0)) +
geom_rect()
ex_ann <- data.frame(xmin=10, xmax=50, ymin=0, ymax=1)
ann <- ggplot(ex_ann, aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax)) +
theme_minimal() +
theme(plot.margin=margin(l=2.0, unit="cm"),
panel.margin=margin(l=2.0, unit="cm"),
panel.background=element_rect(fill="grey", colour="white"),
panel.grid.major.x=element_blank(), panel.grid.minor.x=element_blank(),
panel.grid.major.y=element_blank(), panel.grid.minor.y=element_blank(),
panel.border = element_blank(), panel.background = element_blank(),
# axis.text.y=element_text(margin=margin(r=0, l=0.5)), panel.margin=unit(0, units="cm"),
axis.ticks=element_line(size = 0.25),
axis.ticks.x=element_line(), axis.ticks.y=element_blank(),
axis.text.y=element_blank(),
axis.ticks.length=unit(0.0, units="cm")) +
scale_x_continuous(limits=c(1, 100), expand = c(0, 0)) +
scale_y_continuous(limits=c(0, 1), expand = c(0, 0)) +
geom_rect()
gr <- ggplotGrob(p)
gr_ann <- ggplotGrob(ann)
g_joint <- rbind(gr, gr_ann, size="first") # stack the two plots
g_joint$widths <- unit.pmax(gr$widths, gr_ann$widths) # use the largest widths
g_joint$layout[grepl("guide", g_joint$layout$name),c("t","b")] <- c(1,nrow(g_joint))
grid.newpage()
grid.draw(g_joint)
g <- gtable(widths=unit(c(1), "null"), heights=unit(c(1, 0.1), "null"))
g <- gtable_add_grob(g, list(gr, gr_ann), t=c(1, 2), l=c(1, 1), r=c(1, 1), b=c(1, 2))
grid.newpage()
grid.draw(g)
Я нашел это решение в Интернете: https://github.com/hadley/ggplot2/wiki/Align-two-plots-on-a-page. Это работает на простых примерах, но мои реальные сюжеты искажены. Я не понимаю достаточно знаний о внутренностях ggplot2, чтобы понять, в чем проблема. Другое ограничение этого решения состоит в том, что в этом примере оба графика имеют одинаковую высоту, и я бы хотел, чтобы нижний график имел высоту примерно 1/10 от верхнего.