class: middle, right, title-slide # Visualizing brain data ## - the ggseg-suite of R-packages - ### Athanasia Monika Mowinckel ### 27.11.2020 --- class: middle .pull-left[ <img src="https://www.sv.uio.no/psi/personer/vit/athanasm/athanasia.mowinckel.2.small.png" width="auto" height="600px" /> ] .pull-right[ ## Athanasia Monika Mowinckel - Staff scientist - PhD in cognitive psychology - Software Carpentry Instructor - Currently doing quite some R-package development & other in-house research software development - Find me - Twitter: [DrMowinckels](https://twitter.com/DrMowinckels) - GitHub: [Athanasiamo](https://github.com/Athanasiamo) - Website/Blog: [DrMowinckels.io](https://drmowinckels.io/) ] --- background-image: url(https://www.lifebrain.uio.no/vrtx/decorating/resources/images/logo.png), url(https://www.lifebrain.uio.no/web-banner_rev.jpg), url(https://www.lifebrain.uio.no/vrtx/decorating/resources/images/eu-flag.jpg) background-position: 50% 10%, 50% 80%, 90% 10% --- layout: true <div class="my-sidebar"></div> --- class: dark, center, middle # Neuroimaging workflows --- background-image: url(https://fsl.fmrib.ox.ac.uk/fsl/wiki_static/fsl/img/fsl-logo-x2.png), url(https://freesurfer2016.sciencesconf.org/conference/freesurfer2016/pages/FSlogo.png), url(https://nipype.readthedocs.io/en/latest/_static/nipype-banner-bg.png), url(https://www.mathworks.com/matlabcentral/mlc-downloads/downloads/98b0f6cf-f7e6-4051-b4f4-2aacf06f551b/a5cdc6ec-7ee3-4aaa-afbd-f283c68dd149/images/screenshot.png) background-size: 20%, 40%, 50%, 20% background-position: 20% 45%, 70% 45%, 85% 90%, 20% 95% ## MRI analyses are usually run in specialized software ??? - run in specialized software - but results and dissemination is usually run in stats software - switching between different software creates workflows that are hard to reproduce and keep track of --- background-image: url(https://visceralmind.files.wordpress.com/2017/04/voxel-brain.jpg?w=1024) background-size: contain ??? - the images are 3d matrices of 1mm cubic voxels, usually around 100 thousand voxels per brain - MRI analyses run large numbers of comparisons just within a single subjects' brain, and issues with multiple comparisons need to be dealt with --- background-image: url(https://www.researchgate.net/profile/Arno_Klein2/publication/233889622/figure/fig2/AS:271987822034957@1441858358467/Regions-in-the-DKT-cortical-labeling-protocol-Cortical-regions-of-interest-included-in.png) background-size: contain ??? - To reduce this problem, the brain is often reduced to a smaller set of functionally or structurally meaningful parcellations - here: the DK cortical atlas on an inflated brain (blown up like a balloon) to see also inside the grooves - measurements are extracted from these regions for metrics like coritcal thickness, surface area, gyrification index etc. and used in statistical models --- class: center, dark background-image: url(img/ggseg.png), url(img/ggseg3d.png), url(img/ggsegExtra.png) background-size: 15% background-position: 41% 43%, 59% 43%, 50% 77% # ggseg-suite .pull-left[ 2d polygons / geospatial ] -- .pull-left[ 3d mesh / tri-surface ] -- <br><br><br><br><br><br><br><br><br> <br><br><br><br><br><br><br><br><br> atlas creation / installation --- class: middle, center, dark background-image: url(img/ggseg.png) background-size: 18% background-position: 50% 10% # ## Plotting 2d representations as polygons --- class: middle .pull-left[ ```r library(ggseg, quietly = TRUE) plot(dk, show.legend = FALSE) ``` ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-2-1.png" width="100%" /> ] --- class: middle ```r dk ``` ``` ## # dk cortical brain atlas ## regions: 35 ## hemispheres: left, right ## side views: lateral, medial ## palette: yes ## use: ggplot() + geom_brain() ## ---- ## hemi side region label roi ## <chr> <chr> <chr> <chr> <chr> ## 1 left lateral bankssts lh_bankssts 0002 ## 2 left lateral caudal middle frontal lh_caudalmiddlefrontal 0004 ## 3 left lateral fusiform lh_fusiform 0008 ## 4 left lateral inferior parietal lh_inferiorparietal 0009 ## 5 left lateral inferior temporal lh_inferiortemporal 0010 ## 6 left lateral lateral occipital lh_lateraloccipital 0012 ## 7 left lateral lateral orbitofrontal lh_lateralorbitofrontal 0013 ## 8 left lateral middle temporal lh_middletemporal 0016 ## 9 left lateral pars opercularis lh_parsopercularis 0019 ## 10 left lateral pars orbitalis lh_parsorbitalis 0020 ## # … with 76 more rows ``` --- ## New syntax .pull-left[ **Old syntax** ```r ggseg(atlas = dk, show.legend = FALSE) ``` **New syntax** ```r ggplot() + geom_brain(atlas = dk, show.legend = FALSE) ``` ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-5-1.png" width="100%" /> ] --- ## New syntax .pull-left[ **New position options** ```r ggplot() + geom_brain( atlas = dk, position = position_brain(hemi ~ side), show.legend = FALSE ) ``` ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-6-1.png" width="100%" /> ] --- ## New syntax .pull-left[ **New position options** ```r ggplot() + geom_brain( atlas = dk, position = position_brain(side ~ hemi), show.legend = FALSE ) ``` ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-7-1.png" width="100%" /> ] --- ## New syntax .pull-left[ **New position options** ```r ggplot() + geom_brain( atlas = dk, position = position_brain(side + hemi ~ .), show.legend = FALSE ) ``` ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-8-1.png" width="100%" /> ] --- ## Using your own data .pull-left[ ```r library(dplyr) someData <- tibble( region = rep(c("transverse temporal", "insula", "precentral", "superior parietal"),2), p = sample(seq(0,.5,.001), 8), Group = c(rep("G1",4), rep("G2",4))) someData ``` ] .pull-right[ ``` ## # A tibble: 8 x 3 ## region p Group ## <chr> <dbl> <chr> ## 1 transverse temporal 0.24 G1 ## 2 insula 0.34 G1 ## 3 precentral 0.41 G1 ## 4 superior parietal 0.081 G1 ## 5 transverse temporal 0.062 G2 ## 6 insula 0.194 G2 ## 7 precentral 0.033 G2 ## 8 superior parietal 0.045 G2 ``` ] --- ## Using your own data .pull-left[ ```r ggplot(data = someData) + geom_brain( atlas = dk, position = position_brain(side ~ hemi), colour = "black", * mapping = aes(fill = p)) ``` ] .pull-right[ ``` ## merging atlas and data by 'region' ``` <img src="index_files/figure-html/unnamed-chunk-10-1.png" width="100%" /> ] --- .pull-left[ ## Faceting groups ```r someData %>% * group_by(Group) %>% ggplot() + geom_brain( atlas = dk, position = position_brain(side ~ hemi), colour = "black", mapping = aes(fill = p) ) + * facet_wrap(~Group, * nrow = 2) ``` ] .pull-right[ ``` ## merging atlas and data by 'region' ``` <img src="index_files/figure-html/unnamed-chunk-11-1.png" width="100%" /> ] --- .pull-left[ ## Adapting the look ```r someData %>% group_by(Group) %>% ggplot() + geom_brain( atlas = dk, position = position_brain(side ~ hemi), colour = "black", mapping = aes(fill = p) ) + facet_wrap(~Group, nrow = 2) + theme(axis.text = element_blank(), axis.line = element_blank(), axis.ticks = element_blank(), axis.title = element_blank(), panel.background = element_blank() ) + scale_fill_viridis_c(na.value = "grey62") ``` ] .pull-right[ ``` ## merging atlas and data by 'region' ``` <img src="index_files/figure-html/unnamed-chunk-12-1.png" width="100%" /> ] --- class: middle .left-column[ ## Subcortical atlases ```r plot(aseg) ``` ] .right-column[ <img src="index_files/figure-html/unnamed-chunk-13-1.png" width="100%" /> ] --- class: middle, center, dark background-image: url(img/ggseg3d.png) background-size: 18% background-position: 50% 10% # ## Plotting 3d triangular meshes --- class: middle .pull-left[ ## Powered by plotly ### Fully interactive ```r library(ggseg3d) ggseg3d(atlas = dk_3d) ``` ] .pull-right[
] --- class: middle .pull-left[ ## subcortical structure ### with glass brain for reference ```r ggseg3d(atlas = aseg_3d) %>% add_glassbrain(hemisphere = "left") %>% remove_axes() ``` ] .pull-right[ <img src="aseg_3d.png" width="100%" /> ] --- class: middle, center, dark background-image: url(img/ggsegExtra.png) background-size: 18% background-position: 50% 10% # ## Creating and instaling atlases --- ```r library(ggsegExtra) ggseg_atlas_repos() ``` <table class="table" style="margin-left: auto; margin-right: auto;"> <thead> <tr> <th style="text-align:left;"> repo </th> <th style="text-align:left;"> ggseg </th> <th style="text-align:left;"> ggseg3d </th> <th style="text-align:left;"> source </th> <th style="text-align:left;"> comment </th> <th style="text-align:left;"> package </th> </tr> </thead> <tbody> <tr> <td style="text-align:left;"> LCBC-UiO/ggsegYeo2011 </td> <td style="text-align:left;"> TRUE </td> <td style="text-align:left;"> TRUE </td> <td style="text-align:left;"> github </td> <td style="text-align:left;"> both 17 and 7 Network data </td> <td style="text-align:left;"> ggsegYeo2011 </td> </tr> <tr> <td style="text-align:left;"> LCBC-UiO/ggsegDesterieux </td> <td style="text-align:left;"> FALSE </td> <td style="text-align:left;"> TRUE </td> <td style="text-align:left;"> github </td> <td style="text-align:left;"> the 2009 atlas </td> <td style="text-align:left;"> ggsegDesterieux </td> </tr> <tr> <td style="text-align:left;"> LCBC-UiO/ggsegChen </td> <td style="text-align:left;"> FALSE </td> <td style="text-align:left;"> TRUE </td> <td style="text-align:left;"> github </td> <td style="text-align:left;"> both thickness and area maps </td> <td style="text-align:left;"> ggsegChen </td> </tr> <tr> <td style="text-align:left;"> LCBC-UiO/ggsegSchaefer </td> <td style="text-align:left;"> FALSE </td> <td style="text-align:left;"> TRUE </td> <td style="text-align:left;"> github </td> <td style="text-align:left;"> both 17 and 7 networks </td> <td style="text-align:left;"> ggsegSchaefer </td> </tr> <tr> <td style="text-align:left;"> LCBC-UiO/ggsegGlasser </td> <td style="text-align:left;"> TRUE </td> <td style="text-align:left;"> TRUE </td> <td style="text-align:left;"> github </td> <td style="text-align:left;"> full atlas </td> <td style="text-align:left;"> ggsegGlasser </td> </tr> <tr> <td style="text-align:left;"> LCBC-UiO/ggsegJHU </td> <td style="text-align:left;"> TRUE </td> <td style="text-align:left;"> TRUE </td> <td style="text-align:left;"> github </td> <td style="text-align:left;"> white tract atlas </td> <td style="text-align:left;"> ggsegJHU </td> </tr> <tr> <td style="text-align:left;"> LCBC-UiO/ggsegTracula </td> <td style="text-align:left;"> TRUE </td> <td style="text-align:left;"> TRUE </td> <td style="text-align:left;"> github </td> <td style="text-align:left;"> white tract atlas </td> <td style="text-align:left;"> ggsegTracula </td> </tr> <tr> <td style="text-align:left;"> LCBC-UiO/ggsegICBM </td> <td style="text-align:left;"> FALSE </td> <td style="text-align:left;"> TRUE </td> <td style="text-align:left;"> github </td> <td style="text-align:left;"> white tract atlas </td> <td style="text-align:left;"> ggsegICBM </td> </tr> <tr> <td style="text-align:left;"> LCBC-UiO/ggsegHO </td> <td style="text-align:left;"> TRUE </td> <td style="text-align:left;"> FALSE </td> <td style="text-align:left;"> github </td> <td style="text-align:left;"> Harvard-Oxford cortical (FSL) </td> <td style="text-align:left;"> ggsegHO </td> </tr> <tr> <td style="text-align:left;"> LCBC-UiO/ggsegDefaultExtra </td> <td style="text-align:left;"> TRUE </td> <td style="text-align:left;"> FALSE </td> <td style="text-align:left;"> github </td> <td style="text-align:left;"> extra 2d view for dk, p/a division of aseg hippocampus </td> <td style="text-align:left;"> ggsegDefaultExtra </td> </tr> <tr> <td style="text-align:left;"> LCBC-UiO/ggsegDKT </td> <td style="text-align:left;"> TRUE </td> <td style="text-align:left;"> TRUE </td> <td style="text-align:left;"> github </td> <td style="text-align:left;"> Desikan-Killiany-Tourville cortical atlas </td> <td style="text-align:left;"> ggsegDKT </td> </tr> </tbody> </table> --- .pull-left[ ```r install_ggseg_atlas("LCBC-UiO/ggsegYeo2011", "github") ``` <!-- ```{r, echo=FALSE} --> <!-- library(ggsegYeo2011) --> <!-- yeo7$type = "cortical" --> <!-- yeo17$type = "cortical" --> <!-- ``` --> ```r library(ggsegYeo2011) plot(yeo7) plot(yeo17) ``` ] .pull-right[ <img src="index_files/figure-html/yeo.out-1.png" width="100%" /><img src="index_files/figure-html/yeo.out-2.png" width="100%" /> ] --- # Creating new atlases .pull-left[ ## New cortical atlases ```r # Make brain atlases into # 3d plotly mesh atlas make_aparc_2_3datlas() # Turn plotly mesh atlas # into 2d polygon atlas make_ggseg3d_2_ggseg() ``` ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-20-1.png" width="100%" /> ] ??? Here is an example of the HCP Glasser atlas which was made with the automatic process we have made. It works really well, but we also know that there are 2 regions that are not in the data for the 2d-plot, because they are so small the pipeline cannot see when making the polygons. So it's not 100%. We are looking into if we can implement some inflation of very small, but true, polygons so that they will still appear, but its tricky. --- # Creating new atlases .pull-left[ ## New subcortical atlases ```r # Make brain atlas image into # 3d plotly mesh atlas make_volumetric_2_3datlas() # Make brain atlas image into # into 2d polygon atlas make_volumetric_ggseg() ``` ] .pull-right[ <img src="aseg_new.png" width="100%" /> ] ??? Here is an example of a pipeline to make the aseg subcortical atlas with the functions. This was made entirely through R, but with function calls from within R to FreeSurfer and ImageMagick. --- class:dark, middle, center # Check out the online package docs Here you can find tutorials and more in-depth descriptions of what you can accomplish with the packages. ## [ggseg](https://lcbc-uio.github.io/ggseg/index.html) ## [ggseg3d](https://lcbc-uio.github.io/ggseg3d/index.html) ## [ggsegExtra](https://lcbc-uio.github.io/ggsegExtra/index.html) --- class: middle, center, dark # Things to improve --- .pull-left[ ## Grouping twice ```r someData %>% * group_by(Group) %>% ggplot() + geom_brain( atlas = dk, position = position_brain(side ~ hemi), mapping = aes(fill = p) ) + * facet_wrap(~Group, * nrow = 2) ``` ] .pull-right[ ``` ## merging atlas and data by 'region' ``` <img src="index_files/figure-html/sf3-out-1.png" width="100%" /> ] --- background-image: url(img/ggseg3d.png) background-size: 10% background-position: 7% 97% .pull-left[ ```r ggseg3d(atlas = dk) ``` ] .pull-right[ <img src="dkt3d.png" width="100%" /> ] ??? Currently, ggseg3d plots the segments in loops, which makes a lot of customization of the plots tedious, and also quite slow in plotting. Ideally, we'd love to understand how to index the vertices to the mesh-faces directly, and to plot one large mesh grid, with specifications of colours in a vector. --- class: dark, bottom, center # Things to check out -- ## [Neuroconductor](https://neuroconductor.org/) -- ## [gganatogram](https://github.com/jespermaag/gganatogram) --- ## gganatogram .pull-left[ <img src="index_files/figure-html/unnamed-chunk-23-1.png" width="100%" /> ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-24-1.png" width="100%" /> ] --- class: center, dark background-image: url(img/ggseg.png), url(img/ggseg3d.png), url(img/ggsegExtra.png) background-size: 15% background-position: 41% 43%, 59% 43%, 50% 77% # ggseg-suite .pull-left[ 2d polygons / geospatial ] .pull-left[ 3d mesh / tri-surface ] <br><br><br><br><br><br><br><br><br> <br><br><br><br><br><br><br><br><br> atlas creation / installation --- class: title-slide, middle, right # Thanks to our lab # for funding to develop # these tools [oslobrains.no](https://www.oslobrains.no/) --- class: center, inverse background-image: url(https://www.sv.uio.no/psi/english/people/aca/didacvp/didacvp.jpg), url(https://www.sv.uio.no/psi/personer/vit/athanasm/athanasia.mowinckel.2.small.png) background-position: 41% 70%, 59% 70% background-size: 15% # Thank you for listening ## on behalf of Didac Vidal-Piñeiro and myself --- class: middle, center, dark # Backup live-coding bits --- ```r ggseg3d(someData, atlas = dk_3d, surface = "white", colour = "p", hoverinfo = "name") ```