【问题标题】:knitr plots, labels, and captions within one chunk一大块内的 knitr 绘图、标签和标题
【发布时间】:2023-03-30 12:42:01
【问题描述】:

我正在生成一个乳胶报告,该报告在 dlply 调用中生成多个图。 dlply 调用当然是在一个单独的块中,为了让标签和标题发生变化,我使用了来自下面Steve Powell 的 sn-p。该方法有效,但似乎 knitr 并没有正确格式化输出。一个简单的例子说明:

\documentclass{article}

\begin{document}
<startup,echo=FALSE,results='hide',message=FALSE,tidy=FALSE,warning=FALSE,fig.keep='all',comment=NA>>=
require(knitr)
require(ggplot2)
opts_knit$set(progress = F, verbose = F)
opts_chunk$set(comment=NA,
           tidy=FALSE,
           warning=FALSE, 
           message=FALSE, 
           echo=FALSE, 
           dpi=600,
           fig.width=6.75, fig.height=4, # Default figure widths
           dev=c("pdf",'tiff'),
           dev.args=list(pdf=list(NULL),tiff=list(compression='lzw')),
           error=FALSE)
@
<<plotloop,results='asis'>>=
for(x in seq(1,20)){
  x1<-data.frame(x=seq(1,10),y=seq(1,10))
  plt<-ggplot(data=x1,aes(x,y))+geom_point()
  figLabel=paste('Figure',x,sep='')
  capt<-paste('Caption for fig.',x)
  cat(knit(text=(paste("<<",figLabel,",fig.pos='ht',fig.cap='",capt,"'>>=\nplt\n@",sep=''))))
}
@
\end{document}

这几乎可行。问题是 knitr 将结束 \caption 大括号放在 \label 大括号之外,这可以在下面 .tex 文件的 sn-p 中看到:

\begin{knitrout}
\definecolor{shadecolor}{rgb}{0.969, 0.969, 0.969}
\color{fgcolor}
\begin{figure}[ht]
\includegraphics[width=\maxwidth]{figure/Figure1} \caption[Caption for fig]{Caption for fig. 1\label{fig:Figure1}}
\end{figure}
\end{knitrout}

latex 可以处理这种情况,如果只有几个这样的数字,但如果有大量的地块,它就会开始错误地放置它们。 我也试过这个

fig.cap=paste('testLoop',seq(1,20))

接近并获得相同的结果。

进一步澄清:我在wikipedia's Latex/Floats... 页面上找到了这个:

如果你想标记一个图形以便以后可以引用它,你必须在标题之后添加标签(内部似乎在 LaTeX 2e 中工作)但在浮动环境中。如果在外面声明,会给出节号。

“内部似乎在 LaTeX 2e 中工作”部分引起了我的注意。似乎它只是因为错误被忽略了多次才有效?我在用 LaTeX2e 。 我认为代码位在 hooks-latex.R 的 hook_plot_tex 函数第 120 行:

fig2 = sprintf('\\caption%s{%s\\label{%s}}\n\\end{%s}\n', scap, cap,
                 paste(lab, if (mcap) fig.cur, sep = ''), options$fig.env)  

这样可以解决吗?

fig2 = sprintf('\\caption%s{%s}\\label{%s}\n\\end{%s}\n', scap, cap,
                 paste(lab, if (mcap) fig.cur, sep = ''), options$fig.env)

建议?我对github的流程不熟悉... 谢谢!

【问题讨论】:

    标签: r knitr


    【解决方案1】:

    简短的回答是它似乎是由太多 \includegraphics 命令和没有分页符引起的 LaTeX 问题。从循环内完成带有标题和标签的多个图形的功能(感谢 Steve Powell 和 Yihui):

    plot.knit<-function(chunkLabel,#text for chunk label which is also used for figure file name
                    capt,#text for caption
                    plt)#plot object to be placed
       {
        cat(knit(text=(paste("<<",chunkLabel,",fig.pos='h',fig.cap='",capt,"'>>=\nplt\n@",sep=''))))
    }
    cat('\\newpage')#some sort of page break must be inserted along the way to keep latex from breaking.
    

    可以修改它以添加您想要的任何块选项。

    长答案: 这是我为使其正常工作所做的工作。我从 github 下载了 knitr,在上面进行了建议的更改,编译并运行了示例。修改后的代码并没有改变结果。对乳胶错误的进一步调查将我带到了LaTeX FAQ,它指出:

    错误也发生在长序列的浮动环境中,没有中间文本。除非环境适合“这里”(并且你允许它们去“这里”),否则永远不会出现分页符,因此 LaTeX 永远不会有机会重新考虑放置。 (当然,如果序列足够长,浮点数不能全部放在“这里”:一旦页面填满,LaTeX 将不再放置任何浮点数,从而导致错误。

    解析技术可能涉及使用 float 包的 [H] 浮点限定符重新定义浮点数,但如果不时不时使用 \clearpage,您不太可能逃脱。

    所以,我添加了

    cat('\\clearpage')
    

    在循环的每个步骤中生成图之后。这导致没有错误被抛出并且数字在正确的位置。还有,

    cat('\\newpage')
    

    在我的实际文档的页面上放置数字 2 时效果更好,而且似乎做得更好。

    工作代码:

    \documentclass{article}
    
        \begin{document}
    <<startup,echo=FALSE,results='hide',message=FALSE,tidy=FALSE,warning=FALSE,fig.keep='all',comment=NA>>=
    require(knitr)
    require(ggplot2)
    opts_knit$set(progress = F, verbose = F)
    opts_chunk$set(comment=NA,
               tidy=FALSE,
               warning=FALSE, 
               message=FALSE, 
               echo=FALSE, 
               dpi=600,
               fig.width=6.75, fig.height=4, # Default figure widths
               dev=c("pdf",'tiff'),
               dev.args=list(pdf=list(NULL),tiff=list(compression='lzw')),
               error=FALSE)
    @
    <<plotloop,results='asis'>>=
    for(x in seq(1,20)){
      x1<-data.frame(x=seq(1,10),y=seq(1,10))
      plt<-ggplot(data=x1,aes(x,y))+geom_point()
      figLabel=paste('Figure',x,sep='')
      capt<-paste('Caption for fig.',x)
      cat(knit(text=(paste("<<",figLabel,",fig.pos='h',fig.cap='",capt,"'>>=\nplt\n@",sep=''))))
    cat('\\newpage')
    }
    @
    
    \end{document}
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-02
    • 1970-01-01
    • 2012-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多