The sections below are incomplete!
The package includes a few images that can be used for demonstrating its capabilities. The locations of the images (and the code to load them) are listed below.
# MNI 2009c anatomical underlay
underlay_3mm <- system.file("extdata", "mni_template_2009c_3mm.nii.gz", package = "ggbrain")
# onset of decision phase for learning task
decision_onset_3mm <- system.file("extdata", "decision_onset_zstat_3mm.nii.gz", package = "ggbrain")
# Parametric modulator: entropy change following feedback in learning task
echange_overlay_3mm <- system.file("extdata", "echange_overall_zstat_3mm.nii.gz", package = "ggbrain")
# Schaefer 200-parcel atlas of cortex
schaefer200_atlas_3mm <- system.file("extdata", "Schaefer_200_7networks_2009c_3mm.nii.gz", package = "ggbrain")
print(c(underlay_3mm, decision_onset_3mm, echange_overlay_3mm, schaefer200_atlas_3mm))
## [1] "/private/var/folders/y0/pkh_h_511bn27zjj8m0w2wx00000gn/T/Rtmpv6gHgC/Rinst5aba1fc64864/ggbrain/extdata/mni_template_2009c_3mm.nii.gz"
## [2] "/private/var/folders/y0/pkh_h_511bn27zjj8m0w2wx00000gn/T/Rtmpv6gHgC/Rinst5aba1fc64864/ggbrain/extdata/decision_onset_zstat_3mm.nii.gz"
## [3] "/private/var/folders/y0/pkh_h_511bn27zjj8m0w2wx00000gn/T/Rtmpv6gHgC/Rinst5aba1fc64864/ggbrain/extdata/echange_overall_zstat_3mm.nii.gz"
## [4] "/private/var/folders/y0/pkh_h_511bn27zjj8m0w2wx00000gn/T/Rtmpv6gHgC/Rinst5aba1fc64864/ggbrain/extdata/Schaefer_200_7networks_2009c_3mm.nii.gz"
For reasons that are somewhat boring (having to do with how R handles
S3 operators like +
), the brain-related addition steps for
ggbrain
object must come before generic
ggplot2
modifications of the plot. More specifically, the
use of the +
operator for ggbrain commands like
geom_brain()
or images()
create and modify an
object that is internal to the
blur_edge = NULL,
fill_holes = NULL, remove_specks = NULL, trim_threads = NULL)
At times, when slicing a given image (esp. functional activations),
it is possible that some clusters are very small, yielding small
‘specks’ on some rendered slices. These are visually unappealing and may
merit removal, depending on your tastes. Of course, removing these
specks can, at the extreme, misrepresent the data, which is undesirable.
This concern notwithstanding, you can use the clean_specks
argument of images
to specify the voxel threshold used to
remove clusters smaller than a certain size. For example,
clean_specks = 30
would remove any clusters smaller than 30
voxels in size from each slice on the rendered image.
# TODO: make this in geom_brain
gg_obj <- gg_obj + images(echange=echange_overlay_3mm)
Another aesthetic problem is that at times there will be small holes
on the interior of a cluster. These may reflect voxels that fall below a
statistical threshold (e.g., voxels that have a z-statistic value of
3.02 in a cluster defined by z > 3.1). These can be filled in using
the fill_holes
argument of images
. This
specifies the size of holes (in voxels) that should be filled on the
rendered slices. For example, fill_holes = 30
would fill
holes of 30 or fewer voxels on the interior of each cluster. The holes
are filled by nearest neighbor imputation in which the nearest
non-missing voxels are used to impute missing voxels. In
integer-valued/categorical images, the mode of the neighboring voxels is
used for imputation.
# TODO: make this in geom_Brain
gg_obj <- gg_obj + images(echange=echange_overlay_3mm)
a <- ggbrain(bg_color = "gray60", text_color = "black") +
images(c(underlay = "template_brain.nii.gz")) +
images(c(dan_clust = dan_clust), fill_holes = TRUE, clean_specks = 20, labels = dan_labels) +
# slices(paste0("x = ", seq(10, 90, 10), "%")) +
slices(montage("axial", 10, min = 0.1, max = 0.8)) +
# add_slice("y=50%", title = "hello", xlab = "testx", border_size = 1, border_color = "blue") +
geom_brain(definition = "underlay", fill_scale = scale_fill_gradient(low = "grey8", high = "grey62"), show_legend = FALSE) +
geom_brain(definition = "dan_clust", mapping = aes(fill = label), fill_scale = scale_fill_brewer("DAN 17 label", palette = "Set1"), show_legend = TRUE) +
geom_outline(definition = "dan_clust", mapping = aes(group = roi_label), show_legend = TRUE, outline = "black") + # fill_scale = scale_fill_discrete("hello"),
# geom_outline(definition = "dan_clust", show_legend = TRUE, mapping=aes(group=label), size=2, outline="cyan") + #fill_scale = scale_fill_discrete("hello"),
# geom_outline(definition = "dan_clust", show_legend = TRUE, outline = "cyan") + #fill_scale = scale_fill_discrete("hello"),
geom_region_label_repel(image = "dan_clust", label_column = "roi_label", min.segment.length = 0, size = 1.5, color = "black", force_pull = 0.2, max.overlaps = Inf) +
render() + plot_layout(guides = "collect")
[Principles of patchwork]
Oftentimes, higher-resolution images (e.g., 1mm) yield better
graphics since they potentially provide more detail. But fMRI data are
often of lower resolution than T1-weighted images. If you wish to render
your fMRI data on a higher-resolution anatomical template in
ggbrain
, you can first use AFNI’s 3dresample
command to resample your functional data to match the anatomical
template (underlay).
Here is an example of resampling a 3mm statistic image to a 1mm underlay using nearest neighbor interpolation. Note that the image to be resampled should be in the same sterotaxic space as the master/template image.
3dresample -input echange_overall_zstat_3mm.nii.gz \
-prefix echange_overall_zstat_1mm.nii.gz \
-master mni_template_2009c_1mm.nii.gz \
-rmode NN
The ggbrain
package uses the ggplot2
package to create 2D volume renderings of NIfTI files containing MRI
data. It seeks to follow the principles of a graphical grammar in which
plots are built from datasets that are mapped onto the visual space via
a set of aesthetic mappings. Likewise, ggbrain
follows the
approach of creating layers in which different geometric marks (e.g.,
square pixels) are overlaid on the plot, such that many images and marks
can be combined.
Every ggbrain plot is composed of one or more panels that have layers representing different images that have been overlaid. Each panel contains a slice along one of the three axes of the volume: x (Left-Right), y (Anterior-Posterior), or z (Superior-Inferior). Panels can also contain annotations that reflect one or more marks to aid in the interpretation of the plot, as well as region labels in which text is positioned at certain markers within the displayed brain slice.
annotate
function (e.g., coordinate
label)geom_text
, region
labels represent text that should be overlaid at one or more spatial
positions across the panel/slice (e.g., anatomical labels)Use bg argument
ggsave("test.png", gg_obj$render(), width=8, height=6, bg="blue")
pdf("test_dev.pdf", width=8, height=6, bg="blue")
plot(gg_obj)
dev.off()