Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic height and width for knitr plots

Tags:

r

knitr

In knitr, one can specify the size of plot by simply specifying it in the chunk options.

For example:

```{r, fig.width=9,fig.height=3} plot(x) ``` 

I would like to be able to dynamically adjust the figure height and width on the basis of variables in x. Let's say that x is a data.frame:

x <- data.frame(x=factor(letters[1:3]),y=rnorm(3)) 

For example's sake lets say I would like to adjust fig.height to be equal to length(unique(x$x))

like image 302
Brandon Bertelsen Avatar asked Mar 12 '13 15:03

Brandon Bertelsen


2 Answers

You can for example define the width in another chunk, then use it

```{r,echo=FALSE} x <- data.frame(x=factor(letters[1:3]),y=rnorm(3)) len = length(unique(x$x)) ```   ```{r fig.width=len, fig.height=6}  plot(cars) ``` 
like image 198
agstudy Avatar answered Sep 30 '22 19:09

agstudy


I just found a great blog post about this.

Read more at Michael J Williams' blog - I've shamelessly pilfered the code, so more detail there. Remember to set chunk options to results = "asis".

Say you want to output a bunch of plots using a loop but you want them to each have different sizes. Define the following function (again, I'm just copy-pasting here):

subchunkify <- function(g, fig_height=7, fig_width=5) {   g_deparsed <- paste0(deparse(     function() {g}   ), collapse = '')    sub_chunk <- paste0("   `","``{r sub_chunk_", floor(runif(1) * 10000), ", fig.height=",    fig_height, ", fig.width=", fig_width, ", echo=FALSE}",   "\n(",      g_deparsed     , ")()",   "\n`","``   ")    cat(knitr::knit(text = knitr::knit_expand(text = sub_chunk), quiet = TRUE)) } 

And use the function like this, defining your own figure sizes:

```{r echo=FALSE, results='asis'} g <- ggplot(economics, aes(date, unemploy)) +    geom_line() subchunkify(g, 10, 3) subchunkify(g, 7, 7) ``` 

Or let the data define the sizes:

```{r echo=FALSE, results='asis'} g <- ggplot(economics, aes(date, unemploy)) +    geom_line() for (i in seq(2, 5)) {   subchunkify(g, i / 2, i) } ``` 

In the post Michael warns that you must be careful:

Since we’re using results='asis', if we want to output text or headings or anything else from the chunk, we must use raw HTML, not Markdown, and we must use cat() to do this, not print(). For instance:

g <- ggplot(economics, aes(date, unemploy)) +    geom_line()  cat('<h2>A Small Square Plot</h2>') subchunkify(g, 3, 3) 

Again, not my work... head on over to that lovely blog post for more details. Hope this works for you.

like image 39
Nova Avatar answered Sep 30 '22 20:09

Nova