Figure Caption in R markdown

Hi!

I want to create a PDF document by R Markdown with lots of graphs. I want to keep track of the plots. So I would like to ad Figure 1, Figure 2, Figure 3, ... etc.

I know about fig_caption: yes, but simply adding this didn't help.

I set fig.cap = TRUE in the beginning, but it displays "Figure 1: TRUE", "Figure 2: TRUE", etc.

I can't add fig.cap to each code chunk, as then I don't know how to do it for those chinks which create more than one plots.

Is there any way to achieve this, i.e. auto-numbering the figures without any other caption?

I would like to do the same for tables also, but that's not very necessary.

Thanks

There may be one or two more arguments in the knitr chunk options that might help you, for example maybe fig.path-label-i?

From the knitr package documentation:
"Note any number of plots can be recorded in a single code chunk, and this package does not need to know how many plots are in a chunk in advance – it can figure out automatically, and name these images as fig.path-label-i where i is incremental from 1; if a code chunk does not actually produce any plots, knitr will not record anything either (the graphics device is open only when plots are really produced); in other words, it does not matter if fig.keep='high' but no plots were produced."

Fully described here: https://yihui.name/knitr/options/#plots.

Cheers, Steph

1 Like

I guess if you used fig.cap = "" on each one you'd get Figure 1:, Figure 2:, etc., but I suppose you'd rather not have the colons afterward, huh? That's tricky :thinking:

Unfortunately I don't have an example—I have not had multiple plots in the same code chunk needing different figure headings.

It might make it easier for folks to help you if you posted a reproducible example—or a "reprex"—of what you trying to do?

1 Like

rensa, You're right that I will prefer without the colons, but did you get it? I mean, I tried the same earlier, but knitr considered that to be NULL and didn't show any caption. You'll find that in my following example to stephhazlitt.

Here's the example.

---
title: "Example"
date: "8 April 2018"
output: 
  pdf_document: 
    fig_caption: yes
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(fig.cap = "", fig.path = "Plot")
```

Bla...Bla...Bla
```{r Chunk_1}
x <- rnorm(10)
plot(x)
```

Bla...Bla...Bla
```{r Chunk_2}
y <- rcauchy(10)
z <- runif(10)
plot(y)
plot(z)
```

As an output, I got this.

try.pdf (137.7 KB)

In the circled parts, I want to have Figure 1, Figure 2, Figure 3. Instead, I get the following files in my working directory.

try-screenshot


Edit (for following two replies)

When I'm using fig.cap = " ", it behaves exactly the same as fig.cap = "".

I haven't tried captioner yet, but certainly it looks interesting.

I'll update if it solves the problem.

rensa, my Latex is frustratingly horrible :cry:. I tried a lot, but didn't get it.

I always got the error ! Package caption Error: \caption outside float.

Can you please provide an example?

Thanks.

1 Like

Yep, I understand what you mean :slight_smile: Are you only outputting to PDF? If so, the nuclear option might be to modify the LaTeX template under the hood to not use colons in Figure numbering.

I'm not 100% sure what that looks like, but one option as per this answer on LaTeX might be to add \usepackage{caption} to your YAML:

title: "Example"
date: "8 April 2018"
output: 
  pdf_document: 
    fig_caption: yes
header-includes:
- \usepackage{caption}
---

Does this work for you?

OK, with some playing I found it worked for me with your code above, you need a space in fig.cap=" ". If you don't want the files for each plot created you can remove fig.path. However, it does leave you with "Figure 1:" which is not ideal. I found this R package—captioner—looks promising?

Ah! I had a lot of that recently when I was trying to get the subfig package working. It turned out that RMarkdown + LaTeX didn't like the spaces or underscores in my filenames or chunk names, and they were breaking the LaTeX rendering completely. Changing both to hyphens fixed that problem for me.

Here is the yaml header and set options chunk I used:

---
title: "Example"
date: "9 April 2018"
output: 
  pdf_document
---

```{r set-options}
knitr::opts_chunk$set(cache=TRUE, message=FALSE, warning=FALSE, 
                      error=FALSE, fig.cap = " ")

And the output:
helping.pdf (123.2 KB)

So it works, but it is not ideal as it has the colons after the caption (e.g. Figure 1:) and using fig.cap seems to shift the plots to the end of the resulting PDF (which I know is useful for some ms submission formatting but maybe less so for other documents?).

I tried captioner and it seems to get the job done. I noticed that the vignette mentions that fig.cap is finicky in Rmd :disappointed_relieved:, they suggest adding captions using inline r code chunks .

Good luck! Cheers, Steph

1 Like

I'm really confused.

The following is my Rmd file following your hint.

---
title: "Example"
date: "8 April 2018"
output: 
  pdf_document: 
    fig_caption: yes
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(cache=TRUE, error=FALSE, fig.cap = " ", message=FALSE, warning=FALSE)
```

Bla...Bla...Bla...1

```{r Chunk_1}
x <- rnorm(10)
plot(x)
```

Bla...Bla...Bla...2

```{r Chunk_2}
y <- rcauchy(10)
z <- runif(10)
plot(y)
```

```{r Chunk_3}
plot(z)
```

Bla...Bla...Bla...3

This gives me the following output.

try.pdf (116.7 KB)

As you can see, there is no caption. Can you please point out the mistake?

For captioner, I tried a lot, but not totally satisfied. I tried the following.

---
title: "Example"
date: "8 April 2018"
output: 
  pdf_document: 
    fig_caption: yes
---

```{r setup, include=FALSE}
fig_caption <- captioner::captioner("Fig.")
fig_caption("first", "trying for the first time")
fig_caption("second", "trying for one more time")
fig_caption("third", "trying once again")
```

Bla...Bla...Bla...1

```{r Chunk_1, fig.cap = fig_caption("first")}
x <- rnorm(10)
plot(x)
```

Bla...Bla...Bla...2

```{r Chunk_2, fig.cap = fig_caption("second")}
y <- rcauchy(10)
z <- runif(10)
plot(y)
plot(z)
```

Bla...Bla...Bla...3

```{r Chunk_3, fig.cap = fig_caption("third", display = "cite")}
w <- rexp(20)
plot(w)
```

Bla...Bla...Bla...4

I got this output.

try_2.pdf (128.3 KB)

You can understand why I didn't like it. First of all, it shows awkward cations like "Figure 1: Fig. 1: What I wrote". Second, for the 2nd chink, that has two plots, the first caption counter (I don't know when was it initialized) can mark those differently, while my defined one can't. And, the other point is that all plots are at the end, which is not convenient for me to include in my college reports.

Since the display = "cite" worked correctly (without any text and ':'), I got hopeful and tried the same with removal of fig_caption: yes, but that attempt failed, as nothing changed.


Edit (for the next reply)

I have the following:

R: 3.4.4
RStudio: 1.1.442
MikTeX: 2.9.6637

sessionInfo()
## R version 3.4.4 (2018-03-15)
## Platform: x86_64-w64-mingw32/x64 (64-bit)
## Running under: Windows 10 x64 (build 16299)
##
## Matrix products: default
##
## locale:
## [1] LC_COLLATE=English_India.1252 LC_CTYPE=English_India.1252
## [3] LC_MONETARY=English_India.1252 LC_NUMERIC=C
## [5] LC_TIME=English_India.1252
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## loaded via a namespace (and not attached):
## [1] compiler_3.4.4 backports_1.1.2 magrittr_1.5 rprojroot_1.3-2
## [5] tools_3.4.4 htmltools_0.3.6 yaml_2.1.18 Rcpp_0.12.16
## [9] stringi_1.1.7 rmarkdown_1.9 knitr_1.20 stringr_1.3.0
## [13] digest_0.6.15 evaluate_0.10.1

I am fairly sure that all of these are updated. And, should there be any reason due to Windows and Mac?

I ran your first example as is and it worked (figures.pdf (114.6 KB)), so I am wondering about investigating other computer "meta" stuff -- are you running the latest versions of everything (R, RStudio and packages)? I ran this on two MacBooks (using MacTex for knitting to PDF)—one with the latest of everything and one with an older version of R.

Cheers, Steph

There is always a possibility it is a Mac-Windows thing :slightly_smiling_face:.

It is interesting that you get fig.cap working with captioner. What happens when you add some text in fig.cap instead of "" or " " in the example w/o using captioner?

Re: what you got working with captioner. This is where I ended my journey as well. At this point I think you have fig.cap working with captioner, however the options/design are not what you are after. I am afraid I don't have much more to offer on that side of things.

I found a way for modifying captions suitably for my need using captioner (thanks to @stephhazlitt and @jcblum). I mentioned them here. Though it still does not solve the problem of automation (I have been recommended against it there), I'm marking this thread to be solved.

2 Likes

Hi there, this may be a little late, as the thread has been marked solved, but I have just been struggling with the same problem.

The solution I found was just to replace any underscores (_) in the code chunk label with a dash (-).

This solved the ´! Package caption Error: \caption outside float. rmarkdown´ error.

An example of a chunk that gave the error:

{r old_figure_label, echo = FALSE, message=FALSE, fig.align='center', fig.cap='Figure caption as whaterver you want it to be', out.width='0.95\\linewidth', fig.pos='H'}
knitr::include_graphics("address/to/image.pdf")

An example of a chunk that does not give the error

{r old-figure-label, echo = FALSE, message=FALSE, fig.align='center', fig.cap='Figure caption as whaterver you want it to be', out.width='0.95\\linewidth', fig.pos='H'}
knitr::include_graphics("address/to/image.pdf")

This way you can still reference your image in text, while keeping the flexibility of the knitr chunk options.

5 Likes