I'd like to align some text output next to a plot output from plotly in an html knitr file. For example, I'd like the output of the functions below to appear side by side in the document.
---
title: 'untitled'
output: html_document
---
```{r}
pacman::p_load(ggplot2, plotly, grid, gridExtra)
p1 <- ggplot(df, aes(y = var1, x =
var2, color = p_c)) + geom_point(aes(text = subjID)) +
geom_smooth(method = "lm")
ggplotly(p1, tooltip = "text")
cor.test(var1, var2)
```
I've fooled around with Grobs (i.e. grobText) and the grid/gridExtra packages - but those don't seem compatible with plotly. For example:
```{r}
pacman::p_load(ggplot2, plotly, grid, gridExtra)
p1 <- ggplot(df, aes(y = var1, x =
var2, color = p_c)) + geom_point(aes(text = subjID)) +
geom_smooth(method = "lm")
p1 <- ggplotly(p1, tooltip = "text")
text1 <- cor.test(var1, var2)
text1 <- textGrob(text1)
grid.arrange(p1, text1, ncol = 2)
```
This returns the error: Error in gList(list(x = list(data = list(list(x = c(-28, 1689, 1122, 284, : only 'grobs' allowed in "gList"
I've also considered flexdashboard, but I don't want the output to appear in a separate html page from the rest of the report.
Any thoughts are appreciated, especially if there's a way to get the row formatting of flexdashboard to be inserted into the middle of a standard html rmarkdown file.
Related
I'm creating a document with PDF output in R Markdown.
My code creates a number of tables and figures in a "for" loop, within the same code chunk. All the tricks I've seen to create a line break in a PDF document - with all sorts of combinations and permutations of preceding slashes and spaces (e.g., newline, linebreak, ,  , etc) are not working. So, I decided to cut some corners and just increase the plot space in my ggplot2 margins to create the illusion of more white space between my table and my graph.
Ideally, I'd love to know how to actually insert white space ( a line, or several lines) properly within a single code chunk, without getting an error.
However, I'd also settle for figuring out why the following code "works" to produce extra space in my ggplot2 plot when I have some background color (first plot) but doesn't work when the background color is white!!? This is truly bizarre behavior folks!
See my screenshot below and the code, with two identical code chunks - except the background color of the plot - where one plot with a light beige background shows the desired "white space" between the table and the plot title, and the plot following (white background) does not show the same "white space".
---
title: "I need a line break"
output: pdf_document
---
```{r setup, include=FALSE}
library(ggplot2)
library(knitr)
library(ggplot2)
knitr::opts_chunk$set(echo = FALSE,
include = TRUE,
message = FALSE,
warning = FALSE,
error = FALSE)
```
```{r, results = "asis", fig.height = 2}
for (i in 1) {
mytable <- kable((iris[c(1,2),]), booktabs = TRUE)
print(mytable)
myplot <- ggplot(iris) +
labs(title = "Gorgeous plot") +
geom_point(aes(Sepal.Length, Sepal.Width)) +
theme_void() +
theme(plot.background = element_rect(fill = "#FFFEEB", color = "white"),
plot.margin = unit(c(1, 0, 0, 0), "cm"))
print(myplot)
}
```
```{r, results = "asis", fig.height = 2}
for (i in 1) {
mytable <- kable((iris[c(1,2),]), booktabs = TRUE)
print(mytable)
myplot <- ggplot(iris) +
labs(title = "Gorgeous plot") +
geom_point(aes(Sepal.Length, Sepal.Width)) +
theme_void() +
theme(plot.background = element_rect(fill = "white", color = "white"),
plot.margin = unit(c(1, 0, 0, 0), "cm"))
print(myplot)
}
```
Can you add linebreaks with cat to solve your problem? E.g.
---
title: "I need a line break"
output: pdf_document
---
```{r setup, include=FALSE}
library(ggplot2)
library(knitr)
library(ggplot2)
knitr::opts_chunk$set(echo = FALSE,
include = TRUE,
message = FALSE,
warning = FALSE,
error = FALSE)
```
```{r, results = "asis", fig.height = 2}
for (i in 1:2) {
mytable <- kable((iris[c(1,i),]), booktabs = TRUE)
print(mytable)
cat("\\ ")
cat("\\linebreak")
cat("\\linebreak")
cat("\\linebreak")
myplot <- ggplot(iris) +
labs(title = "Gorgeous plot") +
geom_point(aes(Sepal.Length, Sepal.Width)) +
theme_void()
print(myplot)
cat("\\linebreak")
cat("\\linebreak")
}
```
(The cat("\\ ") is needed so that there is a line to end)
I have created some awesome graphs that I want to export to my Word document. Yea, should write in Markdown but... you know... someday!
However, how do I resize the graphs to the right dimensions while labels stay "within" the perimeter? See the following examples (code is at the end of the document).
I want to insert the following graph into my word document:
Looks great! Not when I insert it into the document:
Labels are two tiny, and I would love to stretch it vertically, so the width is greater than the height. So I managed to produce this:
And this is were I am stuck. How do I keep the labels within the perimeters? And is there a better way to "fit" the word document than guessing correct dimensions?
Thanks!
This is the code:
library(ggplot2)
df <- mpg # Load sample data
# First test graph
ggplot(data = df, mapping = aes(cyl, hwy)) +
geom_smooth() +
geom_point() +
geom_point() +
labs(y = "This is just one very long label to prove a point ..... 1234",
x = "Cyl") +
theme_classic() +
theme(legend.title = element_blank())
ggsave("test1.png")
# Modified test graph to add fit the Word document
ggplot(data = df, mapping = aes(cyl, hwy)) +
geom_smooth() +
geom_point() +
geom_point() +
labs(y = "This is just one very long label to prove a point ..... 1234",
x = "Cyl") +
theme_classic(base_size = 12) + # SIZE CHANGED
theme(legend.title = element_blank())
ggsave("test2.png", width = 8, height = 4) # DIMENSIONS DEFINED
A solution I tend to use involves the officer package as mentioned above. This used to be able export graphs as vector objects to docx so you could change sizes and text in the graph when it's in the document. This seems to have been suspended in recent versions, but still works for powerpoint. The following code puts the graph as a grouped shape in a powerpoint slide where you can tweak it before copying into word:
library(ggplot2)
library(officer)
library(tidyverse)
df <- mpg # Load sample data
# First test graph
plot2 <- ggplot(data = df, mapping = aes(cyl, hwy)) +
geom_smooth() +
geom_point() +
geom_point() +
labs(y = "This is just one very long label to prove a point ..... 1234",
x = "Cyl") +
theme_classic(base_size = 12) + # SIZE CHANGED
theme(legend.title = element_blank())
pptx <- read_pptx()
pptx %>%
add_slide() %>%
# This first line puts it in as a static png image for comparison
ph_with(plot2, location = ph_location_type(type = "body")) %>%
add_slide() %>%
# This line puts in a shape object, which can be ungrouped and edited
ph_with(rvg::dml(ggobj = plot2),
width = 8,
height = 4,
location = ph_location_type(type = "body"))
#> pptx document with 2 slide(s)
print(pptx, "test_graph.pptx")
Created on 2020-12-08 by the reprex package (v0.3.0)
That's a sort of tweaky solution which at least allows you visual control over sizes. This used to be more easily provided through the export package (available on GitHub), but it's not on CRAN anymore and behind the scenes used the now defunct parts of officer to put vector graphics in docx documents.
Edit: See this issue on GitHub for an explanation of why vector graphics to docx is no longer an option through officer.
I'm producing an RMarkdown document where each chunk produces a plot.
For each of these plots, I'd like to apply a special formatting function that adjusts the way the title appears.
Is there a way to tell knitr/rmarkdown to apply this special function to each chunk's plot? For example, maybe there's a chunk option like {r, fig.function = adjust_title_position}?
The motivation is that I don't want to have to retype the function call separately for each plot (e.g. adjust_title_position(plot_42)) and, at the same time, I don't want to use something like lapply(my_plots, adjust_title_position) which would require all the plots to be defined in one place.
Below is a minimal example of the RMarkdown file to which this could be applied.
---
title: "RMD_Example"
output: html_document
---
```{r setup, include=FALSE}
# Load ggplot2
library(ggplot2)
# Define helper function
adjust_title_position <- function(p) {
# Shift the horizontal position of the plot title
p_built <- invisible(ggplot2::ggplot_build(p))
gt <- invisible(ggplot2::ggplot_gtable(p_built))
gt$layout[which(gt$layout$name == "title"), c("l", "r")] <- c(2, max(gt$layout$r))
# Prints the plot to the current graphical device
gridExtra::grid.arrange(gt, newpage = TRUE)
# Invisibly return the gtable object
invisible(gt)
}
```
```{r plot_1}
ggplot(mtcars) + geom_point(aes(x = wt, y = mpg)) +
labs(title = "Weights and miles-per-gallon")
```
```{r plot_2}
ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) + geom_point() +
labs(title = "Sepal length and width")
```
You could reregister the print-method for ggplot-objects.
# Define helper function
adjusted_title_position <- function(p) {
# Shift the horizontal position of the plot title
p_built <- invisible(ggplot2::ggplot_build(p))
gt <- invisible(ggplot2::ggplot_gtable(p_built))
gt$layout[which(gt$layout$name == "title"), c("l", "r")] <- c(2, max(gt$layout$r))
# Prints the plot to the current graphical device
gridExtra::grid.arrange(gt, newpage = TRUE)
}
# Reregister print.ggplot
assignInNamespace("print.ggplot", adjusted_title_position, asNamespace("ggplot2"))
When including a plot with geom_col in an R Markdown report knitted to pdf, the stacked breaks between observations are made visible as gray lines:
```{r}
library(ggplot2)
ggplot(data = midwest) +
geom_col(mapping = aes(x = state, y = poptotal))
```
But when I run the exact same code directly in R Studio (or knit to HTML), the columns are shown as solid:
Is there something special to do to make the different observations not be shown in a pdf (e.g., to make the pdf-knitted plot look like the HTML-knitted one)?
Did you Try using geom_bar() instead of geom_col(), because geom_col() was created afterwards, its basically geom_bar() only
```{r}
library(ggplot2)
ggplot(data = midwest) +
geom_bar(stat="identity",mapping = aes(x = state, y = poptotal))
```
It might work, try it and let me know
You can also set fill and check what happens
geom_bar(stat="identity",mapping = aes(x = state, y = poptotal,fill="gray60"))
Is there a way in RMarkdown to force R code and the figure that it produces to appear on the same page please? I am using Knit pdf. For example,
```{r}
ggplot(df, aes(x = x, y = y, col = sex_f)) + geom_point() +
ggtitle("Data from Children") +
labs(x = "Age (months)", y = "Height (cms)", col = "Child Gender") +
geom_smooth(method = "lm", se = FALSE) +
facet_grid(sex_f ~ town_f)
```
(which is not reproducible) produces code on one page and a plot on the next page. I have tried setting the figure width and height globally, for example
```{r global_options, include=FALSE}
knitr::opts_chunk$set(fig.width = 4, fig.height = 3,
fig.path = 'Intro_Figs/',
fig.show = 'asis',
fig.align = 'center',
warning = FALSE, message = FALSE)
```
with very small values, but this does not prevent all bad page breaks. Thank you.