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.
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')
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)
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)
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.
::include_graphics(rep('images/knit-logo.png', 3)) knitr
There are a few advantages of using include_graphics()
:
- 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 functioninclude_graphics()
in knitr takes care of these details automatically. - 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
, andfig.show
still have the same meanings. 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 pathfoo/bar.png
can be automatically replaced withfoo/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 argumentauto_pdf = TRUE
, or set the global optionoptions(knitr.graphics.auto_pdf = TRUE)
to enable this feature globally in an R session.- 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 optiondpi
by default. If it is a numeric value and the chunk optionout.width
is not set, the output width of an image will be its actual width (in pixels) divided bydpi
, 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
) whendpi = 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 optionout.width
, or useinclude_graphics(dpi = NA)
.
Do not forget the leading backslash! And also note the parentheses
()
afterref
; they are not curly braces{}
.↩︎