Kevin Ushey
Kevin Ushey

Reputation: 21285

Produce two plots from same chunk / statement in knitr

Is it possible to have plot-generating code output two versions of the same figure, at different sizes, from a .Rmd document? Either through chunk options (I didn't see anything that works directly here), or through a custom knitr hook? Preferably this would be done with the png device.

My motivation: I'd like to be able to output a figure at one size, which would fit inline in a compiled HTML document, and another figure that a user could show after clicking (think fancybox). I think I'll be able to handle the scripting necessary to make that work; however, first I need to convince R / knitr to output two versions of the figure.

Although I'm sure there are workarounds, it would be best if there was some way to get it to 'just work' behind the scenes, e.g. through a knitr hook. That way, we don't have to do anything special to the R code within a chunk, we just modify how we parse / evaluate that chunk.

Alternatively, one could use SVG graphics that would scale nicely, but then we lose the nice inference of good sizes for the plot labels, and vector graphics aren't great for plots with many many points.

Upvotes: 10

Views: 3068

Answers (2)

Yihui Xie
Yihui Xie

Reputation: 30114

I thought there was not a solution, and was about to say no to @baptiste, but got a hack in my mind soon. Below is an R Markdown example:

```{r test, dev='png', fig.ext=c('png', 'large.png'), fig.height=c(4, 10), fig.width=c(4, 10)}
library(ggplot2)
qplot(speed, dist, data=cars)
```

See the [original plot](figure/test.png) and
a [larger version](figure/test.large.png).

The reason I thought the vectorized version of dev would not work was: for dev=c('png', 'png'), the second png file will overwrite the first one because the figure filename is the same. Then I realized fig.ext was also vectorized, and a file extension like large.png does not really destroy the file extension png; this is why it is a hack.

Anyway, by vectorized versions of dev, fig.ext, fig.height, and fig.width, you can save the same plot to multiple versions. If you use a deterministic pattern for the figure file extensions, I think you can also cook up some JavaScript code to automatically attach fancy boxes onto images.

Upvotes: 17

Hillary Sanders
Hillary Sanders

Reputation: 6047

If you just need the small and large figure, can you just do:

<<plotSmall, fig.height=6, fig.width=8, out.width='.1\\textwidth'>>=
plot(...)
@
<<plotBig, fig.height=6, fig.width=8, out.width='.99\\textwidth'>>=
plot(...)
@

Or more simply:

<<plotBoth, fig.height=6, fig.width=8, out.width=c('.1\\textwidth', '.9\\textwidth')>>=
plot(...)
plot(...)
@

(sure you know this, but .Rmd is for LaTeX, while .Rhtml is for html - the .Rhtml syntax is slightly different.)

Upvotes: 0

Related Questions