I am generating a set of plots within a for loop using ggplot2
and setting the overall ggplot
export size with:
ppi <- 300
tiff(file_name, width=2*ppi, height=2*ppi, res=ppi)
However, the actual plot panel size changes when, for example, the number of digits shown along the y-axis changes.
How can this be modified to work for tiff exports?
Reproducible example here (edited to include set_panel_size function:
> CohData
Name ScenID ScenName Year VarName Units value
1 Site01 0 Hind 2000 ANC ueq/L 28.23
2 Site02 0 Hind 2000 ANC ueq/L 35.34
3 Site03 0 Hind 2000 ANC ueq/L 31.73
4 Site04 0 Hind 2000 ANC ueq/L 54.21
5 Site05 0 Hind 2000 ANC ueq/L 28.23
6 Site01 1 BC 2020 ANC ueq/L 45.01
7 Site02 1 BC 2020 ANC ueq/L 32.86
8 Site03 1 BC 2020 ANC ueq/L 30.38
9 Site04 1 BC 2020 ANC ueq/L 53.01
10 Site05 1 BC 2020 ANC ueq/L 31.11
11 Site01 0 Hind 2000 pH 6.40
12 Site02 0 Hind 2000 pH 5.93
13 Site03 0 Hind 2000 pH 6.36
14 Site04 0 Hind 2000 pH 5.75
15 Site05 0 Hind 2000 pH 5.16
16 Site01 1 BC 2020 pH 6.63
17 Site02 1 BC 2020 pH 5.86
18 Site03 1 BC 2020 pH 6.33
19 Site04 1 BC 2020 pH 5.73
20 Site05 1 BC 2020 pH 5.23
## Iterate plots and write to tiff
theme_set(theme_bw(base_size = 8))
ppi <- 300
CohData_nohind <- subset(CohData, ScenID > 0)
stream_vars <- list("ANC", "pH")
for (i in unique(CohData_nohind$ScenID)){
subdata1 <- subset(CohData_nohind, ScenID == i)
ScenName <- unique(subdata1$ScenName)
subdata1 <- subset(CohData, ScenID == i | ScenID == 0)
for (j in stream_vars){
subdata2 <- subset(subdata1, VarName == j)
units <- unique(subdata2$Units)
for (k in unique(subdata2$Name)){
subdata3 <- subset(subdata2, Name == k)
if (j=='ANC'){
file_name = paste("stream", k,i,j, ".tiff", sep="")
#OLD Code tiff(file_name, width=2*ppi, height=2*ppi, res=ppi)
print(ggplot(subdata3, aes(x = Year, y = value)) + geom_line() + expand_limits(y=c(0,100)) +
ggtitle(paste0(as.character(ScenName),":\n", as.character(k))) + ylab(paste0(j, " (", units, ")")))
set_panel_size <- function(p=NULL, g=ggplotGrob(p), file=file_name,
margin = unit(1,"mm"),
width=unit(4, "cm"), height=unit(4, "cm")){
panels <- grep("panel", g$layout$name)
panel_index_w<- unique(g$layout$l[panels])
panel_index_h<- unique(g$layout$t[panels])
nw <- length(panel_index_w)
nh <- length(panel_index_h)
# the following conversion is necessary
# because there is no `[<-`.unit method
# so promoting to unit.list allows standard list indexing
g$widths <- grid:::unit.list(g$widths)
g$heights <- grid:::unit.list(g$heights)
g$widths[panel_index_w] <- rep(list(width), nw)
g$heights[panel_index_h] <- rep(list(height), nh)
class(g) <- c("fixed", class(g), "ggplot")
if(!is.null(file))
ggsave(file, g,
width = convertWidth(sum(g$widths) + margin, unitTo = "in", valueOnly = TRUE),
height = convertHeight(sum(g$heights) + margin, unitTo = "in", valueOnly = TRUE))
g
}
print.fixed <- function(x) grid.draw(x)
#OLD Code: dev.off()
} else if (j=='pH'){
file_name = paste("stream", k,i,j, ".tiff", sep="")
#OLD Code: tiff(file_name, width=2*ppi, height=2*ppi, res=ppi)
print(ggplot(subdata3, aes(x = Year, y = value)) + geom_line() + expand_limits(y=c(3,7)) +
ggtitle(paste0(as.character(ScenName),":\n", as.character(k))) + ylab(paste0(j, " (", units, ")")))
set_panel_size <- function(p=NULL, g=ggplotGrob(p), file=file_name,
margin = unit(1,"mm"),
width=unit(4, "cm"), height=unit(4, "cm")){
panels <- grep("panel", g$layout$name)
panel_index_w<- unique(g$layout$l[panels])
panel_index_h<- unique(g$layout$t[panels])
nw <- length(panel_index_w)
nh <- length(panel_index_h)
# the following conversion is necessary
# because there is no `[<-`.unit method
# so promoting to unit.list allows standard list indexing
g$widths <- grid:::unit.list(g$widths)
g$heights <- grid:::unit.list(g$heights)
g$widths[panel_index_w] <- rep(list(width), nw)
g$heights[panel_index_h] <- rep(list(height), nh)
class(g) <- c("fixed", class(g), "ggplot")
if(!is.null(file))
ggsave(file, g,
width = convertWidth(sum(g$widths) + margin, unitTo = "in", valueOnly = TRUE),
height = convertHeight(sum(g$heights) + margin, unitTo = "in", valueOnly = TRUE))
g
}
print.fixed <- function(x) grid.draw(x)
#OLD Code: dev.off()
}
}
}
}