Search code examples
rpdflatexr-markdown

How to wrap text around ggplot figure in Rmarkdown for pdf


I am trying to align my figure on right side of my text and have used the answer from this question to use wrapfigure package to get the desired result. But the question is about how to wrap text around images and not ggplot output. When applying the answer to ggplot figures, I ran into the following problems:

  1. How to control the white space above and below the figure
  2. I want my second heading to start after the wrapfigure result but can't figure out how to do this.

Reproducible example:

---
title: Domestic and Global Price Trends – Key Commodities
output: pdf_document
header-includes:
  \usepackage{floatrow}
  \usepackage{wrapfig}
  \usepackage{fancyhdr}
  \pagestyle{fancy}
  \fancyhf{}
  \addtolength{\headheight}{1.5cm}
  \rhead{Research Department}
  \lhead{x}
  \renewcommand{\headrulewidth}{1pt}
  \fancypagestyle{plain}{\pagestyle{fancy}} 
  

---


```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(readxl)
library(dplyr)
library(kableExtra)
library(ggplot2)
library(tidyverse)
library(cowplot)
options(scipen = 10)

```

```{r include=FALSE} 
ref=structure(list(date = structure(c(19236, 19243, 19250, 19257, 
19264, 19271, 19278, 19285, 19292, 19299, 19306, 19313, 19320, 
19327, 19334, 19341, 19348, 19355, 19362, 19369, 19376, 19383, 
19390, 19397, 19404, 19411, 19418, 19425, 19432, 19439, 19446, 
19453, 19460, 19467, 19474, 19481, 19488, 19495, 19502, 19509, 
19516, 19523, 19530, 19537, 19544, 19551, 19558, 19565, 19572, 
19579, 19586, 19593, 19600, 19607, 19614, 19621, 19628, 19635, 
19642, 19649, 19656), class = "Date"), Snp_WoW = c(-5.58, -0.24, 
-2.82, -4, 0.24, 9.7, -5.23, -1, 1.75, 4.62, -2.89, -4.31, -2.25, 
1.09, -6.39, 2.75, 2.99, 0.78, -6.09, 5.67, 1.71, -1.18, -5.65, 
4.02, -2.69, -0.68, 3.16, -3.34, -5.96, 1.43, 4.49, 2.55, 1.06, 
-3.53, -1.56, -3.43, -1.23, 0.84, 0.63, -0.23, -1.06, 3.22, -2.81, 
-0.2, 2.11, 1.93, 2.17, 2.82, 0.13, -0.16, -1.48, 0.51, 2.39, 
1.34, 1.82151778156547, -1.10837257097035, -0.245418848167545, 
-5.5744792520912, 3.49745810581812, 0.830715634213242, -1.56417095610418
), Snp_YoY = c(23.12, 22.19, 18.85, 12.52, 10.56, 18.65, 9.54, 
5.72, 7.88, 13.22, 11.45, 6.77, 6.66, 13.26, 9, 8.06, 12.13, 
9.34, 2.16, 4.79, 3.25, 0.14, -7.39, -7.06, -9.57, -10.26, -8.7, 
-26.48, -26.89, -24.29, -26.56, -18.37, -17.42, -24.97, -24.17, 
-27.9, -29.06, -29.04, -31.02, -32.5, -32.93, -26.06, -26.32, 
-24.9, -20.9, -14.57, -13.37, -14.68, -8.87, -12.18, -12.55, 
-15.21, -8.05, -6.6, -2.14230738843033, 0.805686812960249, 0.319617610642409, 
-13.6507991741133, -5.70363464555365, -3.96117061078105, -7.09019336519665
)), row.names = c(NA, -61L), class = c("tbl_df", "tbl", "data.frame"
))

``` 


# Heading 1
## subheading 1

```{r plot2, out.width="50%",out.height="50%",fig.align='right' ,echo=F , warning=F, message=F}
df=ref
d=max(df$Snp_WoW)
c=min(df$Snp_WoW)
b=max(df$Snp_YoY)
a=min(df$Snp_YoY)
m=(d-c)/(b-a)
k=(c*b-a*d)/(b-a)
plot.2<-df%>% ggplot(aes(x=as.Date(date)))+geom_line(aes(y=Snp_WoW, color="S&P-WoW"),linewidth=1)+geom_line(aes(y=(m*Snp_YoY+k), color="S&P-YoY"),linewidth=1)+scale_y_continuous(name = "S&P-WoW",sec.axis = sec_axis(trans = ~ (.-k)/m,name = "S&P-YoY"))+scale_x_date(name='Date',breaks = as.Date(ref$date[seq(length(ref$date)-54,length(ref$date),2)]), date_labels = "%d %b %y")+ggtitle("Standard & Poor Global Index")+scale_color_manual(name="",values = c("S&P-WoW"='darkblue',"S&P-YoY"='red'))+theme_gray()+theme(legend.position=c(0.83,0.85),panel.grid = element_blank(),legend.title = element_blank(),legend.background = element_rect(fill = "lightgrey"),panel.border = element_rect(fill = NA),axis.text.x = element_text(angle = 90))

```

\begin{wrapfigure}{r}{0.5\textwidth}
  \centering
    ```{r plot21, out.width="100%",out.height="100%",fig.align='right' ,echo=F , warning=F, message=F }
    plot.2
    ```
\end{wrapfigure}




This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.Th
This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.Th
This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.Th 

# Heading 2
This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.Th
This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.Th
This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.Th
 

The output: I dont want this red shaded whitespace and also want the heading 2 to start after the wraping.

I dont want this red shaded whitespace and also want the heading 2 to start after the wraping.

One way to do this by using the \newline but that gives rise to another problem. Reproducible example:

---
title: Domestic and Global Price Trends – Key Commodities
output: pdf_document
header-includes:
  \usepackage{floatrow}
  \usepackage{wrapfig}
  \usepackage{fancyhdr}
  \pagestyle{fancy}
  \fancyhf{}
  \addtolength{\headheight}{1.5cm}
  \rhead{Research Department}
  \lhead{x}
  \renewcommand{\headrulewidth}{1pt}
  \fancypagestyle{plain}{\pagestyle{fancy}} 
  

---


```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(readxl)
library(dplyr)
library(kableExtra)
library(ggplot2)
library(tidyverse)
library(cowplot)
options(scipen = 10)

```

```{r include=FALSE} 
ref=structure(list(date = structure(c(19236, 19243, 19250, 19257, 
19264, 19271, 19278, 19285, 19292, 19299, 19306, 19313, 19320, 
19327, 19334, 19341, 19348, 19355, 19362, 19369, 19376, 19383, 
19390, 19397, 19404, 19411, 19418, 19425, 19432, 19439, 19446, 
19453, 19460, 19467, 19474, 19481, 19488, 19495, 19502, 19509, 
19516, 19523, 19530, 19537, 19544, 19551, 19558, 19565, 19572, 
19579, 19586, 19593, 19600, 19607, 19614, 19621, 19628, 19635, 
19642, 19649, 19656), class = "Date"), Snp_WoW = c(-5.58, -0.24, 
-2.82, -4, 0.24, 9.7, -5.23, -1, 1.75, 4.62, -2.89, -4.31, -2.25, 
1.09, -6.39, 2.75, 2.99, 0.78, -6.09, 5.67, 1.71, -1.18, -5.65, 
4.02, -2.69, -0.68, 3.16, -3.34, -5.96, 1.43, 4.49, 2.55, 1.06, 
-3.53, -1.56, -3.43, -1.23, 0.84, 0.63, -0.23, -1.06, 3.22, -2.81, 
-0.2, 2.11, 1.93, 2.17, 2.82, 0.13, -0.16, -1.48, 0.51, 2.39, 
1.34, 1.82151778156547, -1.10837257097035, -0.245418848167545, 
-5.5744792520912, 3.49745810581812, 0.830715634213242, -1.56417095610418
), Snp_YoY = c(23.12, 22.19, 18.85, 12.52, 10.56, 18.65, 9.54, 
5.72, 7.88, 13.22, 11.45, 6.77, 6.66, 13.26, 9, 8.06, 12.13, 
9.34, 2.16, 4.79, 3.25, 0.14, -7.39, -7.06, -9.57, -10.26, -8.7, 
-26.48, -26.89, -24.29, -26.56, -18.37, -17.42, -24.97, -24.17, 
-27.9, -29.06, -29.04, -31.02, -32.5, -32.93, -26.06, -26.32, 
-24.9, -20.9, -14.57, -13.37, -14.68, -8.87, -12.18, -12.55, 
-15.21, -8.05, -6.6, -2.14230738843033, 0.805686812960249, 0.319617610642409, 
-13.6507991741133, -5.70363464555365, -3.96117061078105, -7.09019336519665
)), row.names = c(NA, -61L), class = c("tbl_df", "tbl", "data.frame"
))

``` 


# Heading 1
## subheading 1

```{r plot2, out.width="50%",out.height="50%",fig.align='right' ,echo=F , warning=F, message=F}
df=ref
d=max(df$Snp_WoW)
c=min(df$Snp_WoW)
b=max(df$Snp_YoY)
a=min(df$Snp_YoY)
m=(d-c)/(b-a)
k=(c*b-a*d)/(b-a)
plot.2<-df%>% ggplot(aes(x=as.Date(date)))+geom_line(aes(y=Snp_WoW, color="S&P-WoW"),linewidth=1)+geom_line(aes(y=(m*Snp_YoY+k), color="S&P-YoY"),linewidth=1)+scale_y_continuous(name = "S&P-WoW",sec.axis = sec_axis(trans = ~ (.-k)/m,name = "S&P-YoY"))+scale_x_date(name='Date',breaks = as.Date(ref$date[seq(length(ref$date)-54,length(ref$date),2)]), date_labels = "%d %b %y")+ggtitle("Standard & Poor Global Index")+scale_color_manual(name="",values = c("S&P-WoW"='darkblue',"S&P-YoY"='red'))+theme_gray()+theme(legend.position=c(0.83,0.85),panel.grid = element_blank(),legend.title = element_blank(),legend.background = element_rect(fill = "lightgrey"),panel.border = element_rect(fill = NA),axis.text.x = element_text(angle = 90))

```

\begin{wrapfigure}{r}{0.5\textwidth}
  \centering
    ```{r plot21, out.width="100%",out.height="100%",fig.align='right' ,echo=F , warning=F, message=F }
    plot.2
    ```
\end{wrapfigure}




This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.Th
This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.Th
This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.Th \newline

# Heading 2
This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.Th
This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.Th
This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.This is some text.Th

Output:the text doesnot align well the text doesnot align well


Solution

  • You could position the plot image as follows:

    The default position for figures in LaTeX is below the first line of adjacent text. See for example https://tex.stackexchange.com/questions/238265/vertically-align-text-to-graphic. So you can control the figure vertical alignment using \vspace{-\baselineskip}

    The space below the figure can be controlled using wrapfigure parameter 1; wrapfig documentation refers: https://ctan.org/pkg/wrapfig. By trial and error you may be able to find a better result than achieved in the questions using [12].

    You will probably need to adjust the arguments to suit your use case.

    \begin{wrapfigure}[12]{r}{0.5\textwidth}
    
     \vspace{-\baselineskip}
    
     \centering
     
     ```{r plot21, fig.align='right', echo=FALSE}
     
     plot.2
     
     ```
    
    \end{wrapfigure}
    

    Which results in:

    enter image description here