Knitr Ignoring Fig.Pos

Knitr ignoring fig.pos?

The chunk option fig.pos is only used when knitr thinks it has to write out a LaTeX figure environment instead of pure Markdown ![](), and it writes LaTeX only when a figure caption (fig.cap) is specified, and at least one of these options has been specified: fig.align, out.width, out.extra. If you want to force knitr to write LaTeX code for figures and use fig.pos, you may set the chunk option out.extra = ''.

How to hold figure position with figure caption in pdf output of knitr?

As Yihui mentioned in his answer (Figure position in markdown when converting to PDF with knitr and pandoc), we cannot expect too much about formatting from mardown. To workaround this problem, just write some R scripts to replace htbp to H.

Compared with knit from knitr package, I found render from rmarkdown is better to export a tex file. Just remember to add keep_tex: yes in the yaml header of your rmarkdown file.

library(rmarkdown)
render('filepath.Rmd')
x <- readLines('filepath.tex')
pos <- grep('begin\\{figure\\}\\[htbp\\]', x)
x[pos] <- gsub('htbp', 'H', x[pos])
writeLines(x, 'filepath.tex')
tools::texi2pdf('filepath.tex', clean = TRUE) # gives foo.pdf

file.remove('filepath.tex')

Figure position in markdown when converting to PDF with knitr and pandoc

I'm not aware of such an option for pandoc to set the floating option of figures when converting a Markdown document to LaTeX. If you choose Markdown for its simplicity, you should not expect too much power from it, even with powerful tools like pandoc. Bottom line: Markdown is not LaTeX. It was designed for HTML instead of LaTeX.

Two ways to go:

  1. use the Rnw syntax (R + LaTeX) instead of Rmd (R Markdown) (examples); then you will be able to use the chunk option fig.pos='H' after you \usepackage{float} in the preamble; in this case, you have full power of LaTeX, and pandoc will not be involved

  2. hack at the LaTeX document generated by pandoc, e.g. something like

    library(knitr)
    knit('foo.Rmd') # gives foo.md
    pandoc('foo.md', format='latex') # gives foo.tex
    x = readLines('foo.tex')
    # insert the float package
    x = sub('(\\\\begin\\{document\\})', '\\\\usepackage{float}\n\\1', x)
    # add the H option for all figures
    x = gsub('(\\\\begin\\{figure\\})', '\\1[H]', x)
    # write the processed tex file back
    writeLines(x, 'foo.tex')
    # compile to pdf
    tools::texi2pdf('foo.tex') # gives foo.pdf

If you do not like these solutions, consider requesting a new feature to pandoc on Github, then sit back and wait.

Internationalization R knitr Figure caption label

You can actually include LaTeX code directly within the Rmd file to alter the settings.

As this answer explains, names like "Figure" and "Contents" are stored in macros like \figurename and \contentsname. To change them, you have to change the definition of the respective macros using \renewcommand within your preamble:

\renewcommand{\figurename}{Fig.}
\renewcommand{\contentsname}{Table of Contents}

Here's a list of the "name macros" (and their default meaning) defined by the LaTeX standard classes article, book, and report:

  • \abstractname [only article, report]: Abstract
  • \appendixname: Appendix
  • \bibname [only book, report]: Bibliography
  • \chaptername [only book, report]: Chapter
  • \contentsname: Contents
  • \figurename: Figure
  • \indexname: Index
  • \listfigurename: List of Figures
  • \listtablename: List of Tables
  • \partname: Part
  • \refname [only article]: References
  • \tablename: Table

Here is a MWE for your scenario:

---
output:
pdf_document: default
---
\renewcommand{\figurename}{YOUR LABEL}
\renewcommand{\tablename}{TABLE LABEL}

```{r Table, echo =FALSE}
knitr::kable(iris[1:5,], caption = "A table")
```

```{r pressure, echo=FALSE, fig.cap="Test Caption"}
plot(pressure)
```

Alternative Approach

The fantastic package bookdown expands a lot on the basics of RMarkdown and knitr. One thing the package allows you to set internalisation, as explained here.

knitr plots, labels, and captions within one chunk

Short answer is it seems to be a LaTeX issue caused by too many \includegraphics commands and no pagebreaks. Function to accomplish multiple figures with captions and labels from within loop (with credit to Steve Powell and 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.

This can be modified to add any of chunk options you would like.

Long Answer:
Here is what I did to get it to work. I downloaded knitr from github, made the suggested alteration above, compiled, and ran example. The altered code did not change the outcome. Further investigation of latex error took me to the LaTeX FAQ where it states:

The error also occurs in a long sequence of float environments, with no intervening text. Unless the environments will fit “here” (and you’ve allowed them to go “here”), there will never be a page break, and so there will never be an opportunity for LaTeX to reconsider placement. (Of course, the floats can’t all fit “here” if the sequence is sufficiently prolonged: once the page fills, LaTeX won’t place any more floats, leading to the error.

Techniques for resolution may involve redefining the floats using the float package’s [H] float qualifier, but you are unlikely to get away without using \clearpage from time to time.

So, I added

cat('\\clearpage')

after the plots are generated in each step of the loop. This resulted in no errors being thrown and the figures in correct locations. Also,

cat('\\newpage')

works and seems to do a better job at placing the figures 2 on a page in my actual document.

The working code:

\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}


Related Topics



Leave a reply



Submit