This notebook assembles individual panels into the final Figure 3 composite. All panels (except A which is a user-provided PNG) are loaded from RDS files for font size control and proper ggplot assembly.
Panel layout (8 panels, A-H):
+---------+---------+
| A | D |
+---------+---------+
| B | E |
+---------+---------+
| C | F |
+---------+---------+
| | G |
| +---------+
| | H |
+---------+---------+
Output:
results/inversion_paper/figures/Figure3_RNAseq.png
library(cowplot)
library(ggpubr)
library(ggtext)
library(magick)
library(grid)
library(ggplot2)
# Panel directory for PNGs
panel_dir <- file.path(paths$figures, "panels")
# Final figure dimensions (2-column width for journal)
# Note: height increased to accommodate 8 panels with ggrepel labels
fig_width_mm <- 280
fig_height_mm <- 370
dpi <- 300
# Convert mm to inches for ggsave
fig_width_in <- fig_width_mm / 25.4
fig_height_in <- fig_height_mm / 25.4
# Helper to load RDS panel with fallback
load_rds_panel <- function(filepath, label, script_hint = "") {
if (file.exists(filepath)) {
p <- readRDS(filepath)
cat(sprintf("Loaded Panel %s from RDS\n", label))
return(p)
} else {
warning(sprintf("Panel %s RDS not found. %s", label, script_hint))
return(ggplot() +
annotate("text", x = 0.5, y = 0.5,
label = paste("Panel", label, "\n(missing)"),
size = 8, color = "gray50") +
theme_void())
}
}
# Panel B: MDS plot
mds_file <- file.path(paths$intermediate, "transcript_MDS_34.rds")
panel_B <- load_rds_panel(mds_file, "B",
"Run differential_expression_leaf_treatment_model.Rmd first.")
## Loaded Panel B from RDS
# Remove axis text/ticks for figure assembly
if (file.exists(mds_file)) {
panel_B <- panel_B +
theme(
axis.text.x = element_blank(),
axis.ticks.x = element_blank(),
axis.text.y = element_blank(),
axis.ticks.y = element_blank()
)
}
# Panel C: Volcano plot
volcano_file <- file.path(paths$intermediate, "volcano_inv4m.rds")
panel_C <- load_rds_panel(volcano_file, "C",
"Run volcano_plot_analysis.Rmd first.")
## Loaded Panel C from RDS
# Panel D: Manhattan Leaf
panel_D_file <- file.path(paths$intermediate, "panel_D_manhattan_leaf.rds")
panel_D <- load_rds_panel(panel_D_file, "D",
"Run make_manhattan_plots.Rmd first.")
## Loaded Panel D from RDS
# Panel E: Manhattan Inv4m
panel_E_file <- file.path(paths$intermediate, "panel_E_manhattan_inv4m.rds")
panel_E <- load_rds_panel(panel_E_file, "E",
"Run make_manhattan_plots.Rmd first.")
## Loaded Panel E from RDS
# Panel F: Haplotype
panel_F_file <- file.path(paths$intermediate, "panel_F_haplotype.rds")
panel_F <- load_rds_panel(panel_F_file, "F",
"Run plot_genotype_get_correlated_loci.Rmd first.")
## Loaded Panel F from RDS
# Panel G: Local Manhattan
panel_G_file <- file.path(paths$intermediate, "panel_G_local_manhattan.rds")
panel_G <- load_rds_panel(panel_G_file, "G",
"Run make_manhattan_plots.Rmd first.")
## Loaded Panel G from RDS
# Panel H: Local logFC
panel_H_file <- file.path(paths$intermediate, "panel_H_local_logfc.rds")
panel_H <- load_rds_panel(panel_H_file, "H",
"Run make_manhattan_plots.Rmd first.")
## Loaded Panel H from RDS
# Helper function to load PNG as ggplot
load_png_panel <- function(filepath, label) {
if (file.exists(filepath)) {
img <- image_read(filepath)
grob <- rasterGrob(img, interpolate = TRUE)
p <- ggdraw() + draw_grob(grob)
} else {
p <- ggplot() +
annotate("text", x = 0.5, y = 0.5,
label = paste("Panel", label, "\n(missing)"),
size = 8, color = "gray50") +
theme_void()
}
return(p)
}
# Load Panel A (leaf sampling schematic - user-provided PNG)
panel_A_file <- file.path(panel_dir, "panel_A_leaf_sampling.png")
panel_A <- load_png_panel(panel_A_file, "A")
# Check status of all panels
status_df <- data.frame(
Panel = c("A", "B", "C", "D", "E", "F", "G", "H"),
Source = c("PNG", "RDS", "RDS", "RDS", "RDS", "RDS", "RDS", "RDS"),
Status = c(
ifelse(file.exists(panel_A_file), "OK", "MISSING"),
ifelse(file.exists(mds_file), "OK", "MISSING"),
ifelse(file.exists(volcano_file), "OK", "MISSING"),
ifelse(file.exists(panel_D_file), "OK", "MISSING"),
ifelse(file.exists(panel_E_file), "OK", "MISSING"),
ifelse(file.exists(panel_F_file), "OK", "MISSING"),
ifelse(file.exists(panel_G_file), "OK", "MISSING"),
ifelse(file.exists(panel_H_file), "OK", "MISSING")
)
)
knitr::kable(status_df, caption = "Panel Availability")
| Panel | Source | Status |
|---|---|---|
| A | PNG | OK |
| B | RDS | OK |
| C | RDS | OK |
| D | RDS | OK |
| E | RDS | OK |
| F | RDS | OK |
| G | RDS | OK |
| H | RDS | OK |
Balance font sizes across all panels for consistent appearance.
# Target base size for readable axes
base_size <- 15
# Panel B (MDS): Keep axes readable, shrink legend (legend.text uses element_markdown)
panel_B <- panel_B +
theme(
axis.title = element_text(size = base_size),
legend.title = element_markdown(size = 15),
legend.background = element_rect(fill = "transparent"),
legend.key = element_rect(fill = "transparent", colour = NA),
legend.position = "top",
plot.margin = unit(c(5.5, 5.5, 5.5, 40), "pt")
)
# Panel C (Volcano): Readable axes, smaller legend
panel_C <- panel_C +
theme(
axis.title = element_text(size = base_size),
axis.text = element_text(size = base_size - 2),
legend.key.size = unit(0.12, "cm"),
legend.position = c(0.81, 0.94),
legend.background = element_rect(fill = "transparent"),
legend.key = element_rect(fill = "transparent", colour = NA)
)
# Panels D, E (Manhattan): Readable axes, smaller title and legend
manhattan_theme <- theme(
plot.title = element_markdown(size = base_size, face = "bold", hjust = 1),
axis.title = element_text(size = base_size),
axis.text = element_text(size = base_size - 2),
axis.text.x = element_text(size = base_size - 3)
)
panel_D <- panel_D + manhattan_theme
panel_E <- panel_E + manhattan_theme
# Panels G, H (Local Manhattan/logFC): Readable axes
local_theme <- theme(
axis.title = element_text(size = base_size),
axis.text.x = element_text(size = base_size - 3),
plot.margin = unit(c(5.5, 5.5, 5.5, 20), "pt")
)
# Panel F: Haplotype
panel_F <- panel_F + local_theme +
theme(
legend.title = element_markdown(size = 15)
)
panel_G <- panel_G + local_theme
panel_H <- panel_H + local_theme
add_label <- function(plot, label, fontface = "bold", size = 14) {
ggdraw(plot) +
draw_label(label, x = 0.02, y = 0.98, hjust = 0, vjust = 1,
fontface = fontface, size = size)
}
panel_A_labeled <- add_label(panel_A, "A")
panel_B_labeled <- add_label(panel_B, "B")
panel_C_labeled <- add_label(panel_C, "C")
panel_D_labeled <- add_label(panel_D, "D")
panel_E_labeled <- add_label(panel_E, "E")
panel_F_labeled <- add_label(panel_F, "F")
panel_G_labeled <- add_label(panel_G, "G")
panel_H_labeled <- add_label(panel_H, "H")
# Column 1: A, B, C
col1 <- plot_grid(
panel_A_labeled,
panel_B_labeled,
panel_C_labeled,
ncol = 1,
rel_heights = c(1, 1, 1),
align = "v",
axis = "lr"
)
# Column 2: D, E, F, G, H
# Panel F needs much more height for the 3 haplotype lines to be clearly visible
col2 <- plot_grid(
panel_D_labeled,
panel_E_labeled,
panel_F_labeled,
panel_G_labeled,
panel_H_labeled,
ncol = 1,
rel_heights = c(0.6, 0.6, 0.6, 0.9, 0.9),
align = "v",
axis = "lr"
)
# Combine columns
figure3 <- plot_grid(
col1,
col2,
ncol = 2,
rel_widths = c(1, 1),
align = "h",
axis = "tb"
)
figure3
output_file <- file.path(paths$figures, "Figure3_RNAseq.png")
ggsave(
output_file,
plot = figure3,
width = fig_width_in,
height = fig_height_in,
dpi = dpi,
bg = "white"
)
cat(sprintf("Figure saved to: %s\n", output_file))
## Figure saved to: /Users/fvrodriguez/Library/CloudStorage/GoogleDrive-frodrig4@ncsu.edu/My Drive/repos/inv4m/results/inversion_paper/figures/Figure3_RNAseq.png
cat(sprintf("Dimensions: %.0f x %.0f mm at %d DPI\n", fig_width_mm, fig_height_mm, dpi))
## Dimensions: 280 x 370 mm at 300 DPI
cat("=== Assembly Complete ===\n\n")
## === Assembly Complete ===
cat("Panel sources:\n")
## Panel sources:
cat(" A (Leaf sampling): PNG (user-provided schematic)\n")
## A (Leaf sampling): PNG (user-provided schematic)
cat(" B (MDS): RDS -> axis removed for assembly\n")
## B (MDS): RDS -> axis removed for assembly
cat(" C (Volcano): RDS\n")
## C (Volcano): RDS
cat(" D (Manhattan Leaf): RDS\n")
## D (Manhattan Leaf): RDS
cat(" E (Manhattan Inv4m): RDS\n")
## E (Manhattan Inv4m): RDS
cat(" F (Haplotype): RDS\n")
## F (Haplotype): RDS
cat(" G (Local Manhattan): RDS\n")
## G (Local Manhattan): RDS
cat(" H (Local logFC): RDS\n")
## H (Local logFC): RDS
cat("\nTo regenerate panels, run:\n")
##
## To regenerate panels, run:
cat(" - differential_expression_leaf_treatment_model.Rmd -> Panel B (MDS)\n")
## - differential_expression_leaf_treatment_model.Rmd -> Panel B (MDS)
cat(" - volcano_plot_analysis.Rmd -> Panel C (Volcano)\n")
## - volcano_plot_analysis.Rmd -> Panel C (Volcano)
cat(" - make_manhattan_plots.Rmd -> Panels D, E, G, H\n")
## - make_manhattan_plots.Rmd -> Panels D, E, G, H
cat(" - plot_genotype_get_correlated_loci.Rmd -> Panel F\n")
## - plot_genotype_get_correlated_loci.Rmd -> Panel F
cat("\nAll RDS panels can have fonts adjusted in this assembly script.\n")
##
## All RDS panels can have fonts adjusted in this assembly script.
sessionInfo()
## R version 4.5.2 (2025-10-31)
## Platform: aarch64-apple-darwin20
## Running under: macOS Tahoe 26.3.1
##
## Matrix products: default
## BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRlapack.dylib; LAPACK version 3.12.1
##
## locale:
## [1] C.UTF-8/C.UTF-8/C.UTF-8/C/C.UTF-8/C.UTF-8
##
## time zone: America/New_York
## tzcode source: internal
##
## attached base packages:
## [1] grid stats graphics grDevices utils datasets methods
## [8] base
##
## other attached packages:
## [1] magick_2.9.0 ggtext_0.1.2 ggpubr_0.6.2 ggplot2_4.0.1 cowplot_1.2.0
## [6] here_1.0.2
##
## loaded via a namespace (and not attached):
## [1] sass_0.4.10 generics_0.1.4 tidyr_1.3.2 rstatix_0.7.3
## [5] xml2_1.5.1 stringi_1.8.7 fastman_0.1.0 digest_0.6.39
## [9] magrittr_2.0.4 evaluate_1.0.5 RColorBrewer_1.1-3 fastmap_1.2.0
## [13] rprojroot_2.1.1 jsonlite_2.0.0 ggrepel_0.9.6 backports_1.5.0
## [17] Formula_1.2-5 purrr_1.2.0 viridisLite_0.4.2 scales_1.4.0
## [21] textshaping_1.0.4 jquerylib_0.1.4 abind_1.4-8 cli_3.6.5
## [25] rlang_1.1.6 litedown_0.9 commonmark_2.0.0 withr_3.0.2
## [29] cachem_1.1.0 yaml_2.3.12 otel_0.2.0 tools_4.5.2
## [33] ggsignif_0.6.4 dplyr_1.1.4 broom_1.0.11 vctrs_0.6.5
## [37] R6_2.6.1 lifecycle_1.0.4 stringr_1.6.0 car_3.1-3
## [41] ragg_1.5.0 pkgconfig_2.0.3 pillar_1.11.1 bslib_0.9.0
## [45] gtable_0.3.6 glue_1.8.0 Rcpp_1.1.0 systemfonts_1.3.1
## [49] xfun_0.55 tibble_3.3.0 tidyselect_1.2.1 knitr_1.51
## [53] dichromat_2.0-0.1 farver_2.1.2 htmltools_0.5.9 labeling_0.4.3
## [57] rmarkdown_2.30 carData_3.0-5 compiler_4.5.2 S7_0.2.1
## [61] markdown_2.0 gridtext_0.1.5