--- title: Composing Surface Panel Figures output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Composing Surface Panel Figures} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} params: family: red css: albers.css resource_files: - albers.css - albers.js includes: in_header: |- --- ```{r setup, include = FALSE} if (requireNamespace("ggplot2", quietly = TRUE) && requireNamespace("albersdown", quietly = TRUE)) { ggplot2::theme_set(albersdown::theme_albers(params$family)) } can_plot <- requireNamespace("neuroatlas", quietly = TRUE) && requireNamespace("ggplot2", quietly = TRUE) && requireNamespace("neurosurf", quietly = TRUE) can_layout <- can_plot && requireNamespace("patchwork", quietly = TRUE) && requireNamespace("scico", quietly = TRUE) knitr::opts_chunk$set( collapse = TRUE, comment = "#>", message = FALSE, warning = FALSE, eval = can_layout ) ``` ```{r} library(neuroatlas) ``` ## What problem are we solving? You often have one or more parcel-level maps and need a figure that is already arranged, labeled, and publication-ready. The awkward part is usually not the parcel values themselves; it is the repeated patchwork work afterward: moving the legend, shortening facet labels, keeping the same scale across panels, and making sure left and right hemispheres are labeled anatomically rather than by screen position. `plot_brain()` and `plot_brain_grid()` are the high-level entry points for that job. They let you compose static surface figures directly from parcel values instead of building the figure by hand after plotting. ## What do you need before you start? For panel figures, you need a surface atlas and one numeric value per parcel. ```{r atlas-and-values} atl <- schaefer_surf( parcels = 200, networks = 7, space = "fsaverage6", surf = "inflated" ) parcel_vals <- seq(-2, 2, length.out = length(atl$ids)) ``` For comparison figures, `plot_brain_grid()` takes a named list of those numeric vectors. ```{r multiple-maps} vals_list <- list( Baseline = sin(seq_along(atl$ids) / 15), Follow_up = cos(seq_along(atl$ids) / 18), Difference = sin(seq_along(atl$ids) / 15) - cos(seq_along(atl$ids) / 18) ) ``` ## How do you build one polished panel figure? Use `plot_brain()` when you want one figure with a few surface panels and a single legend. ```{r single-figure, fig.width=8, fig.height=4.5, fig.alt="Surface panel figure with left and right hemisphere lateral and medial views plus a bottom colorbar"} plot_brain( atl, vals = parcel_vals, views = c("lateral", "medial"), interactive = FALSE, style = "ggseg_like", colorbar = "bottom", colorbar_title = "Standardized effect", title = "Parcel-level summary on fsaverage6", subtitle = "Bottom colorbar plus concise panel labels", panel_labels = c( "Left Lateral" = "LH lateral", "Right Lateral" = "RH lateral", "Left Medial" = "LH medial", "Right Medial" = "RH medial" ) ) ``` This is the default static workflow when you want: - view-aware facet labels without post-hoc editing - one explicit legend instead of an implicit colour mapping - a single annotated figure object you can print or save directly ## How do you compare several maps with one legend? Use `plot_brain_grid()` when each panel is a different map but the colour scale should mean the same thing everywhere. ```{r grid-figure, fig.width=10, fig.height=7, fig.alt="Four-panel surface comparison figure with shared right-side colorbar and repeated hemisphere view labels"} plot_brain_grid( atl, vals_list, views = c("lateral", "medial"), titles = c("Baseline", "Follow-up", "Difference"), shared_scale = TRUE, colorbar = "right", colorbar_title = "z-score", title = "Comparing parcel maps with a shared legend", subtitle = "Every panel uses the same limits and the same view labels", panel_labels = c( "Left Lateral" = "LH lateral", "Right Lateral" = "RH lateral", "Left Medial" = "LH medial", "Right Medial" = "RH medial" ), style = "ggseg_like", ncol = 2 ) ``` The arguments that matter most here are: - `titles`: names each map - `shared_scale = TRUE`: enforces one global value range - `colorbar`: places a shared legend on the right or bottom - `panel_labels`: simplifies the repeated surface-view labels If you want each panel to optimise its own within-panel contrast, use `shared_scale = FALSE`. That can make weak patterns easier to see, but you lose strict colour comparability across panels. ## What do the default panel labels mean? The default panel labels are anatomical hemisphere plus view: - `Left Lateral` - `Right Lateral` - `Left Medial` - `Right Medial` Those names describe the surface itself, not where you happen to place the panel in a larger composition. A right-hemisphere panel is still a right hemisphere if you later move it to the left side of a page. `plot_brain()` now uses a fixed anatomical convention for lateral and medial views: - left hemispheres are drawn with anterior on the left - right hemispheres are drawn with anterior on the right That means `panel_labels = c("Right Lateral" = "Right hemisphere")` is a safe simplification when you are showing one view per hemisphere. If you mix lateral and medial views, keep the view in the label unless you have a strong reason to collapse it. ## Which layout controls are worth remembering? These are the arguments you will use repeatedly: - `style = "ggseg_like"` gives a presentation-oriented default layout - `panel_layout = "presentation"` is the explicit layout control behind that style - `panel_labels` rewrites facet labels without changing the underlying hemisphere/view mapping - `colorbar` and `colorbar_title` control the standalone legend - `title`, `subtitle`, and `caption` annotate the composed figure directly - `ncol` controls the panel grid for both `plot_brain()` and `plot_brain_grid()` If you need the raw projected coordinates for a custom workflow, use `panel_layout = "native"`. If you want the cleaner, more balanced publication layout, use `panel_layout = "presentation"` or `style = "ggseg_like"`. ## Where should you go next? Use this vignette as the reference for figure composition, then branch out depending on what you need next: - `vignette("surface-parcellations", package = "neuroatlas")` for loading surface atlases and overlays - `vignette("atlas-visualization", package = "neuroatlas")` for volumetric plotting and palette workflows - `?plot_brain` for the full single-figure API - `?plot_brain_grid` for the shared-scale multi-panel API