37

I'm writing an Rmd file, to be processed by knitr into HTML. It contains some R chunks that generate figures, which get stored as data URIs in HTML.

1) How do I add a caption to such an image? I'd like to have a caption that says something like "Figure 3: blah blah blah", where the "3" is automatically generated.

2) How do I later on reference this image, i.e., "as you can see in Figure 3, blah blah".

Ben
  • 41,615
  • 18
  • 132
  • 227
Jack Tanner
  • 934
  • 1
  • 8
  • 24
  • A few methods have appeared to do this, but hopefully it'll be rolled into knitr or pandoc: https://github.com/adletaw/captioner https://github.com/mkoohafkan/kfigr (noted below) http://galahad.well.ox.ac.uk/repro/ http://rmflight.github.io/posts/2012/10/papersinRmd.html (also noted below) http://gforge.se/2014/01/fast-track-publishing-using-knitr-part-iii/ – Ben Jan 13 '15 at 18:49
  • 2
    It looks like this IS getting direct support in knitr/pandoc now; see https://bookdown.org/yihui/bookdown/, particularly sections 2.3--2.5. – mikeck Apr 14 '16 at 16:19

7 Answers7

25

I'm late to the party, but I wanted to mention a small package I recently built to do figure captioning and cross-referencing with knitr. It is called kfigr and you can install it using devtools::install_github('mkoohafkan/kfigr'). It is still in active development but the main functionality is there. Be sure to check out the vignette, it shows some usage examples and defines some hooks for figure captions and anchors (I may later choose to have the package import knitr and define those hooks on load).

EDIT: kfigr is now available on CRAN!

mikeck
  • 3,534
  • 1
  • 26
  • 39
  • 4
    It looks like `kfigr` will become obsolete soon as `bookdown` is in beta testing: https://bookdown.org/yihui/bookdown/. I encourage folks to try `bookdown` as `kfigr` does not always play nice with `pandoc` and doesn't support markdown-->PDF. – mikeck Apr 14 '16 at 16:22
16
  1. You can create the figure numbers with a simple counter in R; see one example here. The problem is whether the markdown renderer will render the figure caption for you: R Markdown v1 won't, but v2 (based on Pandoc) will.
  2. I do not know. There is no direct way to insert a label as an identifier for figures, so it is probably not possible to cross reference figures with pure Markdown. Once you've got issues like this, think (1) do I really need it? (2) if it is intended to be a document with a complicated structure, I think it is better to use LaTeX directly (Rnw documents).
Yihui Xie
  • 28,913
  • 23
  • 193
  • 419
11

Also very late to the party I changed Yihuis suggestion here that he also linked above to do referencing.

```{r functions, include=FALSE}
# A function for captioning and referencing images
fig <- local({
    i <- 0
    ref <- list()
    list(
        cap=function(refName, text) {
            i <<- i + 1
            ref[[refName]] <<- i
            paste("Figure ", i, ": ", text, sep="")
        },
        ref=function(refName) {
            ref[[refName]]
        })
})
```
```{r cars, echo=FALSE, fig.cap=fig$cap("cars", "Here you see some interesting stuff about cars and such.")}
plot(cars)
```

What you always wanted to know about cars is shown in figure `r fig$ref("cars")`
user3355146
  • 163
  • 2
  • 6
  • Thanks @user3355146. The only issue is the fig$ref() can only be called after the figure was generated, i.e. Figure `r fig$ref("cars")` BELOW shows... etc etc. is not going to work. But still a very nice solution to solve my problem. thanks, – woshishui Jun 19 '16 at 02:27
5

One way to do both of these is described here: http://rmflight.github.io/posts/2012/10/papersinRmd.html

Another is described here (but I don't know if it does your #2). http://gforge.se/2014/01/fast-track-publishing-using-knitr-part-iii/

Tom
  • 4,860
  • 7
  • 43
  • 55
  • 1
    Since the new rmarkdown the workflow in my post needs to [be changed](http://gforge.se/2014/07/fast-track-publishing-using-rmarkdown/), I've currently implemented a few simple functions that do the job for adding a figure counter - even though it is not as elegant as before. The functions are present in the [Gmisc-package](http://gforge.se/packages/) and are `figCapNo`, `figCapNoLast`, and `figCapNoNext`- see how to use it int the documentation for the [first figCapNo](https://github.com/gforge/Gmisc/blob/master/R/figCaptionNo.R#L19). – Max Gordon Dec 10 '14 at 22:01
3

Another solution:

https://github.com/adletaw/captioner

From the README:

captioner() returns a captioner function for each set of figures, tables, etc. that you want to create. See the help files for more details.

For example:

> fig_nums <- captioner()

> fig_nums("my_pretty_figure", "my pretty figure's caption")

"Figure 1: my pretty figure's caption"

> fig_nums("my_pretty_figure", cite = TRUE)
Ed Hagen
  • 409
  • 4
  • 10
1

I did both (figure numbers + references) with bookdown. I added in output section in the header of the file:

output:
  bookdown::html_document2:
    fig_caption : TRUE

Then I created a figure in a R code chunk like follows:

{r, my-fig-label,echo=F, eval=T, fig.align = 'center', fig.cap="This is my caption"}
knitr::include_graphics(here::here("images", "my_image.png"))

This produces an automatic number under your figure. You can refer to it with \@ref(fig:my-fig-label).

karel
  • 5,489
  • 46
  • 45
  • 50
0

Using the official bookdown documentation 4.10 Numbered figure captions:

---
output: bookdown::html_document2
---

```{r cars, fig.cap = "An amazing plot"}
plot(cars)
```

```{r mtcars, fig.cap = "Another amazing plot"}
plot(mpg ~ hp, mtcars)
```
Cucurucho
  • 71
  • 3