Arrange the plots nicely on R markdown pdf - ggplot2

I am a newbie at R markdown and am trying to create a pdf with multiple plots.
This should hopefully be an easy fix for a more experienced user.
I am trying to create a nice pdf with multiple plots over 2/3 pages of a pdf.
I have been stuck on this a while and have looked at various older questions/answer on this site. I am trying to use the patchwork package using the example here:
When I render this to a pdf using R markdown, it only seems to plot on half the page like so:
I have tried playing around with fig.height, out.height="100%", and classoption in the yaml:
---
title: "QC Metrics Report.v1"
date: "`r format(Sys.time(), '%d %B, %Y')`"
output:
pdf_document: default
html_document:
df_print: paged
geometry: margin=1.5cm
classoption: a4paper, bottom=15mm
---
(my code)
```{r, echo=FALSE, message=FALSE, eval=TRUE}
p1 <- ggplot(mtcars) +
geom_point(aes(mpg, disp)) +
ggtitle('Plot 1')
p2 <- ggplot(mtcars) +
geom_boxplot(aes(gear, disp, group = gear)) +
ggtitle('Plot 2')
p3 <- ggplot(mtcars) +
geom_point(aes(hp, wt, colour = mpg)) +
ggtitle('Plot 3')
p4 <- ggplot(mtcars) +
geom_bar(aes(gear)) +
facet_wrap(~cyl) +
ggtitle('Plot 4')
p1 + p2 + p3 + p4
```
If I try with the plot_layout function e.g.
p1 + p2 + p3 + p4
plot_layout(ncol = 2)
half the page is a printout of text (which I don't want)
Please help!

If the case you are running into is overlapping text when you are arranging the plots then plot_spacer and tweaks to some theme options might do the trick.
---
title: "My Report"
subtitle: "Report.v1"
author: "John Doe"
date: "`r format(Sys.time(), '%d %B, %Y')`"
output:
pdf_document: default
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, fig.align =
"center")
library(tidyverse)
library(patchwork)
library(gapminder)
library(scales)
library(gridExtra)
my_countries <- c("Zambia", "Malawi", "Mozambique", "Tanzania", "Kenya")
east_africa <- gapminder %>%
filter(country %in% my_countries) %>%
mutate(country = fct_reorder2(country, year, lifeExp)) # reorder for plotting
bar <- east_africa %>%
filter(year == max(year)) %>% # most recent year only
ggplot(aes(x = country, y = lifeExp, fill = country)) +
geom_col(width = 0.75, alpha = 0.9) +
geom_text(
aes(label = number(lifeExp, 0.1)),
position = position_stack(vjust = 0.5),
color = "white",
fontface = "bold",
size = 5
) +
scale_fill_brewer(palette = "Dark2") +
scale_y_continuous(expand = expand_scale(0.01, 0.05)) + # remove extra space between bars and x-axis labels
labs(y = "Life Expectancy (years)") +
theme_minimal(base_size = 16) +
theme(
legend.position = "none",
axis.title.x = element_blank(),
axis.title.y = element_text(size = 10),
axis.text.x = element_text(size = 7, angle = 45),
axis.title.y.left = element_text(margin = margin(r = 10)),
panel.grid.minor = element_blank(),
panel.grid.major.x = element_blank()
)
#> Warning: `expand_scale()` is deprecated; use `expansion()` instead.
line <- east_africa %>%
ggplot(aes(x = year, y = lifeExp, color = country)) +
geom_line(lwd = 1.25, key_glyph = "timeseries") + # for those cute glyphs in the legend
scale_color_brewer(palette = "Dark2") +
labs(y = "Life Expectancy (years)") +
theme_minimal(base_size = 16) +
theme(
legend.position = "bottom",
legend.title = element_blank(),
axis.title.x = element_blank(),
axis.text.x = element_text(size = 7),
axis.title.y = element_text(size = 10),
axis.title.y.left = element_text(margin = margin(r = 10)),
panel.grid.minor = element_blank(),
plot.margin = margin(t = 30)
)
tab <- east_africa %>%
filter(year == max(year)) %>%
transmute(
Country = country,
Population = comma(pop),
`GDP per capita` = dollar(gdpPercap, 1),
`Life Expectancy` = number(lifeExp, 0.1),
) %>%
arrange(Country) %>%
tableGrob(theme = ttheme_minimal(base_size = 10), rows = NULL)
layout <- bar + plot_spacer() + tab + plot_spacer() + line + plot_spacer()
layout +
plot_annotation(
title = "Life Expectancy of Selected Countries\n in East Africa",
caption = "Source: gapminder: Data from Gapminder
github.com/jennybc/gapminder
gapminder.org/data/",
theme = theme(plot.title = element_text(size = 16, hjust = 0.5, face = "bold"))
)
Created on 2022-10-30 with reprex v2.0.2
updated
If the case you are running into is that you have lots of code stuff in your actual pdf then use results = 'hide'
p1 <- ggplot(mtcars) +
geom_point(aes(mpg, disp)) +
ggtitle('Plot 1')
p2 <- ggplot(mtcars) +
geom_boxplot(aes(gear, disp, group = gear)) +
ggtitle('Plot 2')
p3 <- ggplot(mtcars) +
geom_point(aes(hp, wt, colour = mpg)) +
ggtitle('Plot 3')
p4 <- ggplot(mtcars) +
geom_bar(aes(gear)) +
facet_wrap(~cyl) +
ggtitle('Plot 4')
p1 + p2 + p3 + p4

Related

ggplot show the value rounded to one decimal place above the bar chart

I want to round the values above the bar chart to one decimal place. For example 14 should be 1.5 and not 1.52977.
This is how the bar chart looks right now
This is my code:
CPUE1 <- CPUE
CPUE1$Strecke <- factor (CPUE1$Strecke, levels = c('30/31', '14', '12', '10','1c','1bc', '1b'))
ggplot(CPUE1, aes(x= Strecke, y= CPUE, fill = Strecke ))+
geom_bar(stat='identity', position = 'dodge')+
theme_minimal()+
geom_text (aes (label = CPUE), position=position_dodge(width=0.9), vjust=-0.25)+
scale_fill_manual (values =
c("12" = "green", "10"= "green",
"1c" = "green", "14"= "red",
"1b"= "red","1bc"= "red","30/31" = "red"))
Add round to your geom_text:
library(tidyverse)
tribble(
~Strecke, ~CPUE,
"1b", 1.333,
"1c", 1.222,
"1b", 2.666,
"1c", 2.777
) |>
mutate(Strecke = factor(Strecke)) |>
ggplot(aes(Strecke, CPUE, fill = Strecke)) +
geom_bar(stat = "identity", position = "dodge") +
theme_minimal() +
geom_text(aes(label = round(CPUE, 1)), position = position_dodge(width = 0.9), vjust = -0.25) +
scale_fill_manual(values = c("1b" = "red", "1c" = "blue"))
Created on 2022-07-07 by the reprex package (v2.0.1)

In ggplot2/stat_summary, how to add the `median` value as label to plot (as geom_text())

In ggplot2/stat_summary, how to add the median value as label to plot ? Thanks!
library(ggplot2)
d <- ggplot(mtcars, aes(cyl, mpg)) + geom_point()
d + stat_summary(fun = "median", colour = "red", size = 2, geom = "point")
One potential option is to use after_stat() to get the labels, i.e.
library(ggplot2)
d <- ggplot(mtcars, aes(cyl, mpg)) +
geom_point()
d + stat_summary(fun = "median", colour = "red", size = 4,
geom = "text", aes(label = after_stat(y)),
position = position_nudge(x = 0.25))
Created on 2022-05-16 by the reprex package (v2.0.1)

Changing x-axis tick labels in reverse plot

I try to have an axis going from 0 to 24 (that represent hours in a day). With tick labels at 6, 12 and 18 too.
I am struggling, I tried already scale_x_discrete and scale_x_continuous and ylim, but the axis always goes from 0 to 25... :(
Thanks in avance for your help
Categ <- c("Employment","Voluntary work","Householdchores","Household member care","Personal care","Study","Sports and outdoor",
"Leisure","Travel or unspecified","Sleep")
Regime <- c("Unemp.", "Part-time 1" ,"Part-time 2" ,"Full time" , "Overtime")
Share <- c(0.00,0.10,3.71,1.14,2.70,0.18,0.37,5.55,1.28,8.96,1.29,0.10,4.13,1.13,3.10,0.11,0.18,3.73,1.72,8.50,3.79,0.13,2.89,0.78,2.43,0.04,0.22,3.94,1.69,8.09,5.78,0.08,1.96,
0.76,2.17,0.03,0.24,3.44,1.48,8.05,7.88,0.10,1.46,0.57,1.91,0.02,0.20,2.73,1.33,7.80)
data <- data.frame(Regime = rep(rev(Regime), each=10),
Category = rep(Categ,times=5),
Share = Share)
pct2 <- ggplot(data,
aes(x = Regime, y = Share)) +
geom_bar(aes(fill = Category),
stat = "identity", colour="black")+
coord_flip() +
theme(panel.background = element_blank()) +
scale_fill_manual("Legend", values = c("Employment" = "#F4A582", "Voluntary work" = "#FDDBC7", "Household chores" = "#92C5DE", "Household member care" = "#4393C3", "Personal care" = "#737373", "Study" = "#969696", "Sports and outdoor" = "#BDBDBD", "Leisure" = "#D9D9D9", "Travel or unspecified"= "#F0F0F0", "Sleep" = "#F6E8C3")) +
ylim(0,24)
print(pct2)
This should do (I'm adding scale_y_continuous(...) and I'm omitting ylim(0,24):
ggplot(data, aes(x = Regime, y = Share)) +
geom_bar(aes(fill = Category), stat = "identity", colour="black") +
coord_flip() +
scale_y_continuous(breaks = as.numeric(seq(1:24))) +
theme(panel.background = element_blank()) +
scale_fill_manual("Legend", values = c("Employment" = "#F4A582", "Voluntary work" = "#FDDBC7", "Household chores" = "#92C5DE", "Household member care" = "#4393C3", "Personal care" = "#737373", "Study" = "#969696", "Sports and outdoor" = "#BDBDBD", "Leisure" = "#D9D9D9", "Travel or unspecified"= "#F0F0F0", "Sleep" = "#F6E8C3"))

How do I get subscript in ggplot2 facet grid labels when I have two faceting variables?

I am trying to change one of the labels in my facet grid to contain some subscript text. I have been looking on stack overflow but none of the solutions work/I cannot understand how others are functioning so cannot apply them to my own scenario
This is my current ggplot function:
FacetGridTest <- tss_profiles %>% group_by(pulldown, Condition, replicate, category) %>%
group_by(pulldown,Condition,category,region_bin, region) %>%
mutate(meannone = mean(none)) %>%
ungroup() %>%
mutate(cond_cat=factor(cond_cat, levels=c("IG Target","IG Non-Target","MH Target","PH Target","MH Non-Target","PH Non-Target"))) %>%
mutate(category=factor(category, levels=c("Target","Non-Target"))) %>%
ggplot() + aes(x=Bin, y=meannone, col=Condition, group=paste(pulldown, Condition, replicate, category)) +
geom_line() +
facet_grid(pulldown~category, scale="free_x") +
theme_bw(base_size = 10) +
theme(legend.text.align = 0) +
labs(y=expression(paste("Read Counts")),
x=expression(paste("Bin"))) +
scale_colour_discrete(name = "Condition", labels = c("A","B","C")) +
geom_vline(xintercept=6000, linetype="dotted") +
annotate("text", x = 1000, y = 8800, label = "TSS", size=3) +
annotate("text", x = 11000, y = 8800, label = "TTS", size=3)
I want to change the "Non-Target" label to "J2L2 Non-Target20+"
Based on what I have seen on stack overflow I have tried doing:
vnames <- list('Target' = 'Target',
'Non-Target' = expression(paste("J" ["2"], "L" ["2"], " Non-Target" ["20"], "+")))
bnames <- list('A' = 'A','B' = 'B')
plot_labeller <- function(variable,value){
if (variable=='category') {
return(vnames[value])
} else if (variable=='pulldown') {
return(bnames[value])
} else {
return(as.character(value))
}
}
tss_profiles %>% group_by(pulldown, Condition, replicate, category) %>%
group_by(pulldown,Condition,category,region_bin, region) %>%
mutate(meannone = mean(none)) %>%
ungroup() %>%
mutate(cond_cat=factor(cond_cat, levels=c("IG Target","IG Non-Target","MH Target","PH Target","MH Non-Target","PH Non-Target"))) %>%
mutate(category=factor(category, levels=c("Target","Non-Target"))) %>%
ggplot() + aes(x=Bin, y=meannone, col=Condition, group=paste(pulldown, Condition, replicate, category)) +
geom_line() +
facet_grid(pulldown~category, scale="free_x", plot_labeller) +
theme_bw(base_size = 10) +
theme(legend.text.align = 0) +
labs(y=expression(paste("Read Counts")),
x=expression(paste("Bin"))) +
scale_colour_discrete(name = "Condition", labels = c("A","B","C")) +
geom_vline(xintercept=6000, linetype="dotted") +
annotate("text", x = 1000, y = 8800, label = "TSS", size=3) +
annotate("text", x = 11000, y = 8800, label = "TTS", size=3)
But this has not worked. I am probably misunderstanding how labellers work. Any help would be much appreciated.
I tried to run both codes but got error that object 'tss_profiles' not found.
Therefore I can just hypothesise that you should remove quotes from the subscript text ([20] instead of what you have - ["20"]).

Background Color of grid.arrange in gridExtra

So I am trying to draw a few ggplots and their legend using gridExtra. The legend appears in the last cell on a white background - I would like to change the background color there, so that white background disappears. How can I do that?
Here's my code:
library(reshape)
library(ggplot2)
library(plyr)
library(wq)
library(gridExtra)
library(lattice)
library(grid)
testVisualization <- function()
{
set.seed(123)
xx <- sample(seq(from = 20, to = 50, by = 5), size = 50, replace = TRUE)
yy <- sample(seq(from = 1, to = 50), size = 50, replace = TRUE)
zz <- sample(seq(from = 1, to = 10, by = 1), size = 50, replace = TRUE)
dd <- data.frame(xx,yy,zz)
colRainbow <- rainbow(n, s = 1, v = 1, start = 0, end = max(1, n - 1)/n, alpha = 1)
gg <- ggplot() + geom_point(data=dd, aes(x=xx, y=yy, colour=zz))+
theme_custom()
lay2 <- rbind(c(1,1,1,1,1),
c(2,2,3,3,4))
legg1 <- g_legend(gg)
grid.arrange(
gg+guides(fill=FALSE, colour=FALSE, size=FALSE),
gg+guides(fill=FALSE, colour=FALSE, size=FALSE),
gg+guides(fill=FALSE, colour=FALSE, size=FALSE),
legg1,
layout_matrix=lay2)
}
theme_custom <- function()
{
theme(
plot.background = element_rect(fill = "#002B36", colour = "#002B36"),
panel.background = element_rect(fill = "#002B36"),
panel.background = element_rect(fill = "#002B36"),
legend.background = element_rect(fill="#002B36", colour = "#002B36"),
legend.margin = unit(c(-4, -4), "cm"),
legend.key = element_rect(fill="#002B36", colour ="#002B36"),
legend.text =element_text(colour = "#DCD427"),
legend.title=element_text(colour = "#DCD427")
)
}
g_legend<-function(a.gplot){
tmp <- ggplot_gtable(ggplot_build(a.gplot))
leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
legend <- tmp$grobs[[leg]]
#+ legend.margin = unit(-0.5, "cm")
legend
}
Try this,
g_legend<-function(gg){
tmp <- ggplot_gtable(ggplot_build(gg))
id <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
leg <- tmp$grobs[[id]]
bkg <- leg[["grobs"]][[1]][["grobs"]][leg[["grobs"]][[1]][["layout"]][,"name"]=="background"][[1]][["gp"]][["fill"]]
leg <- gtable_add_grob(leg, grobs = rectGrob(gp=gpar(fill=bkg, col="red", lty=2)),
t=1, l=1, b=nrow(leg), r=ncol(leg), z=-1)
# no idea why, but the legend seems to have weird negative sizes
# that make the background overlap with neighbouring elements
# workaround: set those unidentified sizes to 1null
leg$widths[c(1,2,4,5)] <- unit(rep(1,4),"null")
leg$heights[c(1,2,4,5)] <- unit(rep(1,4),"null")
leg
}