Tip
๐ฆ This package is part of the Eegle.jl ecosystem for EEG data analysis and classification.
This package allows to visualize EEG vector-type distributed inverse solutions data on a standard cortex in 2D and 3D. It is entirely written in julia and is powered by Makie.jl.
The data this package can visualize is easily produced with the help of Leadfields.jl and Xloreta.
Warning
As usual in Julia, the time to first plot (TTFP) may be long, depending on the PC. From the second plot on, it will be much faster.
- ๐ฆ Installation
- ๐ฃ Description
- ๐ API
- ๐ฎ Interactions
- ๐ก Examples
- โ๏ธ About the Author
- ๐ฑ Contribute
julia version 1.10+ is required.
Execute the following command in julia's REPL:
using Pkg
Pkg.add("CortexPlot")This package allows the visualization in 2D and 3D of functional brain neuroimaging data using a color code on top of a structural cortical image. Several kind of plots are available, individually or altogether in a dashboard that allows to easily switch from one to the others. All plots can be inspected and several parameters can be changed on the fly within the dashboard. Typical visualizations of this package concern:
-
the current density square module for p voxels as computed by Xloreta.
-
test-statistics obtained by testing, voxel-by-voxel, p hypotheses on data produced by Xloreta. For instance, one can perform these tests and correct for the multiplicity of comparisons across voxels using PermutationTests.jl.
Tip
Several images can be plotted, one after the other or as an animated sequence. The different frames of the sequence typically represent time samples, for example in event-related potentials, frequencies, or experimental conditions.
The standard cortices used in this package are read from Leadfields.jl. They have been pre-computed via BrainStorm by OpenMEEG, using the โfsaverageโ adult head model (FreeSurferโs default template based on 40 normative brains). The computation of the associated leadfields is based on the Boundary Element Method (BEM).
The available cortex structural data and leadfields correspond to:
- 7509 unconstrained brain dipolar sources (p = 2503 voxels ร 3 cartesian orientations); voxel size: 4.8mm (default)
- 15006 unconstrained brain dipolar sources (p = 5002 voxels ร 3 cartesian orientations); voxel size: 3mm
The cortical data and associated leadfields can be found here.
The package exports only two functions. The main function runs a dashboard:
function cortex_dashboard(data :: Union{Vector{Real}, Matrix{Real}};
voxels :: Int = 2503,
alpha :: Real = 1.0,
title :: String = "Brain activation",
colorbar_label :: String = "Current density square module",
fontsize :: Real = 16.0,
colorscheme :: Symbol = :rain
)Argument
data: a vector holding the value to be plotted at each voxel, or a matrix where each column is such a vector (a frame for a sequence of images).
Optional Keyword Arguments
voxels: the number of voxels p forming the solution space. It can be2503(default) or5002.alpha: the transparency of the cortex. By default it is 1.0 (completely opaque).title: the title of the plot(s).colorbar_label: the label of the color bar. By default it is "current density square module".fontsize: the size of the font for the axes. Its default value (16.0) is the Makie's default value.colorscheme: The initial color scheme. The default is:rain.
The second exported function, cortex_plot, can be used instead of the dashboard when only a specific visualization mode is needed. It supports exactly the same arguments as cortex_dashboard with the addition of keyword argument mode, which sets the visualization mode. Possible values are:
:Cortex3D (default), :Cortex3D_slice, :Cortex3D_3view, :Cortex2D_8view, and :Cortex2D_3view โ for the visualization modes see Interactions.
The dashboard contains drop-box menus, text boxes, sliders and buttons. Interactions are also possible using the keyboard and the mouse.
The first drop-box menu allows the user to switch between five available display modes:
Cortex3D: the default display mode, which displays the whole cortex in 3D (Fig. 1).
Figure 1. Visualization mode "Cortex3D".
Cortex3D_slice: displays in 3D a slice of the cortex along the x, y or z axis, with any position and thickness (Fig. 2).
Figure 2. Visualization mode "Cortex3D_slice".
Cortex3D_3view: as 1., but displays also the three sections through a desired voxel. To set the voxel, either point the mouse on the cortex and hit the "V" key, or enter the voxel coordinates in the text boxes and click the "Display Views" button (Fig. 3).
Figure 3. Visualization mode "Cortex3D_3view".
Cortex2D_8view: displays eight views of the cortex in 2D (Fig. 4).
Figure 4. Visualization mode "Cortex2D_8view".
Cortex2D_3view: displays in 2D the three sections of the cortex along the x, y, and z axis, each with any position and thickness (Fig. 5).
Figure 5. Visualization mode "Cortex2D_3view".
The second drop-box menu allows to select the color scheme for the color map. Note that there are two kinds of color schemes, to be used depending on the data kind, as reported in this table (legend: cdsm = current density square module):
| Color schemes | Data kind | Example usage |
|---|---|---|
| rain, magma, bilbao, solar | non-negative | cdsm, unsigned test-statistics such as ANOVA's F |
| roma, broc, redsblues, vik | real | cdsm differences, signed test-statistics such as Pearson's r and student's t |
The third drop-box allows to switch between the Global and Local scaling mode; with Global scaling all frames are scaled to the maximum across all frames, while with Local scaling each frame is scaled to its own maximum.
The "Alpha" slider sets the opacity of the cortex.
The "Color scale" slider sets the non-linearity of the color map.
The โถ button switches between Play and Pause animation mode.
The "Display max" button displays the sections through the voxel with maximum value. It applies only to visualization modes 3 and 5.
| Key | Effect | Apply to mode |
|---|---|---|
| โ / โ | display the previous / next frame | all |
| โ / โ | increase / decrease the position of the slice | 2. |
| + / - | increase / decrease the thickness of the slice | 2. |
| V | displays the three sections through the voxel under the mouse's pointer | 3. |
2D visualization modes:
- Primary mouse button click and Drag: zoom in
- CTRL + Primary mouse button click: reset
3D visualization modes:
- Primary mouse button click and Drag: rotate
- SHIFT + Primary mouse button click: reset rotation
- Secondary mouse button click and Drag: pan
- Mouse wheel: zoom in & out
- CTRL + Primary mouse button click: reset pas and zooming
Besides CortexPlot.jl, the following example makes use of packages:
- Eegle.jl to import example EEG data and compute the common average reference
- Leadfields.jl to read a leadfield matrix
- Xloreta.jl to compute the sLORETA transformation matrix and to compute current density square module vectors from current density vectors.
- GLMakie.jl, the plotting backend.
To install these packages, run in Julia's REPL
]add Eegle, Leadfields, Xloreta, CortexPlot, GLMakieThen, run this script:
using Eegle, Leadfields, Xloreta, CortexPlot, GLMakie
# read example EEG data, sampling rate and sensor labels using Eegle.jl
# use only the first 128 time samples of X
# VERY IMPORTANT: The data must in common average reference
# function car! is exported by Eegle.jl
X, sr = readASCII(EXAMPLE_Normative_1), 128;
X = car!(X[1:sr, :]);
sensors = readSensors(EXAMPLE_Normative_1_sensors);
# computes a leadfield matrix for 5002 voxels using Leadfields.jl
voxels = 5002 # can also be 2503 for a lower voxels resolution.
K, ename, eloc, gridloc = leadfield(sensors; voxels);
# calculation of sLORETA transformation matrix T with Xloreta.jl.
# NB: in general, the alpha (regularization) value for the inverse solution should be
# carefully chosen depending on the data. Here it is set to 1 (second argument).
T = sLORETA(Float64.(K), 1);
# calculation of curent density for each time sample in EEG data X.
# J_raw is a matrix of size (voxels*3) ร n_samples in X
J_raw = T * Transpose(X)
# calculation of current density module (size : voxels ร n_times) using Xloreta.jl.
# this is the data that will be visualized, frame by frame (column by column)
J = hcat((cd2sm(Vector(c)) for c in eachcol(J_raw))...)
# This is optional, to have a title and display in full screen mode directly
GLMakie.activate!(title = "Title of my study", fullscreen = true)
# Run the dashboard to visualize the data
cortex_dashboard(J; title="Title of my plot", voxels)
# if only a specific visualization mode is desired, use instead, for example
#cortex_plot(J; voxels, mode = :cortex3D_slice)Marco Congedo, Arthur Tatlian and Esteban Padilla
Please contact the first author if you are interested in contributing.

