作者:Yihui Xie
译者:郑宝童
日期:2021.05.17


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.

默认情况下,在knitr生成的输出中图形没有标题,这意味着它们将被放置在R代码中生成它们的地方。下面就是这样一个例子。

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

2.4 图片-ing - 图1

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.

以这种方式排版图片的缺点是:当当前页面上没有足够的空间放置一个图,它可以触到页面的底部(因此超过页面边缘),或被推到下一个页面,给本页留下一个巨大的白色边缘。这就是为什么在LaTeX中会有“浮动环境”(floating environments):不能被分割到多个页面的元素(比如图形)被放在浮动环境中,这样它们就可以浮动到有足够空间容纳它们的页面中。但是,向前或向后浮动也有一个缺点。也就是说,读者可能必须跳转到另一个页面才能找到当前页面中提到的图形,这是在多个固定大小的页面上排版的自然结果。然而,这个问题在HTML中并不存在,(因为所有内容都可以连续地放在一个页面上(html是无限高的)),并且没有必要将任何内容分割到相同页面大小的多个页面上。

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:

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

2.4 图片-ing - 图2
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%.

  1. par(mar = c(4, 4, 0.1, 0.1))
  2. plot(cars, pch = 19)

2.4 图片-ing - 图3
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%.

  1. par(mar = c(4, 4, 0.1, 0.1))
  2. plot(pressure, pch = 19, type = "b")
  3. plot(cars, pch = 19)

2.4 图片-ing - 图42.4 图片-ing - 图5
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.

  1. knitr::include_graphics(rep("images/knit-logo.png", 3))

2.4 图片-ing - 图62.4 图片-ing - 图72.4 图片-ing - 图8
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 {}.↩︎