如何在 ggplot 中修正纵横比?

我试图调整一个绘图的大小,以适应我的文档,但我有困难得到的绘图图表确实是一个正方形。

例如:

pdf(file = "./out.pdf", width = 5, height = 5)
p <- ggplot(mydata, aes(x = col1, y = col2))
print(p)
aux <- dev.off()

虽然 x 和 y 的极限是相同的,但是结果中的曲线不是平方的。我猜 R 使封闭面板5x5“ ,但不关心实际的图表大小。

我怎样才能 解压我的图表?

126198 次浏览

In ggplot the mechanism to preserve the aspect ratio of your plot is to add a coord_fixed() layer to the plot. This will preserve the aspect ratio of the plot itself, regardless of the shape of the actual bounding box.

(I also suggest you use ggsave to save your resulting plot to pdf/png/etc, rather than the pdf(); print(p); dev.off() sequence.)

library(ggplot2)
df <- data.frame(
x = runif(100, 0, 5),
y = runif(100, 0, 5))


ggplot(df, aes(x=x, y=y)) + geom_point() + coord_fixed()

enter image description here

To ensure a particular aspect ratio, e.g. for square, use theme(aspect.ratio=1).

Andrie's answer doesn't give the full picture, as the example provides perhaps unnatural data where range of x equals the range of y. If however the data were:

df <- data.frame(
x = runif(100, 0, 50),
y = runif(100, 0, 5))
ggplot(df, aes(x=x, y=y)) + geom_point() + coord_fixed()

then the plot would look like this:

enter image description here

The coord_fixed() function also has an argument to adjust the ratio of axes:

ratio aspect ratio, expressed as y / x

So that the plot could be made square with:

ggplot(df, aes(x=x, y=y)) + geom_point() + coord_fixed(ratio=10)

enter image description here

But you need to adjust this with the limits of the variables or plot area (not all limits are nicely divisible by whole numbers like these examples).

For completeness sake: If you want to take very different axis limits into account:

df <- data.frame(
x = runif(100, 0, 5000),
y = runif(100, 0, 5))
ratio.display <- 4/3
ratio.values <- (max(df$x)-min(df$x))/(max(df$y)-min(df$y))
plot <- ggplot(df, aes(x=x, y=y)) + geom_point()
plot + coord_fixed(ratio.values / ratio.display)

Resulting in:

Based on baptiste's suggestion and Graipher's answer because it is elegant and useful.

df <- data.frame(
x = runif(100, 0, 5000),
y = runif(100, 0, 5))
aspect.ratio <- 4/3
ratio.values <- (max(df$x)-min(df$x))/(max(df$y)-min(df$y))
plot <- ggplot(df, aes(x=x, y=y)) + geom_point() + theme(aspect.ratio=4/3)

Plot with 1:1 aspect ratio