Rmarkdown: Explicitly specify the figure size of a plot within a chunk
So I haven't found an alternative to subchunkify()
, however I did solve the issue with it reusing the same plots on each loop iteration (though I haven't dug into why it was yet).
I added an id
argument to subchunkify()
and included it in the file name, and then within my loop/map I created an id
value that would be a combination of variables within each iteration that would be unique for each one.
subchunkify <- function(g, fig_height=7, fig_width=5, id = NULL) {
g_deparsed <- paste0(deparse(
function() {g}
), collapse = '')
sub_chunk <- paste0("
`","``{r sub_chunk_", id, "_", 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))
}
So I'm not sure why the runif
in subchunkify
was failing to result in distinct file names on each iteration. My suspicion is that it has something to do with how knitr
caching works. I noticed that if a subsequent iteration of my loop ended up going through the same conditional chain to produce graph A, then graph A would be reused everywhere that the condition chain matched. However if an iteration went off on a different conditional branch to produce graph B, it would correctly generate a new graph. (However then graph B would be reused in all places with the same conditional branch ending).
This still doesn't explain why me introducing a unique file name with id
works, but using runif
doesn't since in both cases the file name should be unique, so this is only a guess.
So I guess if anyone else is having problems, I have a solution here but not an explanation. Very unsatisfying but does the trick!
Changing figure size (Rstudio, Rmarkdown, Shiny)
This is how I use Shiny in Rmarkdown. This is a answer I used. You can adjust your shiny shinyApp()
function with the options
argument.
---
title: "Shiny in Rmarkdown"
output: html_document
runtime: shiny
---
```{r echo = FALSE, warning=FALSE, message=FALSE }
library(tidyverse)
library(shiny)
server <- function(input, output, session) {
trends <- reactive({
req(input$sel_year)
mpg %>%
filter(year %in% input$sel_year)
})
output$plot <- renderPlot({
ggplot(
data = trends(),
mapping = aes(x = trans)
) +
geom_bar()
})
}
ui <- fluidPage(
selectInput(
inputId = "sel_year",
label = "Choose Year",
list("1999", "2008")
),
plotOutput("plot")
)
shinyApp(ui = ui, server = server, options = list(height = 750))
```
Size of plot in R-Markdown
You can change the pot size in an R-Markdown code chunk by setting the fig.height=
and fig.width=
chunk arguments:
```{r fig.height=8, fig.width=8}
ggplot(iris) +
geom_line(aes(x = Sepal.Length, y = Sepal.Width), size = 0.5)
```
Adjust for large figure size in Shiny RMarkdown report
I never followed up with the answer I figured out... here's an approach that doesn't require adding a slider for anyone else facing the same problem in the future, (1) using my example and (2) using a more minimal version with built-in datasets:
Version 1
---
title: "Test"
author: "R User"
date: "9/7/2021"
output: html_document
runtime: shiny
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(ggplot2)
library(dplyr)
# example data
df <- data.frame(
subject = c(rep("A", 1000), rep("B", 1000), rep("C", 1000)),
course = rep(paste0("Course ", as.character(1:300)), 10),
value = rnorm(3000)
)
```
## Modify figure size
I would like to modify the figure size so the ridgelines are still readable when grouped by course, either by making the figure size larger overall or allowing the user to scroll down the figure.
```{r, echo=FALSE}
inputPanel(
selectInput("group", label = "Group",
choices = c("subject", "course"))
)
plot_height <- reactive({
df %>%
pull(get(input$group)) %>%
unique() %>%
length()
})
renderPlot({
ggplot(df, aes(y = !!as.symbol(input$group), x = value)) +
geom_boxplot() +
theme_minimal()
}, height = function() { 50 * plot_height() })
```
Version 2
---
title: "Dynamic Plot Height"
author: "Natalie O'Shea"
date: '2022-05-31'
output: html_document
runtime: shiny
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
library(dplyr)
library(ggplot2)
```
```{r}
inputPanel(
selectInput("grouping", label = "Select grouping:",
choices = c("supp", "dose"))
)
plot_height <- reactive({
ToothGrowth %>%
pull(get(input$grouping)) %>%
unique() %>%
length()
})
renderPlot({
ToothGrowth %>%
ggplot(aes(y = len)) +
geom_histogram() +
facet_wrap(~get(input$grouping), ncol = 1)
}, height = function() { 100 * plot_height() })
```
RMarkdown/Knitr, matching physical figure size and displayed HTML size
When you say out.height="5.29in", out.width="5.89in"
, those values are written into the HTML output as height
and width
attributes of the img
. But height
and width
are expressed in pixels, so you'll end up with a figure about 5 pixels square.
I don't use Powerpoint, but is there a way to specify the image size in pixels, e.g. "589px" or something similar? Then it will use the same scale as the browser, and things should be consistent.
Related Topics
Remove Weekend Data in a Dataframe
How to Remove Na Data in Only One Columns
Predict() with Arbitrary Coefficients in R
R Corpus Is Messing Up My Utf-8 Encoded Text
Getting the Error "Level Sets of Factors Are Different" When Running a for Loop
Ggplot2: More Complex Faceting
Resetting Cumsum If Value Goes to Negative in R
Top to Bottom Alignment of Two Ggplot2 Figures
Directly Adding Titles and Labels to Visnetwork
List and Description of All Packages in Cran from Within R
R: Why Kable Doesn't Print Inside a for Loop
Rename Columns in Multiple Dataframes, R
Group Data in R for Consecutive Rows
Replace Missing Values with a Value from Another Column
Preventing Column-Class Inference in Fread()