2.4 Figures

By default, figures have no captions in the output generated by knitr, which means they will be placed wherever they were generated in the R code. Below is such an example.

par(mar = c(4, 4, .1, .1))
plot(pressure, pch = 19, type = 'b')

The disadvantage of typesetting figures in this way is that when there is not enough space on the current page to place a figure, it may either reach the bottom of the page (hence exceeds the page margin), or be pushed to the next page, leaving a large white margin at the bottom of the current page. That is basically why there are “floating environments” in LaTeX: elements that cannot be split over multiple pages (like figures) are put in floating environments, so they can float to a page that has enough space to hold them. There is also a disadvantage of floating things forward or backward, though. That is, readers may have to jump to a different page to find the figure mentioned on the current page. This is simply a natural consequence of having to typeset things on multiple pages of fixed sizes. This issue does not exist in HTML, however, since everything can be placed continuously on one single page (presumably with infinite height), and there is no need to split anything across multiple pages of the same page size.

If we assign a figure caption to a code chunk via the chunk option fig.cap, R plots will be put into figure environments, which will be automatically labeled and numbered, and can also be cross-referenced. The label of a figure environment is generated from the label of the code chunk, e.g., if the chunk label is foo, the figure label will be fig:foo (the prefix fig: is added before foo). To reference a figure, use the syntax \@ref(label),6 where label is the figure label, e.g., fig:foo.

To take advantage of Markdown formatting within the figure caption, you will need to use text references (see Section 2.2.4). For example, a figure caption that contains _italic text_ will not work when the output format is LaTeX/PDF, since the underscore is a special character in LaTeX, but if you use text references, _italic text_ will be translated to LaTeX code when the output is LaTeX.

If you want to cross-reference figures or tables generated from a code chunk, please make sure the chunk label only contains alphanumeric characters (a-z, A-Z, 0-9), slashes (/), or dashes (-).

The chunk option fig.asp can be used to set the aspect ratio of plots, i.e., the ratio of figure height/width. If the figure width is 6 inches (fig.width = 6) and fig.asp = 0.7, the figure height will be automatically calculated from fig.width * fig.asp = 6 * 0.7 = 4.2. Figure 2.1 is an example using the chunk options fig.asp = 0.7, fig.width = 6, and fig.align = 'center', generated from the code below:

par(mar = c(4, 4, .1, .1))
plot(pressure, pch = 19, type = 'b')
A figure example with the specified aspect ratio, width, and alignment.

FIGURE 2.1: A figure example with the specified aspect ratio, width, and alignment.

The actual size of a plot is determined by the chunk options fig.width and fig.height (the size of the plot generated from a graphical device), and we can specify the output size of plots via the chunk options out.width and out.height. The possible value of these two options depends on the output format of the document. For example, out.width = '30%' is a valid value for HTML output, but not for LaTeX/PDF output. However, knitr will automatically convert a percentage value for out.width of the form x% to (x / 100) \linewidth, e.g., out.width = '70%' will be treated as .7\linewidth when the output format is LaTeX. This makes it possible to specify a relative width of a plot in a consistent manner. Figure 2.2 is an example of out.width = 70%.

par(mar = c(4, 4, .1, .1))
plot(cars, pch = 19)
A figure example with a relative width 70\%.

FIGURE 2.2: A figure example with a relative width 70%.

If you want to put multiple plots in one figure environment, you must use the chunk option fig.show = 'hold' to hold multiple plots from a code chunk and include them in one environment. You can also place plots side by side if the sum of the width of all plots is smaller than or equal to the current line width. For example, if two plots have the same width 50%, they will be placed side by side. Similarly, you can specify out.width = '33%' to arrange three plots on one line. Figure 2.3 is an example of two plots, each with a width of 50%.

par(mar = c(4, 4, .1, .1))
plot(pressure, pch = 19, type = 'b')
plot(cars, pch = 19)
Two plots placed side by side.Two plots placed side by side.

FIGURE 2.3: Two plots placed side by side.

Sometimes you may have certain images that are not generated from R code, and you can include them in R Markdown via the function knitr::include_graphics(). Figure 2.4 is an example of three knitr logos included in a figure environment. You may pass one or multiple image paths to the include_graphics() function, and all chunk options that apply to normal R plots also apply to these images, e.g., you can use out.width = '33%' to set the widths of these images in the output document.

knitr::include_graphics(rep('images/knit-logo.png', 3))
Three knitr logos included in the document from an external PNG image file.Three knitr logos included in the document from an external PNG image file.Three knitr logos included in the document from an external PNG image file.

FIGURE 2.4: Three knitr logos included in the document from an external PNG image file.

There are a few advantages of using include_graphics():

  1. You do not need to worry about the document output format, e.g., when the output format is LaTeX, you may have to use the LaTeX command \includegraphics{} to include an image, and when the output format is Markdown, you have to use ![](). The function include_graphics() in knitr takes care of these details automatically.
  2. The syntax for controlling the image attributes is the same as when images are generated from R code, e.g., chunk options fig.cap, out.width, and fig.show still have the same meanings.
  3. include_graphics() can be smart enough to use PDF graphics automatically when the output format is LaTeX and the PDF graphics files exist, e.g., an image path foo/bar.png can be automatically replaced with foo/bar.pdf if the latter exists. PDF images often have better qualities than raster images in LaTeX/PDF output. To make use of this feature, set the argument auto_pdf = TRUE, or set the global option options(knitr.graphics.auto_pdf = TRUE) to enable this feature globally in an R session.
  4. You can easily scale these images proportionally using the same ratio. This can be done via the dpi argument (dots per inch), which takes the value from the chunk option dpi by default. If it is a numeric value and the chunk option out.width is not set, the output width of an image will be its actual width (in pixels) divided by dpi, and the unit will be inches. For example, for an image with the size 672 x 480, its output width will be 7 inches (7in) when dpi = 96. This feature requires the package png and/or jpeg to be installed. You can always override the automatic calculation of width in inches by providing a non-NULL value to the chunk option out.width, or use include_graphics(dpi = NA).

  1. Do not forget the leading backslash! And also note the parentheses () after ref; they are not curly braces {}.↩︎