在knitr中打印动态大小的图表列表 [英] Print a list of dynamically-sized plots in knitr

查看:133
本文介绍了在knitr中打印动态大小的图表列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够在knitr中打印非预定的情节列表。我可以做到这一点,但还有一些皱纹可以解决。即:

1)你如何在每个图表之前的每个页面上抑制列表索引(如[[2]])?使用echo = FALSE不会执行任何操作。

2)是否可以为每个图设置尺寸我试过在块外设置一个大小变量,但是这只允许我使用一个值而不是每个图的不同值。



我在问这个问题,因为他们似乎在讲同一课,即制作一张情节列表。



一些示例代码:

  \documentclass {article} 
\ usepackage [margin = .5in,landscape] {geometry}
\ begin {document}

<< diamond_plots,echo = FALSE,results ='hide' >> ==
library(ggplot2)

diamond_plot = function(data,cut_type){
ggplot(data,aes(color,fill = cut))+
geom_bar()+
ggtitle(paste(Cut:,cut_type,sep =))
}

cuts = unique(diamonds $ cut)
bots = list()
for(i in 1:length(cuts)){
data = subset(diamonds,cut == cuts [i])
plots [[i ]] = diamond_plot(data,cuts [i])
}
height = 3
@

<<< print_plots,results ='asis',echo = FALSE,fig.width = 10,fig.height = height>> =

@
\ end {document}

这些图的PDF看起来像这样:

解决方案


1)如何在每个图表之前的每个页面上抑制列表索引(如[[2]])?使用echo = FALSE不会做任何事情。


分别绘制列表中的每个元素( lapply )并隐藏输出 lapply 不可见):

 不可见(lapply(plots,print))




2)是否有可能在渲染时为每个绘图设置大小?我试过在块外设置一个大小变量,但只让我使用一个值而不是每个图的不同值。


是的。一般来说,当你将向量传递给图形相关的块选项时, i th 元素用于 i th 图。这适用于图形特定的选项,例如 fig.cap fig.scap out.width out.height



然而,其他数字选项是设备特定的。要理解这一点,重要的是看看选项 dev


dev :函数名称它将用作图形设备来记录选项 dev fig.ext fig.width fig.height dpi 较短的将被回收),例如<< foo,dev = c('pdf','png')>> = 为同一个图创建两个文件: foo.pdf foo.png


将向量传递给具体数字选项 out.height 时,会导致 i th 元素用于 i th ,将矢量传递给特定于设备选项将 i th 元素用于 i th因此,生成动态大小的图块需要对块进行一些黑客攻击,因为 1 组块不能使用不同的 fig.height 设置生成图。以下解决方案基于 knitr 示例`075-knit-expand.Rnw and (它解释了这个答案)。



该解决方案的想法是使用块模板并使用适当的表达式扩展模板值以生成块,然后使用正确的 fig.height 设置生成块。扩展模板被传递给 knit 以评估块:

  \documentclass {article} 
\ begin {document}

<<<< diamondlplots,echo = FALSE,results =asis>> ==
library(ggplot2)
library(knitr)

diamond_plot = function(data,cut_type){
ggplot(aes(color,fill = cut))+
geom_bar()+
ggtitle(paste(Cut:,cut_type,sep =))
}

cuts = unique(diamonds $ cut)

template < - data = subset(diamonds ,cut == cuts [i])
plot(diamond_plot(data,cuts [i]))
@

for(i in seq_along(cuts)){
cat(knit(text = knit_expand(text = template,i = i,height = 2 * i),quiet = TRUE))
}

@

$ end




模板使用 knit_expand 代替表达式s在 {{}} 各自的值。



对于 knit 调用,使用 quite = TRUE 非常重要。否则, knit 会以日志信息污染主文档。



使用 cat 对于避免隐含的 print 会很重要,否则会损害输出。出于同样的原因,外部块( diamond_plots )使用 results =asis


I want to be able to print out non-predetermined list of plots in knitr. I am able to do that, but there are a few wrinkles left to iron out. Namely:

1) How do you suppress the list indices (like [[2]]) on each page that precede each plot? Using echo=FALSE doesn't do anything.

2) Is it possible to set the size for each plot as they are rendered? I've tried setting a size variable outside of the chunk, but that only lets me use one value and not a different value per plot.

I'm asking this as one question because they seem to speak to the same lesson, i.e., producing a list of plots.

Some sample code:

\documentclass{article}
\usepackage[margin=.5in, landscape]{geometry}
\begin{document}

<<diamond_plots, echo = FALSE, results = 'hide'>>==
library(ggplot2)

diamond_plot = function(data, cut_type){
  ggplot(data, aes(color, fill=cut)) + 
    geom_bar() +
    ggtitle(paste("Cut:", cut_type, sep = ""))
}

cuts = unique(diamonds$cut)
plots = list()
for(i in 1:length(cuts)){
    data = subset(diamonds, cut == cuts[i])
    plots[[i]] = diamond_plot(data, cuts[i])
}
height = 3
@

<<print_plots, results='asis', echo=FALSE,  fig.width=10, fig.height=height>>=
plots
@
\end{document}

The PDF of the plots looks like this:

解决方案

1) How do you suppress the list indices (like [[2]]) on each page that precede each plot? Using echo=FALSE doesn't do anything.

Plot each element in the list separately (lapply) and hide the output from lapply (invisible):

invisible(lapply(plots, print))

2) Is it possible to set the size for each plot as they are rendered? I've tried setting a size variable outside of the chunk, but that only let's me use one value and not a different value per plot.

Yes. In general, when you pass vectors to figure-related chunk options, the ith element is used for the ith plot. This applies to options that are "figure specific" like e.g. fig.cap, fig.scap, out.width and out.height.

However, other figure options are "device specific". To understand this, it is important to take a look at the option dev:

dev: the function name which will be used as a graphical device to record plots […] the options dev, fig.ext, fig.width, fig.height and dpi can be vectors (shorter ones will be recycled), e.g. <<foo, dev=c('pdf', 'png')>>= creates two files for the same plot: foo.pdf and foo.png

While passing a vector to the "figure specific" option out.height has the consequence of the ith element being used for the ith plot, passing a vector to the "device specific" option has the consequence of the ith element being used for the ith device.

Therefore, generating dynamically-sized plots needs some hacking on chunks because one chunk cannot generate plots with different fig.height settings. The following solution is based on the knitr example `075-knit-expand.Rnw and this post on r-bloggers.com (which explains this answer on SO).

The idea of the solution is to use a chunk template and expand the template values with the appropriate expressions to generate chunks that, in turn, generate the plots with the right fig.height setting. The expanded template is passed to knit in order to evaluate the chunk:

\documentclass{article}
\begin{document}

<<diamond_plots, echo = FALSE, results = "asis">>==
library(ggplot2)
library(knitr)

diamond_plot = function(data, cut_type){
  ggplot(data, aes(color, fill=cut)) +
    geom_bar() +
    ggtitle(paste("Cut:", cut_type, sep = ""))
}

cuts = unique(diamonds$cut)

template <- "<<plot-cut-{{i}}, fig.height = {{height}}, echo = FALSE>>=
    data = subset(diamonds, cut == cuts[i])
    plot(diamond_plot(data, cuts[i]))
@"

for (i in seq_along(cuts)) {
  cat(knit(text = knit_expand(text = template, i = i, height = 2 * i), quiet = TRUE))
}

@

\end{document}

The template is expanded using knit_expand which replaces the expressions in {{}} by the respective values.

For the knit call, it is important to use quite = TRUE. Otherwise, knit would pollute the main document with log information.

Using cat is important to avoid the implicit print that would deface the output otherwise. For the same reason, the "outer" chunk (diamond_plots) uses results = "asis".

这篇关于在knitr中打印动态大小的图表列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆