Getting Started with neuromapr

knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.width = 6,
  fig.height = 4
)

Two brain maps look correlated. But the brain is spatially autocorrelated---nearby regions tend to have similar values simply because they are neighbours. A standard correlation test ignores this structure, which inflates p-values and produces false positives.

neuromapr exists to answer one question honestly: is the similarity between two brain maps more than spatial structure alone would predict?

It generates surrogate maps that preserve the spatial autocorrelation of the original data, then measures where the real correlation falls in that null distribution. The framework follows Markello et al. (2022).

library(neuromapr)

Comparing two brain maps

The core workflow: load data, compare, interpret. We simulate two brain maps here to keep things self-contained, but in practice you would read real data from GIFTI or NIfTI files.

set.seed(42)
n <- 100
coords <- matrix(rnorm(n * 3), ncol = 3)
distmat <- as.matrix(dist(coords))

map_a <- rnorm(n)
map_b <- 0.4 * map_a + rnorm(n, sd = 0.8)

Two maps with a planted correlation around 0.4, plus a distance matrix describing the spatial layout. The simplest comparison:

result <- compare_maps(map_a, map_b, verbose = FALSE)
result

The r and parametric p tell the familiar story. But that p assumes independence between observations---an assumption the brain violates everywhere.

Adding a spatial null model

To get an honest p-value, we generate surrogate versions of map_a that preserve its spatial autocorrelation, then check whether the observed correlation is unusual against correlations with those surrogates.

neuromapr provides eight null model methods. For parcellated data with a distance matrix, variogram matching (burt2020) is a strong default:

result_null <- compare_maps(
  map_a, map_b,
  null_method = "burt2020",
  distmat = distmat,
  n_perm = 500L,
  seed = 1,
  verbose = FALSE
)
result_null

The p_null value now accounts for spatial autocorrelation. If it remains small, the relationship between the two maps is unlikely to be an artifact of shared spatial structure.

Visualising the null distribution

The comparison object stores all null correlations, making it straightforward to see where the observed value falls:

null_df <- data.frame(r = result_null$null_r)
obs_r <- result_null$r

ggplot2::ggplot(null_df, ggplot2::aes(x = r)) +
  ggplot2::geom_histogram(
    bins = 30, fill = "steelblue", alpha = 0.7
  ) +
  ggplot2::geom_vline(
    xintercept = obs_r,
    linetype = "dashed", color = "red", linewidth = 1
  ) +
  ggplot2::labs(
    x = "Null correlation (r)",
    y = "Count"
  ) +
  ggplot2::theme_minimal()

When the observed correlation sits well outside the null distribution, the relationship is more likely genuine. When it sits inside, spatial autocorrelation alone can explain the similarity.

Pre-computing null distributions

Generating nulls is the expensive part. If you want to compare the same map against several targets, generate once and reuse:

nulls <- generate_nulls(
  map_a,
  method = "moran",
  distmat = distmat,
  n_perm = 200L,
  seed = 42
)
nulls

The null_distribution object has print, summary, plot, and as.matrix methods. The summary gives per-element null means and standard deviations. The plot method shows the null distribution for a chosen element:

plot(nulls, parcel = 1L)

Pass the pre-computed object to compare_maps():

compare_maps(map_a, map_b, nulls = nulls, verbose = FALSE)

No redundant computation when the same source map appears in multiple comparisons.

Working with real brain map files

In practice, brain maps live on disk. compare_maps() and read_brain_map_values() accept file paths directly:

values <- read_brain_map_values("cortical_thickness.func.gii")

result <- compare_maps(
  "path/to/map_a.func.gii",
  "path/to/map_b.func.gii",
  null_method = "moran",
  distmat = distmat
)

Both GIFTI (.func.gii) and NIfTI (.nii.gz) formats are supported. No separate reading step needed.

Accessing the neuromaps atlas collection

The neuromaps project curates a registry of published brain map annotations---PET receptor maps, gene expression, cortical thickness, and more. neuromapr provides direct access to this collection:

neuromaps_available()

neuromaps_available(source = "beliveau", tags = "pet")

Once you find the annotation you want, download it:

paths <- fetch_neuromaps_annotation(
  "abagen", "genepc1", "fsaverage",
  density = "10k"
)

Files are cached locally, so subsequent calls skip the download. The registry is fetched from the neuromaps GitHub repository and cached for the session.

Custom metrics with permtest_metric()

compare_maps() is built around correlation. For other metrics---mean absolute error, cosine similarity, anything that takes two vectors and returns a scalar---permtest_metric() provides the same null model machinery:

mae <- function(a, b) mean(abs(a - b))

result_mae <- permtest_metric(
  map_a, rnorm(n),
  metric_func = mae,
  n_perm = 200L,
  seed = 1
)
result_mae$observed
result_mae$p_value

Add null_method for spatially-constrained surrogates instead of random permutation:

result_spatial <- permtest_metric(
  map_a, rnorm(n),
  metric_func = mae,
  n_perm = 200L,
  seed = 1,
  null_method = "burt2020",
  distmat = distmat
)
result_spatial$p_value

Choosing a null model

The right model depends on your data:

| Situation | Recommended method | |---|---| | Parcellated data with distance matrix | "burt2020" or "moran" | | Vertex-level with sphere coordinates | "spin_hungarian" or "alexander_bloch" | | Parcellated with sphere coordinates | "baum" or "cornblath" | | Spatial autoregressive structure | "burt2018" |

vignette("null-models") walks through each method in detail.

What comes next

This vignette covered the essential workflow: compare maps, generate spatially-constrained null distributions, and interpret results. From here:

References

Markello RD, Hansen JY, Liu Z-Q, et al. (2022). neuromaps: structural and functional interpretation of brain maps. Nature Methods, 19, 1472--1480. doi:10.1038/s41592-022-01625-w



Try the neuromapr package in your browser

Any scripts or data that you put into this service are public.

neuromapr documentation built on Feb. 27, 2026, 5:08 p.m.