ggseg (development version)
A major release. The atlas geometry now comes from the re-keyed ggseg.formats atlases (>= 0.0.4.9008), and geom_brain() has been rebuilt on a Stat so that faceting, inherited data/aes(), and outline aesthetics work the way ggplot2 users expect. Several of those fixes change existing figures, so read the breaking changes before upgrading.
Breaking changes
Region keys changed.
ggseg.formatsre-keyed the bundled atlases: theregioncolumn now holds short keys (e.g."superiorparietal","transversetemporal") and the fully spelled-out names moved to a newnamescolumn. Any user data joined to an atlas byregionmust be re-keyed. Passing a long name where aregionis expected no longer matches, andgeom_brain()warns that the rows were not merged.ggseg.formatsships a helper for translating old keys to new — look forlegacy_region_map()in theggseg.formatsreference — or join by the schema-stablelabelcolumn instead.ggsegnow requiresggseg.formats (>= 0.0.4.9008); the combination of an olderggsegwith the re-keyed atlases is silently wrong, which the new floor rules out.GeomBrainis a different object. Both 2.2.1 and 3.0.0 exportGeomBrain, but it is no longer the same ggproto: it is now the polygon geom (GeomBrain<ggplot2::GeomPolygon<ggplot2::Geom) that backs the defaultgeom_brain(). The sf geom it used to be is nowGeomBrainSf, which this release also exports so extension code doingggplot2::layer(geom = GeomBrain)against the sf path has a migration target: switch toGeomBrainSf. Because the export name did not change, the failure mode in extension code is a confusing rendering error rather than an object-not-found error — check any package that reaches forGeomBraindirectly.geom_brain()gained afunargument, positionally beforeshow.legend. The signature is nowgeom_brain(mapping, data, atlas, hemi, view, position, context, fun, show.legend, inherit.aes, ...). Callers passingshow.legendorinherit.aespositionally shift by one — name those arguments.Multiple
datarows per region are now combined, not overplotted.fun(defaultmean) reduces them within each facet panel. Long data with several rows per region — one per subject, say — used to overplot, so the last row silently won; it is now averaged. This is a silent numeric change for anyone plotting an unaggregated cohort, sogeom_brain()warns once per session whenfunactually collapses rows. Passfun = dplyr::lastto recover the old last-wins behaviour.funapplies to numeric columns only — non-numeric columns take the first value of the group regardless.aes()mappings forx,y,group, andsubgroupare ignored, with a warning. They are derived from the atlas geometry (groupis the polygon feature id,subgroupmarks holes), so mapping them previously corrupted the rendering silently —aes(group = region)collapsed each region’s separate polygon pieces.Polygon draw order now follows your data’s row order. It used to be the atlas’s own polygon order regardless of your data, so when you mapped a variable to
colourthe outlines stacked in an order unrelated to it. Regions now draw in the order they appear in yourdata(later rows on top); regions you supply no value for stay underneath in atlas order.arrange()your data to control layering. Visual-only, but it restacks overlapping outlines (#162).position_brain()ignores thehemiterm for slice-based atlases (subcortical, cerebellar, tract), with a warning. Those views are whole slices already containing both hemispheres, sohemi ~ viewno longer splits the grey context into its own row away from the structures. Each view now renders with its anatomical context integrated, matchingplot(). Subcortical and tract plots usinghemi ~ viewlay out differently (correctly).
New features
New
stat_brain()and exportedStatBrainggproto: the stat-first spelling ofgeom_brain(). Both build the same layer; usestat_brain()to pairStatBrainwith a different geom.New
brain_test_plot()builds a minimal, deterministic atlas plot (regions filled bylabel, no legend,theme_void()) — the canonical construction forvdiffrsnapshots across the ggsegverse, so a stray legend or title cannot creep into a snapshot and every atlas renders identically. It defaults toposition_brain(. ~ view)for slice-based atlases andposition_brain(hemi ~ view)for cortical ones.GeomBrainSfis now exported (see above).
Bug fixes
A bare
geom_brain()again colours the atlas by its palette, keyed onlabel— unchanged from 2.2.1. The default is now installed at build time, so a top-levelaes(fill = value)wins instead of erroring with “Continuous value supplied to a discrete scale”.Faceting no longer needs
dplyr::group_by(). The atlas geometry is drawn byStatBrain, which ggplot2 recomputes per panel, sofacet_wrap()/facet_grid()work directly from your data. Faceting on a variable of your own draws the complete brain in every panel; faceting on an atlas column (hemi,view) draws that slice in each panel, as before.geom_brain()again respectsdataand aesthetics set in the top-levelggplot()call. The polygon renderer built the atlas eagerly, before the plot existed, so it never saw inheriteddata/aes()(#158).geom_brain()again mapsaes(colour = ...)andaes(linewidth = ...)to region outlines. The defaults (grey35,0.2) were injected as fixed geom parameters, which silently overrode any mapping; they are nowdefault_aesonGeomBrain(#160).geom_brain()again warns when rows of yourdatamatch no atlas region. The polygon renderer’s left join dropped unmatched rows silently (#121).scale_x_brain(),scale_y_brain()andscale_labs_brain()no longer require the optionalsfpackage. They derived their axis breaks by converting the atlas tosfand reading coordinates back out, so on a system withoutsfthey errored instead of working – even thoughsfmoved to Suggests in 2.2.0 and everything else on the default path had been made sf-free. They now read the coordinates from the polygon representation (ggseg.formats::atlas_polygons()). The breaks and labels are unchanged fordk(),aseg()andtracula(); a test pins them to the sf-derived values.geom_brain(position = )again applies a layout string or formula. Previously only aposition_brain()spec took effect; everything else, including an invalid value, was silently dropped. Strings and formulas are now coerced,"identity"opts out, and anything else errors.Axis scales work for cerebellar atlases such as
suit().adapt_scales()returnedNULLfor any type outside cortical/subcortical/tract, soscale_x_brain()and friends produced empty scales. Unsupported types now error.scale_continous_brain()no longer returns a scale without breaks at its defaultaesthetics = c("y", "x"); the argument was matched after it was used.position_brain(hemi ~ view, nrow = 2)now errors instead of silently discarding the formula, andnrow/ncolmust be positive whole numbers (ncol = 0producedInfgrid indices). The deprecatedposition_brain_sf()andreposition_brain()validate the same way, and before theirsfguard, so a bad argument is not reported as a missingsf.A
nrow/ncolgrid on a cortical atlas now gives each hemisphere/view pair its own cell; it split onviewalone, putting both hemispheres in every cell.position_brain(views = )warns when a named view is not in the atlas, andzoom =warns when a named region is not, instead of silently dropping it.zoom = TRUEresolves its focus fromlabelbeforeregion, and a named focus may use either vocabulary.A layout formula variable containing a dot (e.g.
my.col ~ view) is no longer dropped along with the.placeholder.annotate_brain()accepts a layout string or formula without requiring the optionalsf; it routed every non-specpositioninto the sf implementation.scale_brain()and friends error with the available atlas names whennameis not an atlas;match.fun()resolved any visible function.The deprecated
scale_*_brain()scales warn at build time when no mapped value is a palette key. Atlas palettes are keyed bylabel, soaes(fill = region)drew every region inna.valuewith no signal.Laying out a data frame that mixes atlas types now errors with an explanation rather than R’s “condition has length > 1”.
Documentation and internals
Roxygen documentation now uses markdown.
positioning-views.Rmdused region and view names no atlas has ("Thalamus Proper",coronal_3), so three zoom figures and two view-selection figures demonstrated nothing.Tests, examples, and vignettes resolve region names dynamically through
ggseg.formats::atlas_regions()and the schema-stablelabelcolumn instead of hard-coding region strings.vdiffrsnapshots are keyed by atlas schema through testthat’svariantmechanism, so one snapshot set perggseg.formatsschema can be committed side by side.The test helpers no longer attach Suggests packages unconditionally, so the suite degrades to skips rather than erroring under
_R_CHECK_DEPENDS_ONLY_=true.
ggseg 2.2.1
CRAN release: 2026-07-03
- The test suite now builds its
sffixtures through the public atlas accessors instead of reaching into atlas internals, so tests no longer break when the internal atlas layout changes.
ggseg 2.2.0
CRAN release: 2026-06-22
This release makes the sf package optional. ggseg now draws brains from a lightweight polygon representation by default, so it installs and plots even on systems where sf (and its GDAL / GEOS / PROJ system libraries) is unavailable — including WebAssembly and air-gapped setups.
sf is now optional
-
Your plotting code keeps working, without sf.
geom_brain(),position_brain(), andannotate_brain()produce the same figures as before, now drawn withoutsf.sfhas moved from Imports to Suggests. -
Need the full sf toolkit? To add region labels with
geom_sf_label(), layer other sf geoms, or wrangle the geometry directly, convert an atlas withas_sf_atlas()and useggplot2::geom_sf(). Seevignette("geom-sf"). - The sf-backed
geom_brain_sf()andposition_brain_sf()remain for a transition period but are deprecated and will be removed in a future release.
New plotting features
-
Zoom in on regions of interest.
position_brain(zoom = ...)crops each view onto the regions you’re highlighting so they fill the panel, with the surrounding brain reduced to a tidy grey frame. Usezoom = TRUEto follow the regions in your data, or name them explicitly;zoom_padsets the margin. Especially handy for focus atlases where only a few structures carry values. -
Readable view labels.
annotate_brain()now places labels clear of the brain instead of on top of it. The newpaddingargument (5% of the plot height by default) controls the gap. -
One annotation function.
annotate_brain()works with whicheverpositionyou gave the geom — there’s no separate labelling function to remember. -
Hide context regions.
geom_brain(context = FALSE)drops the grey, unlabelled regions and tightens the layout around the regions you’re plotting. -
Faceting. Group your data with
dplyr::group_by()andfacet_wrap()/facet_grid()draw the full atlas in every panel. -
FreeSurfer labels. Data keyed by
label(e.g."lh_bankssts") now joins to the atlas directly, in addition toregion.
Other changes
- When no
fillis mapped,geom_brain()fills regions with the atlas’s own colours, and the stray “No shared levels” warning that appeared when filtering by hemisphere or view is gone. - New
coord_brain()keeps brain proportions undistorted;geom_brain()applies it automatically, so you rarely need to add it yourself. - The deprecated
scale_brain()family keeps working with the currentggseg.formats. - The
suitcerebellar atlas is re-exported alongsidedk(),aseg(), andtracula().
ggseg 2.1.0
CRAN release: 2026-04-03
- Support cerebellar atlas type in 2D view stacking. Cerebellar atlases now use the same stacking layout as subcortical atlases in
position_brain().
ggseg 2.0.0
CRAN release: 2026-02-19
This is a major release that simplifies the package architecture by moving atlas data structures and utilities to the ggseg.formats package.
Breaking changes
ggseg()is now defunct and errors immediately. Useggplot() + geom_brain()instead.Atlas data (
dk,aseg) is no longer bundled in ggseg. Atlases are now provided by ggseg.formats and re-exported as functions:dk(),aseg(),tracula(). Code using the bare objects (e.g.,atlas = dk) must be updated toatlas = dk().The following functions have been removed and are now in ggseg.formats:
as_brain_atlas(),is_brain_atlas(),brain_atlas(),brain_regions(),brain_labels(),brain_pal(),brain_pals_info(),ggseg_atlas(),as_ggseg_atlas(),is_ggseg_atlas(),read_freesurfer_stats(),read_freesurfer_table(),read_atlas_files().scale_brain2(),scale_fill_brain2(),scale_colour_brain2(), andscale_color_brain2()are deprecated in favour ofscale_brain_manual(),scale_fill_brain_manual(),scale_colour_brain_manual(), andscale_color_brain_manual().scale_brain(),scale_fill_brain(),scale_colour_brain(), andscale_color_brain()are deprecated. Atlas palettes are now applied automatically bygeom_brain().The
sideargument ingeom_brain()andposition_brain()has been renamed toview.
New features
New
annotate_brain()function adds view labels (e.g., “left lateral”) to brain plots, respecting the layout fromposition_brain().New
scale_brain_manual()family for applying custom named colour palettes to brain plots.position_brain()gainsnrow,ncol, andviewsarguments for grid-based layout control of subcortical and tract atlases.adapt_scales()now accepts atlas objects directly (not just pre-converted coordinate data frames), and handles"tract"atlas types alongside subcortical.geom_brain()now automatically applies the atlas colour palette when nofillaesthetic is mapped.
Improvements
Messaging uses cli for all user-facing output (
brain_join()warnings and info messages).Rewrote and reorganised all vignettes with updated examples and renamed files for cleaner URLs.
Added tracula (white matter tract) atlas as a re-export from ggseg.formats.
Improved documentation throughout with updated roxygen2 docs.
ggseg 1.6
ggseg 1.6.7
- Fixed testthat issues with latest version of testthat
- Fixed vignette build issues on CRAN
- removed sf minimum version requirement
ggseg 1.6.5
- Bump version to 1.6.5
- rm freesurfer dep
- rm old remnants
- update readme img
- switch cerebellum labels for wm, gm, fix #80
- fix aseg labels to original, fix #78
- add vis as categorical. fix #76
- change aseg data class , fix #56
- bump version, small CRAN fixes
- add sysreq
- fix axial to coronal in vignette
- change axial to coronal in aseg data
- re-add ggplot2 depends
1.6.4
- Added options
hemiandsideto geom - improved
position_brain()to accept character vector, and also support subcortical atlases - Altered axial to coronal in aseg atlas
ggseg 1.6.3
- removed function to display ggseg palettes
- preparations for CRAN submission
- added examples to more functions
- updated links
ggseg 1.6.02
- bug fixes in atlas objects and method internals
- tests in vdiffr
- vctrs class for polygon ggseg data
ggseg 1.6.02
- No longer depends on ggplot2, but imports it.
- as is advised practice
- users must explicitly load ggplot2 to access further ggplot2 functions
ggseg 1.6.00
New large update, many new features. Of particular note is the introduction of the brain sf geom, which improved speed, and adaptability of the plots.
-
ggseg()will stay for a while, but is superseded by a simple features geom -
geom_brainintroduced as a new function to plot the atlas data- an sf geom provides a lot of new features to the package
- more control over display of the slices through
position_brain() - improved capabilities for atlases with regions that have holes
- new atlas class
brain_atlaswhich contains simple features data - new functions to allow compatibility between sf and polygon data
- utility functions to use on the atlas data for easy access to information
-
plot()functions for ggseg_atlas and brain_atlas classes for a quick look at atlases -
brain_regionsfunctions to easily extract the unique names of regions for an atlas - improved
printmethod for atlases classes ggseg_atlas and brain_atlas
-
ggseg 1.5.4
- dkt renamed to dk
- the dkt (Desikan-Killiany-Tourville) atlas is not yet available
- atlas columns
arearenamed toregion- to avoid confusion with the calculation of cortical/surface area
- dk atlas region name “medial orbito frontal” changed to “medial orbitofrontal”
ggseg 1.5
Changed atlas.info to function
atlas_info()Changed brain.pal to function
brain_pal()Changed atlas.info to function
atlas_info()Reduced code necessary for
brain_pals_infoSimplified
display_brain_pal()Moved palettes of ggsegExtra atlases to ggsegExtra package
Added a
NEWS.mdfile to track changes to the package.Added compatibility with
groupeddata.framesReduced internal atlases, to improve CRAN compatibility
Added function to install extra atlases from github easily
Changes vignettes to comply with new functionality
