79634680

Date: 2025-05-23 00:06:55
Score: 0.5
Natty:
Report link

Based on Edward's comment about the positioning of the y-axis title, I tinkered with Jon's patchwork solution. To preserve the default positioning of most plot elements, I used the patchwork functionality to calculate the amount by which I need to adjust the margin of the smaller plot. This solution works even when the sizing of multiple plot elements differs across plots (in the example, the axis text and the axis title).

library(ggplot2)
library(patchwork)
p1 <- ggplot(mpg, aes(x = hwy, y = cty)) +
  geom_point()
p2 <- ggplot(mpg, aes(x = hwy, y = cty*10000)) +
  geom_point()
p3 <- ggplot(mpg, aes(x = hwy, y = cty)) +
  geom_point() + ylab('blablablab\nblub')

p1_dims <- get_dim(p1)
p2_dims <- get_dim(p2)
p3_dims <- get_dim(p3)

p1_dims_tinker <- p1_dims
p2_dims_tinker <- p2_dims
p3_dims_tinker <- p3_dims

p1_dims_tinker$l[1] <- p1_dims_tinker$l[1] + max(sum(p1_dims$l), sum(p2_dims$l), sum(p3_dims$l)) - sum(p1_dims$l)
p2_dims_tinker$l[1] <- p2_dims_tinker$l[1] + max(sum(p1_dims$l), sum(p2_dims$l), sum(p3_dims$l)) - sum(p2_dims$l)
p3_dims_tinker$l[1] <- p3_dims_tinker$l[1] + max(sum(p1_dims$l), sum(p2_dims$l), sum(p3_dims$l)) - sum(p3_dims$l)

p1c <- set_dim(p1, p1_dims_tinker)
p2c <- set_dim(p2, p2_dims_tinker)
p3c <- set_dim(p3, p3_dims_tinker)

ggsave(plot = p1c, filename = "p1patchworktinker.pdf", height = 5, width = 6, units = "cm")
ggsave(plot = p2c, filename = "p2patchworktinker.pdf", height = 5, width = 6, units = "cm")
ggsave(plot = p3c, filename = "p3patchworktinker.pdf", height = 5, width = 6, units = "cm")

I have a lot of plots in my presentation, so I also developed a more general way of adjusting all four margins across a list of plots

p1 <- ggplot(mpg, aes(x = hwy, y = cty)) +
  geom_point()
p2 <- ggplot(mpg, aes(x = hwy, y = cty*10000)) +
  geom_point()
p3 <- ggplot(mpg, aes(x = hwy, y = cty)) +
  geom_point() + ylab('blablablab\nblub')

plotList <- list(p1,p2,p3)
dimList <- lapply(plotList, get_dim)
maxDimPerPlot <- lapply(dimList, function(x) lapply(x, sum))
maxDimAcrossPlots <- as.list(apply(do.call(rbind, lapply(maxDimPerPlot, data.frame)), 2, max))

for (i in 1:length(plotList)){
  dimsTMP <- dimList[[i]]
  for (m in names(dimsTMP)){
    dimsTMP[[m]][i] <- dimsTMP[[m]][i] + maxDimAcrossPlots[[m]] - maxDimPerPlot[[i]][[m]]
  }
  pTMP <- set_dim(plotList[[i]], dimsTMP)
  ggsave(plot = pTMP, filename = paste0("p", i, "patchworktinker2.pdf"), height = 5, width = 6, units = "cm")
}

This does the job, but it is not very elegant and requires constructing all plots of my presentation in one script. I would still be glad, if there is a way to set the coordinates of the center (or corner) of a fixed-size-panel within a PDF image.

Reasons:
  • Blacklisted phrase (0.5): I need
  • Long answer (-1):
  • Has code block (-0.5):
  • Self-answer (0.5):
  • Low reputation (1):
Posted by: Steph_B