Figure Caption in R markdown


#1

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


Avoiding repetitive LaTeX codes in R Markdown
#2

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


#3

I am very bad at going through documentations. :disappointed:

But I am sorry to say that your suggestion did not solve my problem.

The method you suggested saves the plots in the working directory with the prefix I provided. But I just wanted to make those names appear at my document above or below the graphs.

If you are able to do so (using this method or otherwise), can you please provide an example?


#4

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:


#5

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?


#6

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 example to @stephhazlitt.


#7

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


#8

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?


#9

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?


#10

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.


#11

:cry:

My Latex is frustratingly horrible. 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.


#12

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.


#13

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


#14

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.


#15

Sorry, I failed once again. I tried the following.

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

Bla...Bla...Bla

```{r}
x <- rnorm(10)
pdf("first.pdf")
plot(x)
dev.off()
```

\includegraphics{first.pdf}
\caption[text1]{abracadabra}

Bla...Bla...Bla

```{r}
y <- rcauchy(10)
z <- runif(10)
pdf("second.pdf")
plot(y)
dev.off()
pdf("third.pdf")
plot(z)
dev.off()
```

\includegraphics{second.pdf}
\caption[text2]{something}

\includegraphics{third.pdf}
\caption[third]{}

I got the same error, as you can find below.


#16

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


#17

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?


#18

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.


#19

If I use fig.cap = "abc", then there'll be cations and they'll be of the form "Figure 1: abc", "Figure 2: abc", etc.

I found this link.

I don't think I'll get anything not starting with Figure n, where n is natural. Even if I save the files separately and include by ![caption](file.extension), that remains present.

It'll be nice if someone knows how to control that text and the counter.

Thanks


#20

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.