9

I would like to place the caption above the figure using knitr in texmaker. I know that this question has already been asked, and I understand that the solution suggested so far is to use:

\begin{figure} 
\caption{This is a caption above the figure} 
<<a-plot, echo=FALSE>>= 
plot(1) 
@ 
\end{figure} 

But in this way I cannot show the code (since echo=FALSE). And if I choose instead echo=TRUE, what I get is the caption, then the codes, and then the graph, which is also not what I want. What I would like to show is the code for R, (and) the graph plotted with that R code, with the caption above the graph.

Michael Harper
  • 14,721
  • 2
  • 60
  • 84
Serena
  • 123
  • 1
  • 4

4 Answers4

13

My preference tends to be to use LaTeX packages to achieve customisation like this: there is a large community on Tex StackExchange who have developed methods to load of problems similar to this.

The floatrow package can be used to reposition the caption above the figure. This is largely based on this previous answer.

Using R Markdown, as this is the most typically used workflow these days, the package can be loaded by including header-includes argument within the YAML, as follows:

---
output: pdf_document
header-includes:
   - \usepackage{floatrow}
   - \floatsetup[figure]{capposition=top}
---


```{r fig.cap="cap, cap, and cap"}
plot(1)
```

The output has the desired order with the code displayed first, followed by the caption then the plot.

enter image description here

If the code is not wanted, the echo=FALSE option can be added to the chunk header.

Tung
  • 26,371
  • 7
  • 91
  • 115
Michael Harper
  • 14,721
  • 2
  • 60
  • 84
3

Try using hook:

<<include=FALSE>>=
f <- function(x, options) {
  paste("\\end{kframe}\n", 
        "\\caption{", options$capT, "}\n", 
        hook_plot_tex(x, options), 
        "\n\\begin{kframe}", sep = "")
}
knit_hooks$set(plot = f)
@

\begin{figure} 
<<a-plot, echo=TRUE, capT="cap, cap, and cap">>= 
plot(1) 
@ 
\end{figure} 

enter image description here

kohske
  • 65,572
  • 8
  • 165
  • 155
  • Thanks a lot for your answer! But I tried to use exactly your example, and I got an error message from Texmaker, saying that " object 'knit_hooks' not found". I am really new with texmaker, knitr and hook. Do you have an idea why this didn't work for me? – Serena Jul 15 '14 at 15:07
  • @Serena insert `library(knitr)` at the beginning of the first chunk. – kohske Jul 16 '14 at 00:59
  • Great solution, thanks! But 2 drawbacks: 1) need to add \begin{figure} oneself, 2) need to change fig.cap to new figT. The first problem is easily solved (just add: \\begin{figure}\n","\\end{figure}\n" in f). The second problem seems very difficult to address, as using fig.cap triggers the automatic insertion of \caption below the figure, and it seems the only way to avoid this would be to rewrite completely hook_plot_tex... – Matifou Nov 11 '14 at 21:56
1

This is a slighty modified version of kohske's answer, that includes \begin{figure} and adds \label. Note however that it contains 5 lines, while the original code contains more than 150 lines, so it should be used in very limited settings.

f <- function(x, options) {
  lab <- paste0(options$fig.lp, options$label)
  paste("\\end{kframe}\n", 
        "\\begin{figure}\n\\caption{", options$capT, "}\\label{", lab,"}\n", 
        hook_plot_tex(x, options), 
        "\\end{figure}\n\n\\begin{kframe}", sep = "")
}
knit_hooks$set(plot = f)
CL.
  • 14,577
  • 5
  • 46
  • 73
Matifou
  • 7,968
  • 3
  • 47
  • 52
0

Add a new block below it, with the same name, to print the code.

     \documentclass{article}
     \begin{document}
     \begin{figure} 
     \caption{This is a caption above the figure} 
     <<a-plot, echo=FALSE>>= 
     plot(1) 
     @ 
     \end{figure} 
     <<a-plot,echo=TRUE>>=
     @

\end{document}

Dan Wright
  • 11
  • 2