为什么tiff输出看起来与R studio中的ggplot2输出不同?

时间:2015-01-26 16:25:16

标签: r ggplot2 tiff

我在最新版本的R studio中使用ggplot2制作出版质量图。

他们需要以300 dpi保存为TIFF。

当我运行代码并在命令控制台中调用绘图时,它在绘图窗口中完美显示。但是,当我将它保存为宽度,高度和分辨率命令的tiff时,当我在图像查看器中打开tiff时,它看起来完全搞砸了。字体很大,传说很大,错位等。

我试图从R studio情节窗口导出图像,但我只有高度和宽度选项。因为我想要300 dpi的数字是3.5 x 2.33我理解宽度:高度将是1050:699(像素)。但是,也许我误解了这个条目。

也许,我应该输入以英寸为单位的高度和宽度。如果我这样做,那我怎么指定dpi?

我使用tiff命令保存了我的情节。这是一个可以从Cookbook for R

借来的可重复的例子
set.seed(955)
dat <- data.frame(cond = rep(c("A", "B"), each=10),
              xvar = 1:20 + rnorm(20,sd=3),
              yvar = 1:20 + rnorm(20,sd=3))

library(ggplot2)
test <- ggplot(dat, aes(x=xvar, y=yvar, color=cond)) + 
     geom_point(shape=1) +
     scale_colour_hue(l=50) + # Use a slightly darker palette than normal
     geom_smooth(method=lm,   # Add linear regression lines
          se=FALSE) +
    theme(legend.position=c(.75,.38),
    axis.title.y = element_text(colour="black", size = 18), 
    axis.title.x = element_text( colour="black", size = 18),
    axis.text.x=element_text(colour="black", size= 16), 
    axis.text.y=element_text( colour="black", size = 16), 
    plot.title=element_text(size=14), # changing size of plot title)+
    legend.text=element_text( size=16))

tiff("test.tiff", width= 1050, height= 699, units="px", res=300)

plot(test)
dev.off()

当我使用预览打开它时,看起来完全搞砸了。我希望它看起来与在绘图窗口中完全一样,但是以某个dpi保存。我究竟做错了什么?我有什么误会?

谢谢!

3 个答案:

答案 0 :(得分:5)

这很麻烦,因为您必须调整很多属性...但是可以做到。问题是存在为字体,点和行大小设置的默认值,这些默认值与1/72英寸的比例相关,并且R / RStudio图像的默认分辨率为72ppi。当使用更高的分辨率时,这些尺寸会按像素比例成比例地变大,因此必须同时调整RStudio窗口的尺寸和分辨率。

我建议的简单解决方案是首先使绘图大于1050x699px,然后在Rstudio外部调整其大小以进行发布。但是,如果您真的想在R中完全做到这一点,则可以。

要注意的关键是:

  • R和RStudio图像的默认分辨率为72ppi
  • 可以使用dev.size()
  • 确定当前RStudio图像窗口的大小。
  • pointsizebigpts相对于英寸,并解释为1/72英寸。因此,它以像素数pointsize / 72inches * res ppi的形式出现(请参见unit
  • ggplot2图层具有点,线等属性的默认设置,可以用str(test)看到。
  • 可以使用ggplot2查看theme_get()的默认主题属性,例如图例字体大小,图例标题大小,图例框间距。
  • legend.positiondetermined by values from 0 to 1, where bottom-left is 0,0 and top-right is 1,1

这对于错位的图例意味着什么,因为它是相对位置,所以图例的坐标可能很好,但是需要重新计算图例的其他属性,例如页边距或标题大小。对于丢失的字体,这意味着必须相对于res ppi和Rstudio窗口的大小重新计算大小。由于未在theme中进行指定,因此对于误删除的行意味着必须相对于theme_get()中的默认值重新计算它们。我将按部分细分每个组件的解决方案。

RStudio窗口

我将首先在默认的Rstudio窗口中(以MacBook上的屏幕截图实用程序拍摄)发布该图的显示方式的屏幕截图:

image from Rstudio with 72ppi and 577x563px size

我可以使用dev.size("px")获得Rstudio窗口的大小(以像素为单位)。我的恰好是:

> dev.size("px")
[1] 577 563

我的RStudio窗口比所需的TIFF图的尺寸更大。这意味着长宽比将不精确,并且取决于用户。就我而言,我将尝试纠正与577窗口宽度有关的问题。

您当前可能拥有的东西

当您执行问题中的代码时,您可能最终得到如下图像:

> test <- ggplot(dat, aes(x=xvar, y=yvar, color=cond)) + 
     geom_point(shape=1) +
     scale_colour_hue(l=50) + # Use a slightly darker palette than normal
     geom_smooth(method=lm,   # Add linear regression lines
                 se=FALSE) +
     theme(legend.position=c(.75,.38),
           axis.title.y = element_text(colour="black", size = 18), 
           axis.title.x = element_text( colour="black", size = 18),
           axis.text.x=element_text(colour="black", size= 16), 
           axis.text.y=element_text( colour="black", size = 16), 
           plot.title=element_text(size=14), # changing size of plot title)+
           legend.text=element_text( size=16))
> 
> tiff("test.tiff", width= 1050, height= 699, units="px", res=300)
> 
> plot(test)
> dev.off()

enter image description here

非常丑陋;一切都需要调整。

简单解决方案

老实说,使TIFF文件更大,然后在“预览”中手动调整大小是最简单的方法。为了保持与RStudio窗口相同的外观,您需要通过ppi比率进行调整。因此,对于我们的绘图,我们将为577px * 300ppi / 72ppi = 2404px。那么等效高度将为2404px * 699px / 1050px = 1600px。

tiff("test2.tiff", width= 2404, height= 1600, units="px", res=300)

plot(test)
dev.off()

结果(由于TIFF文件太大而捕获):

Screencap of 2404x1600px TIFF at 300ppi

然后可以在“预览”中调整其大小。

字体大小

由于pointsizeres ppi处为1/72英寸,因此在Rstudio绘图中,这意味着轴标题为18 x 1 / 72inch x 72ppi = 18像素。所以1点= 1像素因此,在宽度= 577像素的图上,轴标题占据的图比例为18/577 = 0.032。因此,在宽度为1050像素(72ppi)的绘图中,我想要18/577 * 1050 = 32.76点字体。但是,我的图实际上是300ppi的width = 1050pixels。因此,我还需要根据曲线图之间的ppis比率进行调整,即72ppi / 300ppi。这给了我32.76点/300*72=7.86点,以获得与我的Rstudio窗口相同的字体。因此,我的公式是x / 577 * 1050/300 * 72,以从Rstudio窗口中的点大小转换为TIFF图像中的点大小。所以:

  • 18pts / 577 * 1050/300 * 72 = 7.86pts
  • 16分/577*1050/300*72=6.99分
  • 14pts / 577 * 1050/300 * 72 = 6.11pts

这些是我实际上应该在theme参数中输入的要点。

线和点的大小

未指定线和点的大小,因此我们必须从test$layers中获取它:

#layers[[1]] is geom_point    
> point_size<-test$layers[[1]]$geom$default_aes$size
> point_size
[1] 1.5
#layers[[2]] is geom_smooth
> line_size<-test$layers[[2]]$geom$default_aes$size
> line_size
[1] 1

使用与上述相同的逻辑,这意味着我们需要大小:

  • 1.5 / 577 * 1050/300 * 72 = 0.66
  • 1/577 * 1050/300 * 72 = 0.44

传奇位置

在示例中,图例位置在c(.75,.38)处。很好,但由于1)我的Rstudio窗口大部分为正方形,以及2)图例的其他属性(例如页边距大小和盒子大小),因此主观上似乎放错了位置。我可以使用theme_get()获得这些其他属性:

> theme_get()$legend.margin
[1] 5.5pt 5.5pt 5.5pt 5.5pt
> theme_get()$legend.key.size
[1] 1.2lines

这给了我们

将它们放在一起

将所有内容与上面的代码段一起放入,我们将输入:

test<- ggplot(dat, aes(x=xvar, y=yvar, color=cond)) + 
    geom_point(shape=1,size=0.66) +
    scale_colour_hue(l=50) + # Use a slightly darker palette than normal
    geom_smooth(method=lm,   # Add linear regression lines
                se=FALSE,size=0.44)+
    theme(legend.position=c(.75,.38),
          axis.title.y = element_text(colour="black", size = 7.62), 
          axis.title.x = element_text( colour="black", size = 7.62),
          axis.text.x=element_text(colour="black", size= 6.99), 
          axis.text.y=element_text( colour="black", size = 6.99), 
          plot.title=element_text(size=6.11), # changing size of plot title)+
          legend.text=element_text( size=6.11),
          legend.title=element_text(size=6.11), # legend title size wasn't specified originally
          legend.margin=margin(t=2.4,r=2.4,b=2.4,l=2.4),
          legend.key.size = unit(0.52,"lines")) 
tiff("test.tiff", width= 1050, height= 699, units="px", res=300)

plot(test)
dev.off()

这给了我们

enter image description here

似乎足够接近。 (图例的位置并不完全相同,但我们也从正方形图形变成了矩形图形)

一些其他注释

一种大大简化计算并能够更好地比较图例位置的方法是从1050x699像素的窗口大小开始,而不是我拥有的正方形窗口。然后,您只需要按72/300调整行和字体大小,而不需要进行其他窗口大小调整。我做了一个随机的不同大小,以显示结合了分辨率的窗口大小。

除了精确计算之外,当然还有一个替代方法,就是处理点,字体,线,边距等大小,直到获得所需的内容为止。

答案 1 :(得分:4)

Joran的上述评论似乎是正确的答案。从上面的示例中,尝试...

ggsave(filename = "test2.tiff", plot = test)

默认情况下,ggsave()输出为300 dpi,并通过扩展程序猜测输出类型。它将使您的绘图看起来就像在绘图窗口中一样,因为它使用grDevices::dev.size()获取绘图窗口大小。我猜测示例中传递给tiff()的像素尺寸与绘图窗口的尺寸不同。这就是为什么保存的情节看起来不同。

如果您使用dev.size()获取当前绘图设备的尺寸,则应该能够使用tiff()保存绘图,但通常更容易使用ggsave()包装器使用类ggplot的对象时。

答案 2 :(得分:1)

您的问题是3.5 x 2.33英寸是一个很小的数字。文本大小为18或16意味着剩余的剩余空间不大。例如,18pt字体是0.25英寸,或者是您2.33英寸高的情节高度的10%。如果RStudio中的绘图窗口大于最终图形的大小,则将要求绘图看起来不同。总的来说,为所有绘图元素获取正确的尺寸需要一些试验和错误。我建议通过以英寸为单位指定tiff尺寸来避免任何混淆。

tiff("test.tiff", width= 3.5, height= 2.33, units="in", res=300)
plot(test)
dev.off()

为避免每次都要打开新的tiff,您可以按照Andrie在评论中所说的做,并创建一个适当大小的交互式窗口:

windows(3.5, 2.33)

请注意,默认单位为英寸。

这样,您可以交互式地调整图以适应可用空间。注意打开tiff文件时打开的窗口的大小与创建文件时指定的大小不同,因此可能会拉伸图像以适合窗口。