我有一个for循环,可以生成60个图。我想将所有这些图保存在一个文件中。
如果我设置par(mfrow=c(10,6))
,则会显示:Error in plot.new() : figure margins too large
我该怎么办?
我的代码如下:
pdf(file="figure.pdf")
par(mfrow=c(10,6))
for(i in 1:60){
x=rnorm(100)
y=rnorm(100)
plot(x,y)
}
dev.off()
答案 0 :(得分:4)
如循环中所述,您的默认绘图不会非常有效地使用空间。如果只查看单个图,则可以看到它在轴和边之间具有较大的边距,并绘制区域和轴文本。实际上,有很多空间占用。
其次,默认的pdf函数会创建7 x 7英寸的小页面。这不是一张可以绘制的大表。
尝试在7 x 7英寸的范围内绘制10 x 6或12 x 5的图形,因此试图在非常小的空间内挤入大量的空白。
要使其成功,您必须查看par
mar
,mai
,oma
和omi
的{{1}}的保证金选项,并且可能多一点。请使用命令
?par
除此之外,你可以考虑不为60个子图中的每一个显示轴文本,刻度线,刻度标签和标题,因为这也可以节省空间。
但是有人已经为你解决了一些麻烦。查看lattice
- 包或ggplot2
,它有一些很好的方法可以制作类似于表格的子图。
但是还有另一个迫切的问题:你想用60个子图显示什么?
<强>更新强>
看到你想要做什么,这里是ggplot2
中的一个小面孔的例子。它使用jrnold的ggthemes中的Tufte主题,将其复制到此处,然后在函数后面的行中略微修改。
library(ggplot2)
library(scales)
#### Setup the `theme` for the plot, i.e. the appearance of background, lines, margins, etc. of the plot.
## This function returns a theme-object, which ggplot2 uses to control the appearance.
theme_tufte <- function(ticks=TRUE, base_family="serif", base_size=11) {
ret <- theme_bw(base_family=base_family, base_size=base_size) +
theme(
legend.background = element_blank(),
legend.key = element_blank(),
panel.background = element_blank(),
panel.border = element_blank(),
strip.background = element_blank(),
plot.background = element_blank(),
axis.line = element_blank(),
panel.grid = element_blank())
if (!ticks) {
ret <- ret + theme(axis.ticks = element_blank())
}
ret
}
## Here I modify the theme returned from the function,
theme <- theme_tufte() + theme(panel.margin=unit(c(0,0,0,0), 'lines'), panel.border=element_rect(colour='grey', fill=NA))
## and instruct ggplot2 to use this theme as default.
theme_set(theme)
#### Some data generation.
size = 60*30
data <- data.frame(x=runif(size), y=rexp(size)+rnorm(size), mdl=sample(60,size, replace=TRUE))
#### Main plotting routine.
ggplot(data, aes(x,y, group=mdl)) ## base state of the plot to be used on all "layers", i.e. which data to use and which mappings to use (x should use x-variable, y should use the y-variable
+ geom_point() ## a layer that renders data as points, creates the scatterplot
+ stat_quantile(formula=y~x) ## another layer that adds some statistics, in this case the 25%, 50% and 75% quantile lines.
+ facet_wrap(~ mdl, ncol=6) ## Without this, all the groups would be displayed in one large plot; this breaks it up according to the `mdl`-variable.
使用ggplot2
的常见挑战是将所有数据重组为data.frames。对于此任务,reshape2
和plyr
- 包可能很有用。
对于你,我会想象你创建子图的函数都计算估计和创建图。这意味着您必须将函数拆分为计算估算值,并将其返回到data.frame
,然后您可以对其进行整理并传递给ggplot
。
答案 1 :(得分:3)
将图表输出为pdf:
X = matrix(rnorm(60*100), ncol=60)
Y = matrix(rnorm(60*100), ncol=60)
pdf(file="fileName.pdf")
for(j in 1:60){
plot(X[,j], Y[,j])
}
dev.off()
答案 2 :(得分:2)
为了在页面或文档上放置许多绘图(我创建了包含数千个绘图的图像),可以方便地将R
之间的工作分开 - 这样可以单独创建绘图 - 以及其他更适合安排数组事物的软件。如果这让您想起电子表格或文字处理表,那么我们就是在思考。
此页面是PDF文件的屏幕截图,包含200多个统计图形。虽然为了模糊专有数据,它已经大大减少(标称尺寸为40%),但原始版本具有原始R
图形的所有细节,并且可以毫无问题地缩放到1600%。 < / p>
两种机制运作良好。对于多达几百个图,一个小宏可以将一组位图图像文件(.emf或.wmf)导入并重新排序到Word文档中。为了更好地控制,我转向可比较的Excel宏。除了包含列标题的行和包含行标题的列之外,它由一个没有所有内容的工作表驱动。 (您可以在图的左侧和顶部看到它们。)宏删除该工作表上的所有其他内容(格式除外),然后将行和列标题的每个可能组合导入文件名,如果找到该文件,它将它导入相应的单元格。几千张图片的整个操作只需几秒钟。
显然,R
与其他软件之间的这种通信机制是原始的,由具有标准命名约定的图像文件集合组成。但实现它所需的代码很简单(虽然针对每种情况进行了定制)并且可靠地运行。例如,如果将绘图代码封装在函数中,则会在循环内调用它以创建许多类似的绘图。在该函数的末尾添加几行以将绘图保存到文件中,如下所示:
path <- "W: <whatever>/" # Folder for the output files
ext <- "wmf" # or "emf" or "png" or ... # Format (and extension) of the output
...
if (save) {
outfile <- paste(path, paste(munge(well), munge(parm), sep="_"), sep="/")
outfile <- paste(outfile, ext, sep=".")
savePlot(filename=outfile, type=ext)
}
在这种情况下,每个图由两个循环变量well
和parm
标识,两个变量都是字符串(它们对应于列和行标题)。创建可接受的文件名的功能只是删除标点符号,用anodyne占位符替换它:
munge <- function(s) gsub("[[:punct:]]", "_", s)
将这些图像导入Word,Excel或任何您喜欢的地方后,可以很容易地重新组织它们,在它们周围放置其他材料等,然后以PDF格式打印结果。
创造这些非常大的“小倍数”是一种艺术(用Tufte的术语)。在可能的范围内,有助于遵循Tufte增加数据的原则:通过擦除不必要的材料来实现墨水比率。即使在大小已经大大减小画面以便一次理解其所有行和列时,这使得图形图案清晰。虽然前面的图是一个不好的例子 - 单个图必须有轴,网格线,标签等,以便在缩放时可以详细阅读 - 这种方法的力量显示模式即使在这个规模上也很清楚。使这些地块彼此相当至关重要。在这个由时间序列组成的例子中,每个图在x轴上具有相同的范围;在每行内(对应于不同类型的观察),y轴上的范围是相同的;所有的配色方案和符号化方法都是一样的。
答案 3 :(得分:0)
您也可以使用knitr
。这并没有立即转换为基础图形(我现在必须运行),但使用ggplot
很容易。
\documentclass{article}
\begin{document}
<<echo = FALSE, fig.keep='high', fig.height=3, fig.width=4>>=
require(ggplot2)
for (i in 1:10) print(ggplot(mtcars, aes(x = disp, y = mpg)) + geom_point())
@
\end{document}
上面的代码将生成一个包含所有图形的漂亮的多页pdf。
答案 4 :(得分:0)
对于这类问题的一个非常简单的解决方案,我发现设置一个大的&#34; Windows&#34;设备设法使窗口足够大,可用于多种用途。
windows(50,50)
par(mfrow=c(10,6))
for(i in 1:60){
x=rnorm(100)
y=rnorm(100)
plot(x,y)
}
或者就我而言,
windows(20,20)
plot(Plotting_I_Need_In_Rows_of_4, mfrow=c(4,4))