is there a simple way (e.g., via a chunk option) to get a chunk's source code and the plot it produces side by side, as on page 8 (among others) of this document?
是否有一种简单的方法(例如,通过块选项)来获取块的源代码和它并排生成的图,如本文档的第8页(以及其他)?
I tried using out.width="0.5\\textwidth", fig.align='right'
, which makes the plot correctly occupy only half the page and be aligned to the right, but the source code is displayed on top of it, which is the normal behaviour. I would like to have it on the left side of the plot.
我尝试使用out.width =“0.5 \\ textwidth”,fig.align ='right',这使得绘图正确占据页面的一半并与右边对齐,但源代码显示在其上,这是正常的行为。我想把它放在情节的左侧。
Thanks
谢谢
Sample code:
示例代码:
<<someplot, out.width="0.5\\textwidth", fig.align='right'>>=
plot(1:10)
@
3 个解决方案
#1
8
Well, this ended up being trickier than I'd expected.
好吧,这最终比我想象的更棘手。
On the LaTeX side, the adjustbox package gives you great control over alignment of side-by-side boxes, as nicely demonstrated in this excellent answer over on tex.stackexchange.com. So my general strategy was to wrap the formatted, tidied, colorized output of the indicated R chunk with LaTeX code that: (1) places it inside of an adjustbox environment; and (2) includes the chunk's graphical output in another adjustbox environment just to its right. To accomplish that, I needed to replace knitr's default chunk output hook with a customized one, defined in section (2)
of the document's <<setup>>=
chunk.
在LaTeX方面,adjustbox软件包可以很好地控制并排盒的对齐,这在tex.stackexchange.com上的优秀答案中得到了很好的证明。所以我的一般策略是用LaTeX代码包装指定的R chunk的格式化,整理,着色输出:(1)将它放在adjustbox环境中; (2)将块的图形输出包含在右侧的另一个调整框环境中。为了实现这一点,我需要将knitr的默认块输出钩子替换为自定义的钩子,在文档的<< setup >> = chunk的第(2)节中定义。
Section (1)
of <<setup>>=
defines a chunk hook that can be used to temporarily set any of R's global options (and in particular here, options("width")
) on a per-chunk basis. See here for a question and answer that treat just that one piece of this setup.
<< setup >>的第(1)节定义了一个块钩子,它可以用来临时设置任何R的全局选项(特别是这里,选项(“width”))。请看这里的问题和答案,只处理这个设置的一部分。
Finally, Section (3)
defines a knitr "template", a bundle of several options that need to be set each time a side-by-side code-block and figure are to be produced. Once defined, it allows the user to trigger all of the required actions by simply typing opts.label="codefig"
in a chunk's header.
最后,Section(3)定义了一个knitr“模板”,这是一组需要在每次生成并排代码块和图形时需要设置的几个选项。一旦定义,它允许用户通过在块的标题中键入opts.label =“codefig”来触发所有必需的操作。
\documentclass{article}
\usepackage{adjustbox} %% to align tops of minipages
\usepackage[margin=1in]{geometry} %% a bit more text per line
\begin{document}
<<setup, include=FALSE, cache=FALSE>>=
## These two settings control text width in codefig vs. usual code blocks
partWidth <- 45
fullWidth <- 80
options(width = fullWidth)
## (1) CHUNK HOOK FUNCTION
## First, to set R's textual output width on a per-chunk basis, we
## need to define a hook function which temporarily resets global R's
## option() settings, just for the current chunk
knit_hooks$set(r.opts=local({
ropts <- NA
function(before, options, envir) {
if (before) {
ropts <<- options(options$r.opts)
} else {
options(ropts)
}
}
}))
## (2) OUTPUT HOOK FUNCTION
## Define a custom output hook function. This function processes _all_
## evaluated chunks, but will return the same output as the usual one,
## UNLESS a 'codefig' argument appeared in the chunk's header. In that
## case, wrap the usual textual output in LaTeX code placing it in a
## narrower adjustbox environment and setting the graphics that it
## produced in another box beside it.
defaultChunkHook <- environment(knit_hooks[["get"]])$defaults$chunk
codefigChunkHook <- function (x, options) {
main <- defaultChunkHook(x, options)
before <-
"\\vspace{1em}\n
\\adjustbox{valign=t}{\n
\\begin{minipage}{.59\\linewidth}\n"
after <-
paste("\\end{minipage}}
\\hfill
\\adjustbox{valign=t}{",
paste0("\\includegraphics[width=.4\\linewidth]{figure/",
options[["label"]], "-1.pdf}}"), sep="\n")
## Was a codefig option supplied in chunk header?
## If so, wrap code block and graphical output with needed LaTeX code.
if (!is.null(options$codefig)) {
return(sprintf("%s %s %s", before, main, after))
} else {
return(main)
}
}
knit_hooks[["set"]](chunk = codefigChunkHook)
## (3) TEMPLATE
## codefig=TRUE is just one of several options needed for the
## side-by-side code block and a figure to come out right. Rather
## than typing out each of them in every single chunk header, we
## define a _template_ which bundles them all together. Then we can
## set all of those options simply by typing opts.label="codefig".
opts_template[["set"]](
codefig = list(codefig=TRUE, fig.show = "hide",
r.opts = list(width=partWidth),
tidy = TRUE,
tidy.opts = list(width.cutoff = partWidth)))
@
A chunk without \texttt{opts.label="codefig"} set...
<<A>>=
1:60
@
\texttt{opts.label="codefig"} \emph{is} set for this one
<<B, opts.label="codefig", fig.width=8, cache=FALSE>>=
library(raster)
library(RColorBrewer)
## Create a factor raster with a nice RAT (Rast. Attr. Table)
r <- raster(matrix(sample(1:10, 100, replace=TRUE), ncol=10, nrow=10))
r <- as.factor(r)
rat <- levels(r)[[1]]
rat[["landcover"]] <- as.character(1:10)
levels(r) <- rat
## To get a nice grid...
p <- as(r, "SpatialPolygonsDataFrame")
## Plot it
plot(r, col = brewer.pal("Set3", n=10),
legend = FALSE, axes = FALSE, box = FALSE)
plot(p, add = TRUE)
text(p, label = getValues(r))
@
\texttt{opts.label="codefig"} not set, and all settings back to ``normal''.
<<C>>=
lm(mpg ~ cyl + disp + hp + wt + gear, data=mtcars)
@
\end{document}
#2
4
I see 3 possibilities
我看到3种可能性
- for
beamer
presentations, I'd go for\begin{columns}
...\end{columns}
as well. - 对于投影仪演示,我会去\ begin {columns} ... \ end {columns}。
- If it is only one such plot: Minipages
- 如果它只是一个这样的情节:小型商品
- Here I used a table (column code and column result). (This example is "normal" Sweave)
- 这里我使用了一个表(列代码和列结果)。 (这个例子是“正常”的Sweave)
For all three, the chunk options would have include = FALSE
, and the plot would "manually" be put to the right place by \includegraphics[]{}
.
对于所有这三个,块选项将包括= FALSE,并且将通过\ includegraphics [] {}“手动”将绘图放到正确的位置。
#3
2
You can display the text in a 'textplot' from package PerformanceAnalytics or gplots.
您可以在PerformanceAnalytics或gplots包中的“textplot”中显示文本。
(Little) downside: To my knowledge there is no Syntax highlighting possible.
(小)缺点:据我所知,没有语法突出显示可能。
Sample Code:
示例代码:
```{r fig.width=8, fig.height=5, fig.keep = 'last', echo=FALSE}
suppressMessages(library(PerformanceAnalytics))
layout(t(1:2))
textplot('plot(1:10)')
plot(1:10)
```
#1
8
Well, this ended up being trickier than I'd expected.
好吧,这最终比我想象的更棘手。
On the LaTeX side, the adjustbox package gives you great control over alignment of side-by-side boxes, as nicely demonstrated in this excellent answer over on tex.stackexchange.com. So my general strategy was to wrap the formatted, tidied, colorized output of the indicated R chunk with LaTeX code that: (1) places it inside of an adjustbox environment; and (2) includes the chunk's graphical output in another adjustbox environment just to its right. To accomplish that, I needed to replace knitr's default chunk output hook with a customized one, defined in section (2)
of the document's <<setup>>=
chunk.
在LaTeX方面,adjustbox软件包可以很好地控制并排盒的对齐,这在tex.stackexchange.com上的优秀答案中得到了很好的证明。所以我的一般策略是用LaTeX代码包装指定的R chunk的格式化,整理,着色输出:(1)将它放在adjustbox环境中; (2)将块的图形输出包含在右侧的另一个调整框环境中。为了实现这一点,我需要将knitr的默认块输出钩子替换为自定义的钩子,在文档的<< setup >> = chunk的第(2)节中定义。
Section (1)
of <<setup>>=
defines a chunk hook that can be used to temporarily set any of R's global options (and in particular here, options("width")
) on a per-chunk basis. See here for a question and answer that treat just that one piece of this setup.
<< setup >>的第(1)节定义了一个块钩子,它可以用来临时设置任何R的全局选项(特别是这里,选项(“width”))。请看这里的问题和答案,只处理这个设置的一部分。
Finally, Section (3)
defines a knitr "template", a bundle of several options that need to be set each time a side-by-side code-block and figure are to be produced. Once defined, it allows the user to trigger all of the required actions by simply typing opts.label="codefig"
in a chunk's header.
最后,Section(3)定义了一个knitr“模板”,这是一组需要在每次生成并排代码块和图形时需要设置的几个选项。一旦定义,它允许用户通过在块的标题中键入opts.label =“codefig”来触发所有必需的操作。
\documentclass{article}
\usepackage{adjustbox} %% to align tops of minipages
\usepackage[margin=1in]{geometry} %% a bit more text per line
\begin{document}
<<setup, include=FALSE, cache=FALSE>>=
## These two settings control text width in codefig vs. usual code blocks
partWidth <- 45
fullWidth <- 80
options(width = fullWidth)
## (1) CHUNK HOOK FUNCTION
## First, to set R's textual output width on a per-chunk basis, we
## need to define a hook function which temporarily resets global R's
## option() settings, just for the current chunk
knit_hooks$set(r.opts=local({
ropts <- NA
function(before, options, envir) {
if (before) {
ropts <<- options(options$r.opts)
} else {
options(ropts)
}
}
}))
## (2) OUTPUT HOOK FUNCTION
## Define a custom output hook function. This function processes _all_
## evaluated chunks, but will return the same output as the usual one,
## UNLESS a 'codefig' argument appeared in the chunk's header. In that
## case, wrap the usual textual output in LaTeX code placing it in a
## narrower adjustbox environment and setting the graphics that it
## produced in another box beside it.
defaultChunkHook <- environment(knit_hooks[["get"]])$defaults$chunk
codefigChunkHook <- function (x, options) {
main <- defaultChunkHook(x, options)
before <-
"\\vspace{1em}\n
\\adjustbox{valign=t}{\n
\\begin{minipage}{.59\\linewidth}\n"
after <-
paste("\\end{minipage}}
\\hfill
\\adjustbox{valign=t}{",
paste0("\\includegraphics[width=.4\\linewidth]{figure/",
options[["label"]], "-1.pdf}}"), sep="\n")
## Was a codefig option supplied in chunk header?
## If so, wrap code block and graphical output with needed LaTeX code.
if (!is.null(options$codefig)) {
return(sprintf("%s %s %s", before, main, after))
} else {
return(main)
}
}
knit_hooks[["set"]](chunk = codefigChunkHook)
## (3) TEMPLATE
## codefig=TRUE is just one of several options needed for the
## side-by-side code block and a figure to come out right. Rather
## than typing out each of them in every single chunk header, we
## define a _template_ which bundles them all together. Then we can
## set all of those options simply by typing opts.label="codefig".
opts_template[["set"]](
codefig = list(codefig=TRUE, fig.show = "hide",
r.opts = list(width=partWidth),
tidy = TRUE,
tidy.opts = list(width.cutoff = partWidth)))
@
A chunk without \texttt{opts.label="codefig"} set...
<<A>>=
1:60
@
\texttt{opts.label="codefig"} \emph{is} set for this one
<<B, opts.label="codefig", fig.width=8, cache=FALSE>>=
library(raster)
library(RColorBrewer)
## Create a factor raster with a nice RAT (Rast. Attr. Table)
r <- raster(matrix(sample(1:10, 100, replace=TRUE), ncol=10, nrow=10))
r <- as.factor(r)
rat <- levels(r)[[1]]
rat[["landcover"]] <- as.character(1:10)
levels(r) <- rat
## To get a nice grid...
p <- as(r, "SpatialPolygonsDataFrame")
## Plot it
plot(r, col = brewer.pal("Set3", n=10),
legend = FALSE, axes = FALSE, box = FALSE)
plot(p, add = TRUE)
text(p, label = getValues(r))
@
\texttt{opts.label="codefig"} not set, and all settings back to ``normal''.
<<C>>=
lm(mpg ~ cyl + disp + hp + wt + gear, data=mtcars)
@
\end{document}
#2
4
I see 3 possibilities
我看到3种可能性
- for
beamer
presentations, I'd go for\begin{columns}
...\end{columns}
as well. - 对于投影仪演示,我会去\ begin {columns} ... \ end {columns}。
- If it is only one such plot: Minipages
- 如果它只是一个这样的情节:小型商品
- Here I used a table (column code and column result). (This example is "normal" Sweave)
- 这里我使用了一个表(列代码和列结果)。 (这个例子是“正常”的Sweave)
For all three, the chunk options would have include = FALSE
, and the plot would "manually" be put to the right place by \includegraphics[]{}
.
对于所有这三个,块选项将包括= FALSE,并且将通过\ includegraphics [] {}“手动”将绘图放到正确的位置。
#3
2
You can display the text in a 'textplot' from package PerformanceAnalytics or gplots.
您可以在PerformanceAnalytics或gplots包中的“textplot”中显示文本。
(Little) downside: To my knowledge there is no Syntax highlighting possible.
(小)缺点:据我所知,没有语法突出显示可能。
Sample Code:
示例代码:
```{r fig.width=8, fig.height=5, fig.keep = 'last', echo=FALSE}
suppressMessages(library(PerformanceAnalytics))
layout(t(1:2))
textplot('plot(1:10)')
plot(1:10)
```