如何在 R 中正确调整 ggplot 的所有方面,包括图例?

How do I properly resize all aspects of a ggplot in R, including the legend?

我在 ggplot2 中制作散点图,然后使用 ggsave 导出特定宽度和高度的 PDF。但是,图形图例永远无法使用 ggsave 正确调整大小(其边框不会留在图中)。是否有另一种方法可以同时调整 ggplot 所有部分的大小以便于导出?我也试过使用pdf(),但同样的问题出现了。

以下是使用 iris 的示例:

data(iris)

test <- ggplot(iris, aes(x = iris$Sepal.Length, y = iris$Sepal.Width, 
  colour = iris$Species)) + 
  geom_point(size = .1) +
  theme(panel.grid.major = element_blank(), 
    panel.grid.minor = element_blank(), panel.border = element_blank(),
    panel.background = element_blank(), 
    axis.line = element_line(colour = "black", size = .8), 
    legend.key=element_blank(),
    axis.ticks = element_line(colour = "black", size = .6), 
    axis.text=element_text(size=6, colour = "black"), 
    plot.title = element_text(hjust = 0.0, size = 6, colour = "black"), 
    axis.title=element_text(size= 6), 
    legend.text=element_text(size = 6),
    legend.title=element_text(size = 6, face = "bold"),
    legend.position = c(.9, .15)) + labs(colour = "Species")

##saving plot with no resizing
ggsave(plot = test, file = "NoResize.pdf", dpi = 600, family = "ArialMT")

##saving plot with resizing results in relatively larger legend
ggsave(plot = test, file = "Resize.pdf", device = "pdf", width = 3.5, 
    height = 3, units = "in", dpi = 600, family = "ArialMT")

传说似乎在改变,但它似乎变得比情节的其他方面相对更大,以至于它不再适合情节轴。

size参数以点为单位。如果您对默认的 7 英寸 x 7 英寸图形有首选尺寸,那么您需要相应地缩放 size 以获得不同尺寸的图形。

另外两个笔记。

  1. 不要在 ggplot2::aes 调用中使用 $。这会给你带来未来的麻烦。使用 ggplot(iris) + aes(x = Sepal.Length).

  2. 就足够了 本例中的
  3. absolute legend.position 可能难以在不同尺寸的图形中使用。我建议改为 legend.position = "bottom"

在您的示例中,有两种控制字体相对大小的方法。

library(ggplot2)

data(iris)


# Okay solution, using a scaling value in an expression.  I would not recommend
# this in general, but it will work. A better solution would be to use a
# function
test <- 
  expression({
  ggplot(iris) +
  aes(x = Sepal.Length, y = Sepal.Width, colour = Species) + 
  geom_point(size = .1) +
  theme(panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank(),
        panel.border     = element_blank(),
        panel.background = element_blank(),
        axis.line        = element_line(colour = "black", size = .8),
        legend.key       = element_blank(),
        axis.ticks       = element_line(colour = "black", size = .6),
        axis.text        = element_text(size = 6 * scale_value, colour = "black"),
        plot.title       = element_text(hjust = 0.0, size = 6 * scale_value, colour = "black"),
        axis.title       = element_text(size = 6 * scale_value),
        legend.text      = element_text(size = 6 * scale_value),
        legend.title     = element_text(size = 6, face = "bold"),
        legend.position  = c(.9, .15)) + 
  labs(colour = "Species")
  })

scale_value <- 1
ggsave(eval(test), width = 7 * scale_value, height = 7 * scale_value, file = "sotest1.pdf")

scale_value <- 3/7
ggsave(eval(test), width = 7 * scale_value, height = 7 * scale_value, file = "sotest2.pdf")


# Define a function to do the work.
iris_plot <- function(scale_value = 1, filename) {
  g <- ggplot(iris) +
    aes(x = Sepal.Length, y = Sepal.Width, colour = Species) + 
    geom_point(size = .1) +
    theme(panel.grid.major = element_blank(), 
          panel.grid.minor = element_blank(),
          panel.border     = element_blank(),
          panel.background = element_blank(),
          axis.line        = element_line(colour = "black", size = .8),
          legend.key       = element_blank(),
          axis.ticks       = element_line(colour = "black", size = .6),
          axis.text        = element_text(size = 6 * scale_value, colour = "black"),
          plot.title       = element_text(hjust = 0.0, size = 6 * scale_value, colour = "black"),
          axis.title       = element_text(size = 6 * scale_value),
          legend.text      = element_text(size = 6 * scale_value),
          legend.title     = element_text(size = 6, face = "bold"),
          legend.position  = c(.9, .15)) + 
    labs(colour = "Species")

  ggsave(g, width = 7 * scale_value, height = 7 * scale_value, file = filename)
}

iris_plot(filename = "iris7x7.pdf")
iris_plot(4/7, filename = "iris4x4.pdf")

编辑

使用包 magick will give you a nice programming interface for resizing and editing graphics via imagemagick

例如

library(ggplot2)
library(magick)

g <-
  ggplot(iris) +
  aes(x = Sepal.Length, y = Sepal.Width, colour = Species) + 
  geom_point(size = .1) +
  theme(panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank(),
        panel.border     = element_blank(),
        panel.background = element_blank(),
        axis.line        = element_line(colour = "black", size = .8),
        legend.key       = element_blank(),
        axis.ticks       = element_line(colour = "black", size = .6),
        axis.text        = element_text(size = 6, colour = "black"),
        plot.title       = element_text(hjust = 0.0, size = 6, colour = "black"),
        axis.title       = element_text(size = 6),
        legend.text      = element_text(size = 6),
        legend.title     = element_text(size = 6, face = "bold"),
        legend.position  = c(.9, .15)) + 
  labs(colour = "Species")

ggsave(g, file = "iris7x7.pdf", width = 7, height = 7)

iris_g <- image_read("iris7x7.pdf")

iris_3x3 <- image_scale(iris_g, "216x216")
image_write(iris_3x3, path = "iris3x3.pdf", format = "pdf")

请注意,调整后的图形可能需要进行一些编辑以处理像素化或模糊问题。

同样,我建议不要使用绝对 legend.position 值。也许,如果您知道您需要 3 英寸乘 3 英寸的图形,您可以打开一个具有这些尺寸的开发 window 来构建您的图形,然后适当地保存。例如,通过 X11(width = 3, height = 3).

打开 3in x 3in X Window