Plot width/height not obeyed after RStudio upgrade - r

I'm using knitr with RStudio, generating html reports. My report contains many plots of various sizes, some are small and some are much wider. I use fig.width and fig.height per chunk to specify the size. Till yesterday I used RStudio 0.98.50* and it was rendered just perfectly - each plot with its own size, horizontal scrollbar appeared if some plots were too big. However I wanted to get TOC added to the reports and thus upgraded to the latest RStudio 0.98.1091.
Since the upgrade, all the fig.width/fig.height chunk settings seem to be just ignored. The HTML shows all plots of the same size, scalled, no scrolling. If I use the comment <!-- rmarkdown v1 --> all gets back to normal and looks like before but the TOC is gone.
Code Example
---
title: "Example"
output: html_document
---
<!-- rmarkdown v1 -->
```{r}
library(NMF)
# Generate random data
n <- 50; p <- 20
x <- abs(rmatrix(n, p, rnorm, mean=4, sd=1))
x[1:10, seq(1, 10, 2)] <- x[1:10, seq(1, 10, 2)] + 3
x[11:20, seq(2, 10, 2)] <- x[11:20, seq(2, 10, 2)] + 2
rownames(x) <- paste("ROW", 1:n)
colnames(x) <- paste("COL", 1:p)
```
```{r plot_small, fig.width=10, fig.height=25}
aheatmap(x)
```
```{r plot_big, fig.width=100, fig.height=45}
aheatmap(x)
```
If <!-- rmarkdown v1 --> is present, the result HTML looks as expected - plot_small is small, plot_big is much wider, horizontal scrollbar appears. If <!-- rmarkdown v1 --> is removed the result HTML looks very different - both plots have the same size, the plot_big is scaled, no scrolling. I think probably explained by those lines in the HTML:
.main-container {
max-width: 940px;
margin-left: auto;
margin-right: auto;
}
img {
max-width:100%;
height: auto;
}
I'd appreciate any ideas of either how to get TOC generated with v1 or plot size set as requested with v2.
Thanks

You can override the CSS rule, e.g. add this to your document
<style>
img {
max-width: none;
}
</style>
or use a custom CSS file (see the documentation for html_document).

Related

R, Gauge in flexdashboard - how to make it responsive to changes in browser size, like a plotly chart

I have created a simple example demonstrating the problem. The gauge does not change size when the height of the browser reduces, but disappears below the bottom of the panel. I would like it to behave like the plotly chart, which shrinks as the browser shrinks. the reason is that I am sending an html document to lots of people who all have different screen set ups. When something shrinks, it is obvious to the user that they have to expand the browser. That is not always the case with the gauge which does not shrink.
Compare screen shots of the browsers when wide open with the browser height much reduced. In the latter some of the gauge on the left has disappeared but the plotly chart on the right has just reduced in size:
Browser fully open
Browser height reduced- gauge partly disappeared and not shrunken
Any help would be appreciated.
Code is below:
---
title: "Untitled"
output:
flexdashboard::flex_dashboard:
css: styles1.css
orientation: columns
storyboard: TRUE
---
```{r setup, include=FALSE}
library(flexdashboard)
library(ggplot2)
library(dplyr)
library(plotly)
```
Scorecard
============================================================
Column 1 {data-width=800}
------------------------------------------------------------
### Gauge A
```{r}
mygauge <- gauge(value = 70,
min = 0,
max = 100,
symbol = "%",
abbreviateDecimals = 0,
sectors = gaugeSectors(colors = "DarkSlateGray")
)
mygauge
```
### [Take-up rate time series]
Column 2
----------------------------------------------------------
### Chart B
```{r}
chart_data <- tibble( x1 = c(2,3), y1 = c(4,5))
mychart <- ggplot(chart_data, aes(x=x1, y=y1)) + geom_line()
ggplotly (mychart)
```
### Hello
```{r}
```
.html-widget.gauge {
height: 250px; /*or try sth like 320px instead of 100%, whatever you prefer*/
width: auto;
padding-bottom: 4px;
}
.html-widget.gauge svg {
height: 250px; /*or try something like 320px instead of 100%, whatever you prefer*/
width: auto;
padding-bottom: 4px;
}

Custom CSS to rmarkdown chunk to change width of graph

I have an rmarkdown document which output html. I have my own css styles that I use by adding it to the YAML header. I also want to control css of specific code chunks. I have a dashboard (3x2 grid of plots) that I want to have larger width than the main document.
I've found these two questions:
Add a CSS class to single code chunks in RMarkdown
Adding custom CSS tags to an RMarkdown html document
But neither of them are working for me (or I didn't understand the answers). I want to change the width of a plot so it float into the margins e.g. width: 110%. I tried this:
```{r dash1, fig.height=16, fig.width=14, results="asis"}
cat("
<style>
.toc-content {
width: 110%;
}
</style>
")
margin = theme(plot.margin = unit(c(1,2,1,2), "cm"))
pl_1 <- list(g_1_kaupmattur, g_2_gallup, g_3_vnv, g_4_spa, g_5_ibud, g_6_swirlo)
grid.arrange(grobs = lapply(pl_1, "+", margin), ncol = 2)
```
This changed the whole document, not only the output of this particular chunk.
I also tried creating a new css style with width: 110% and adding it to the chunk option like this:
```{r dash1, fig.height=16, fig.width=14, class.source="dash_styles"}
margin = theme(plot.margin = unit(c(1,2,1,2), "cm"))
pl_1 <- list(g_1_kaupmattur, g_2_gallup, g_3_vnv, g_4_spa, g_5_ibud, g_6_swirlo)
grid.arrange(grobs = lapply(pl_1, "+", margin), ncol = 2)
```
It didn't work either.
I would like the plot to extend to the margins as I "show" on the screenshot below.

Height of RMarkdown code chunk in reveal.js slides

I keep running into the problem of my code chunks overflowing in my slides, and so having to scroll around them. Not optimal for teaching.
How can one make a code chunk taller (or wider) on a chunk by chunk basis?
How can one in reveal.js or other html formats change code text size, again, on a chunk by chunk basis. I know globally I can change things in the CSS, but want to be more dynamic than that.
p.s. If anyone wants to know how to change the center-text behavior while not affecting other slide elements, troubleshot that one recently, and it's nontrivial, but doable.
Customize Code Chunks using CSS
You could use fenced_code_attributes to add a CSS class (or several different classes) to certain code chunks. For this to work, you add this option to your YAML header and define a new hook using knit_hoooks$set() (for details see Hooks). After that, we can use the chunk option class = 'myCssClass'.
In the following example we define a class .smallCode, which sets a certain width for the chunk and a smaller font size. In the final document, the result looks like this:
<pre class="sourceCode r smallCode">
<code class="sourceCode r">
THE CODE WE PRODUCED
</code>
</pre>
As you can see, we just added the class smallCode to the <pre> element! Yay!
You can modify anything, the font styles, the background and much more. For an overview of possibilities check out this CSS Tutorial
Wrapping Source Code
If you want the source code to be wrapped, you can use the chunk option tidy=T with its option width.cutoff (also implemented in the example below).
Reproducible Example:
---
title: "Customized Code Chunks"
author: Martin Schmelzer
date: March 22, 2005
output:
revealjs::revealjs_presentation:
md_extensions: +fenced_code_attributes
---
<style>
pre.smallCode {
width: 360px; /* Change the width of the chunk */
height: 360px; /* Change the height of the chunk */
font-size: 0.4em; /* Change the font-size */
background-color: lightgrey; /* Change background color */
}
</style>
```{r, include=FALSE}
knitr::knit_hooks$set(source = function(x, options) {
return(paste0(
"```{.r",
ifelse(is.null(options$class),
"",
paste0(" .", gsub(" ", " .", options$class))
),
"}\n",
x,
"\n```"
))
})
```
# Customized Code Chunks
## Example
<!-- Here we use the option tidy=TRUE with a cutoff after 40 characters -->
```{r, class = 'smallCode', tidy=T, tidy.opts=list(width.cutoff=40)}
df <- data.frame(A = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20))
```
And here is a screenshot of the code chunk we just have customized:

2 column format in Rmarkdown fails after opts_chunk

I have reproduced a simple example of what I am facing in a long markdown script.
I would like some plots on slides to appear in 2 column format and some in 1 column format. Accordingly I need to adjust the width of the plots. trouble is the 2 column format does not seem to work when I open the resulting HTML in Chrome browser ; the charts appear one below the other.
The Rmd (saved using "Presentation" -> default Output Format "HTML ioslides") is below:
---
title: "Test"
author: "Gaurav Chaturvedi"
date: "6/29/2016"
output: ioslides_presentation
---
<style>
.col2 {
columns: 2 200px;
-webkit-columns: 2 200px;
-moz-columns: 2 200px;
}
</style>
## Slide with Plot
```{r, echo=FALSE}
suppressPackageStartupMessages(library(knitr))
boxplot(mpg~cyl, data=mtcars)
opts_chunk$set(comment=NA, fig.height = 4, fig.width = 4)
```
## 2 Plots
<div class = "col2">
```{r, echo=FALSE}
boxplot(mpg ~cyl, data=mtcars[mtcars$cyl==4,])
boxplot(mpg ~cyl, data=mtcars[mtcars$cyl==6,])
```
</div>
If you change the css in to:
<style>
.col2 {
float:left;
}
</style>
Your 2 plots will float aside each other (in the div-element). When I replicate your example in Chrome, it worked as you would like.

How to hide code in RMarkdown, with option to see it

I'm writing an RMarkdown document in which I'd like to re-run some chunks (5 to 9).
There's no need to display these chunks again, so I considered using
```{r echo=FALSE}
to make the rerun chunks invisible, as described in another stackoverflow question. This is fine, and outputs the desired results (improved fit of second iteration - see this solution implemented here).
In an ideal world, however, the code would be expandable so the user could see exactly what's going on if they want to for educational purposes and clarity (e.g. see link to Greasemonkey solution here) rather than hidden as in my second rpubs example. The solution may look something like this, but with a shorter surrounding box to avoid distraction:
for (i in 1:nrow(all.msim)){ # Loop creating aggregate values (to be repeated later)
USd.agg[i,] <- colSums(USd.cat * weights0[,i])
}
for (j in 1:nrow(all.msim)){
weights1[which(USd$age <= 30),j] <- all.msim[j,1] /USd.agg[j,1]
weights1[which(USd$age >= 31 & USd$age <= 50),j] <- all.msim[j,2] /USd.agg[j,2]
weights1[which(USd$age >= 51),j] <- all.msim[j,3] /USd.agg[j,3] ##
}
# Aggregate the results for each zone
for (i in 1:nrow(all.msim)){
USd.agg1[i,] <- colSums(USd.cat * weights0[,i] * weights1[,i])
}
# Test results
for (j in 1:nrow(all.msim)){
weights2[which(USd$sex == "m"),j] <- all.msim[j,4] /USd.agg1[j,4]
weights2[which(USd$sex == "f"),j] <- all.msim[j,5] /USd.agg1[j,5]
}
for (i in 1:nrow(all.msim)){
USd.agg2[i,] <- colSums(USd.cat * weights0[,i] * weights1[,i] * weights2[,i])
}
for (j in 1:nrow(all.msim)){
weights3[which(USd$mode == "bicycle"),j] <- all.msim[j,6] /USd.agg2[j,6]
weights3[which(USd$mode == "bus"),j] <- all.msim[j,7] /USd.agg2[j,7]
weights3[which(USd$mode == "car.d"),j] <- all.msim[j,8] /USd.agg2[j,8]
weights3[which(USd$mode == "car.p"),j] <- all.msim[j,9] /USd.agg2[j,9]
weights3[which(USd$mode == "walk"),j] <- all.msim[j,10] /USd.agg2[j,10]
}
weights4 <- weights0 * weights1 * weights2 * weights3
for (i in 1:nrow(all.msim)){
USd.agg3[i,] <- colSums(USd.cat * weights4[,i])
}
# Test results
plot(as.vector(as.matrix(all.msim)), as.vector(as.matrix(USd.agg3)),
xlab = "Constraints", ylab = "Model output")
abline(a=0, b=1)
cor(as.vector(as.matrix(all.msim)), as.vector(as.matrix(USd.agg3)))
#rowSums(USd.agg3[,1:3]) # The total population modelled for each zone, constraint 1
#rowSums(USd.agg3[,4:5])
#rowSums(USd.agg3[,6:10])
I'm happy with the echo=F solution, but would be even happier with an expandable code snippet one.
Edit: all RPubs examples except the first have now been removed, to avoid clogging their excellent publication system with essentially the same document.
This has been made much easier with the rmarkdown package, which did not exist three years ago. Basically you just turn on "code folding": https://bookdown.org/yihui/rmarkdown/html-document.html#code-folding. You no longer have to write any JavaScript.
E.g.
---
title: "Habits"
output:
html_document:
code_folding: hide
---
Also see https://bookdown.org/yihui/rmarkdown-cookbook/fold-show.html for more control over which code blocks to be fold or unfold.
If you add an html tag before your code you can use CSS selectors to do clever things to bits of the output - markdown handily passes the HTML through:
<style>
div.hidecode + pre {display: none}
</style>
<div class="hidecode"></div>
```{r}
summary(cars)
```
Here my CSS style rule matches the first <pre> tag after a <div class=hidecode> and sets it to be invisible. Markdown writes the R chunk with two <pre> tags - one for the R and one for the output, and this CSS catches the first one.
Now you know how to match the code and output blocks in CSS, you can do all sorts of clever things with them in Javascript. You could put something in the <div class=hidecode> tag and add a click event that toggles the visibility:
<style>
div.hidecode + pre {display: none}
</style>
<script>
doclick=function(e){
e.nextSibling.nextSibling.style.display="block";
}
</script>
<div class="hidecode" onclick="doclick(this);">[Show Code]</div>
```{r}
summary(cars)
```
The next step in complexity is to make the action toggle, but then you might as well use jQuery and get real funky. Or use this simple method. Let's do it with a button, but you also need a div to get your hooks into the R command PRE block, and the traversal gets a bit complicated:
<style>
div.hideme + pre {display: none}
</style>
<script>
doclick=function(e){
code = e.parentNode.nextSibling.nextSibling.nextSibling.nextSibling
if(code.style.display=="block"){
code.style.display='none';
e.textContent="Show Code"
}else{
code.style.display="block";
e.textContent="Hide Code"
}
}
</script>
<button class="hidecode" onclick="doclick(this);">Show Code</button>
<div class="hideme"></div>
```{r}
summary(cars)
```
( Note: I thought you could wrap R chunks in <div> tags:
<div class="dosomething">
```{r}
summary(cars)
```
</div>
but that fails - anyone know why?)

Resources