Skip to content

Electrode Layouts

EegFun.jl includes a comprehensive collection of electrode layout files that define the spatial positions of EEG channels for various montage systems. These layouts are essential for topographic plotting, channel interpolation, and spatial analyses.

Overview

Layout files are stored in CSV format with three required columns:

  • label: Channel name (Symbol)

  • inc: Incidence angle in degrees (vertical angle from vertex)

  • azi: Azimuth angle in degrees (horizontal angle)

The polar coordinates (inc, azi) serve as the Source of Truth for electrode positions. Cartesian coordinates (2D and 3D) are computed on-demand from these polar coordinates.

Sources

The electrode layout files included in EegFun.jl were obtained from the following sources:

Usage

julia
# Load a layout file
layout = EegFun.read_layout("./resources/layouts/biosemi/biosemi72.csv")

# Convert to 2D Cartesian coordinates (preserving radial distances)
EegFun.polar_to_cartesian_xy!(layout)

# Calculate neighbors 
EegFun.get_neighbours_xy!(layout, 0.3)

# Plot the layout with neighbours; hover over electrodes to see neighbours
EegFun.plot_layout_2d(layout; neighbours=true)

EegFun.get_neighbours_xyz!(layout, 0.5)
EegFun.plot_layout_3d(layout; neighbours=true)

Available Layouts

BioSemi

Standard BioSemi ActiveTwo electrode caps and extended montages:

biosemi16 (16 channels) - Standard 16-channel montagebiosemi16 layout
biosemi32 (32 channels) - Standard 32-channel montagebiosemi32 layout
biosemi64 (64 channels) - Standard 64-channel montagebiosemi64 layout
biosemi70 (70 channels) - 64 + 6 external channelsbiosemi70 layout
biosemi72 (72 channels) - 64 + 8 external channelsbiosemi72 layout
biosemi128 (128 channels) - Standard 128-channel montagebiosemi128 layout
biosemi160 (160 channels) - Extended high-density montagebiosemi160 layout
biosemi256 (256 channels) - Ultra high-density montagebiosemi256 layout

BrainProducts actiCap

BrainProducts electrode caps organized by product line:

Standard BrainCap

BC-22 (22 channels) - 22-channel clinical montageBC-22 layout
BC-32 (32 channels) - Standard 32-channel montageBC-32 layout
BC-64 (64 channels) - Standard 64-channel montageBC-64 layout
BC-96 (96 channels) - High-density 96-channel montageBC-96 layout
BC-128 (128 channels) - High-density 128-channel montageBC-128 layout
BC-256 (256 channels) - Ultra high-density montageBC-256 layout

BrainCap MR (MRI-compatible)

BC-MR-32 (32 channels)BC-MR-32 layout
BC-MR-64 (64 channels)BC-MR-64 layout
BC-MR-96 (96 channels)BC-MR-96 layout
BC-MR-128 (128 channels)BC-MR-128 layout

BrainCap MR3 (3T MRI-compatible)

BC-MR3-32 (32 channels)BC-MR3-32 layout
BC-MR3-64 (64 channels)BC-MR3-64 layout
BC-MR3-96 (96 channels)BC-MR3-96 layout
BC-MR3-128 (128 channels)BC-MR3-128 layout

BrainCap MEG (MEG-compatible)

BC-MEG-32 (32 channels)BC-MEG-32 layout
BC-MEG-64 (64 channels)BC-MEG-64 layout
BC-MEG-128 (128 channels)BC-MEG-128 layout

BrainCap TMS (TMS-compatible)

BC-TMS-32 (32 channels)BC-TMS-32 layout
BC-TMS-64 (64 channels)BC-TMS-64 layout
BC-TMS-96 (96 channels)BC-TMS-96 layout
BC-TMS-128 (128 channels)BC-TMS-128 layout

BrainCap Sleep

BC-MRS-15 (15 channels) - MR sleep - AASM standardBC-MRS-15 layout
BC-MRS-32 (32 channels) - MR sleep montageBC-MRS-32 layout
BC-MRS-64 (64 channels) - MR sleep montageBC-MRS-64 layout
BC-MRS3-15 (15 channels) - MR3 sleep - AASM standardBC-MRS3-15 layout
BC-MRS3-32 (32 channels) - MR3 sleep montageBC-MRS3-32 layout
BC-MRS3-64 (64 channels) - MR3 sleep montageBC-MRS3-64 layout
BC-SL-32 (32 channels) - BrainAmp sleepBC-SL-32 layout
BC-SL-64 (64 channels) - BrainAmp sleepBC-SL-64 layout
BC-SL-128 (128 channels) - BrainAmp sleepBC-SL-128 layout
BCA-SL-32 (32 channels) - actiCHamp sleepBCA-SL-32 layout
BCA-SL-64 (64 channels) - actiCHamp sleepBCA-SL-64 layout
BCA-SL-128 (128 channels) - actiCHamp sleepBCA-SL-128 layout

LiveCap

LC-32 (32 channels) - LiveAmp 32-channelLC-32 layout
LC-64 (64 channels) - LiveAmp 64-channelLC-64 layout
LC-SL-32_Ch1-24 (32 channels) - LiveCap sleep (24 + 8)LC-SL-32_Ch1-24 layout

R-Net

RNP-BA-32 (32 channels) - R-Net for BrainAmpRNP-BA-32 layout
RNP-BA-64 (64 channels) - R-Net for BrainAmpRNP-BA-64 layout
RNP-BA-96 (96 channels) - R-Net for BrainAmpRNP-BA-96 layout
RNP-BA-128 (128 channels) - R-Net for BrainAmpRNP-BA-128 layout
RNP-LA-32 (32 channels) - R-Net for LiveAmpRNP-LA-32 layout
RNP-LA-64 (64 channels) - R-Net for LiveAmpRNP-LA-64 layout
RNP-AC-32 (32 channels) - R-Net for actiCHamp PlusRNP-AC-32 layout
RNP-AC-64 (64 channels) - R-Net for actiCHamp Plus (with Iz)RNP-AC-64 layout
RNP-AC-96 (96 channels) - R-Net for actiCHamp Plus (with Iz)RNP-AC-96 layout
RNP-AC-128 (128 channels) - R-Net for actiCHamp Plus (with Iz)RNP-AC-128 layout
RNP-BA-MR3-32 (32 channels) - R-Net MR3RNP-BA-MR3-32 layout
RNP-BA-MR3-64 (64 channels) - R-Net MR3RNP-BA-MR3-64 layout
RNP-BA-MR3-96 (96 channels) - R-Net MR3RNP-BA-MR3-96 layout
RNP-BA-MR3-128 (128 channels) - R-Net MR3RNP-BA-MR3-128 layout
RNP-AP-32 (32 channels) - R-Net for actiCHamp PlusRNP-AP-32 layout
RNP-AP-64 (64 channels) - R-Net for actiCHamp Plus (with FCz)RNP-AP-64 layout
RNP-AP-96 (96 channels) - R-Net for actiCHamp Plus (with FCz)RNP-AP-96 layout
RNP-AP-128 (128 channels) - R-Net for actiCHamp Plus (with FCz)RNP-AP-128 layout
RNP-AP-160 (160 channels) - R-Net for actiCHamp Plus (with FCz, Iz)RNP-AP-160 layout

actiCAP (Standard)

AC-21 (21 channels)AC-21 layout
AC-32 (32 channels)AC-32 layout
AC-64 (64 channels)AC-64 layout
AC-96 (96 channels)AC-96 layout
AC-128 (128 channels)AC-128 layout

actiCAP Xpress Twist

Twist-32 (32 channels) - for BrainAmp (with REF)Twist-32 REF layout
Twist-32 (32 channels) - for LiveAmp (with REF)Twist-32 REF layout
Twist-32 (32 channels) - for actiCHamp (no REF)Twist-32 NO REF layout

actiCHamp Electrode Cap (CAP)

AP-32 (32 channels) - actiCHamp electrode capAP-32 layout
AP-64 (64 channels) - actiCHamp electrode capAP-64 layout
AP-96 (96 channels) - actiCHamp electrode capAP-96 layout
AP-128 (128 channels) - actiCHamp electrode capAP-128 layout
AP-160 (160 channels) - actiCHamp electrode capAP-160 layout

actiCAP UOL (CMA)

CMA-21 (21 channels) - BrainAmp (with REF)CMA-21 REF layout
CMA-21 (21 channels) - actiCHamp (no REF)CMA-21 NO REF layout
CMA-21 (21 channels) - actiCHamp Plus (no REF)CMA-21 NO REF layout
CMA-32 (32 channels) - BrainAmp (with REF)CMA-32 REF layout
CMA-32 (32 channels) - actiCHamp (no REF)CMA-32 NO REF layout
CMA-32 (32 channels) - actiCHamp Plus (no REF)CMA-32 NO REF layout
CMA-64 (64 channels) - BrainAmp (with REF)CMA-64 REF layout
CMA-64 (64 channels) - actiCHamp (no REF)CMA-64 NO REF layout
CMA-64 (64 channels) - actiCHamp Plus (no REF)CMA-64 NO REF layout
CMA-96 (96 channels) - BrainAmp (with REF)CMA-96 REF layout
CMA-96 (96 channels) - actiCHamp (no REF)CMA-96 NO REF layout
CMA-96 (96 channels) - actiCHamp Plus (no REF)CMA-96 NO REF layout
CMA-128 (128 channels) - BrainAmp (with REF)CMA-128 REF layout
CMA-128 (128 channels) - actiCHamp (no REF)CMA-128 NO REF layout
CMA-128 (128 channels) - actiCHamp Plus (no REF)CMA-128 NO REF layout
CMA-160 (160 channels) - BrainAmp (with REF)CMA-160 REF layout
CMA-160 (160 channels) - actiCHamp (no REF)CMA-160 NO REF layout
CMA-160 (160 channels) - actiCHamp Plus (no REF)CMA-160 NO REF layout

actiCAP Slim (AS)

AS-32 (32 channels) - with REFAS-32 REF layout
AS-32 (32 channels) - no REFAS-32 NO REF layout
AS-64 (64 channels) - with REFAS-64 REF layout
AS-64 (64 channels) - no REFAS-64 NO REF layout
AS-96 (96 channels) - with REFAS-96 REF layout
AS-96 (96 channels) - no REFAS-96 NO REF layout
AS-128 (128 channels) - with REFAS-128 REF layout
AS-128 (128 channels) - no REFAS-128 NO REF layout
AS-160 (160 channels) - with REFAS-160 REF layout
AS-160 (160 channels) - no REFAS-160 NO REF layout

actiCap for LiveAmp

CLA-32 (32 channels) - actiCap for LiveAmpCLA-32 layout

actiCap Slim (ASP) — for BrainAmpDC

CACS-32 (32 channels) - for BrainAmpDC (with REF)CACS-32 REF layout
CACS-64 (64 channels) - for BrainAmpDC (with REF)CACS-64 REF layout
CACS-96 (96 channels) - for BrainAmpDC (with REF)CACS-96 REF layout
CACS-128 (128 channels) - for BrainAmpDC (with REF)CACS-128 REF layout

actiCap Slim (ASP) — for LiveAmp

CACS-32 (32 channels) - for LiveAmp (with REF)CACS-32 REF layout
CACS-64 (64 channels) - for LiveAmp (with REF)CACS-64 REF layout

actiCap Slim (ASP) — for actiCHamp Plus

CACS-32 (32 channels) - for actiCHamp Plus (no REF)CACS-32 NO REF layout
CACS-64 (64 channels) - for actiCHamp Plus (no REF)CACS-64 NO REF layout
CACS-96 (96 channels) - for actiCHamp Plus (no REF)CACS-96 NO REF layout
CACS-128 (128 channels) - for actiCHamp Plus (no REF)CACS-128 NO REF layout
CACS-160 (160 channels) - for actiCHamp Plus (no REF)CACS-160 NO REF layout

actiCap Snap — for BrainAmpDC

CACS-21 (21 channels) - for BrainAmpDC (with REF)CACS-21 REF layout
CACS-32 (32 channels) - snap for BrainAmpDC (with REF)CACS-32 REF layout
CACS-64 (64 channels) - snap for BrainAmpDC (with REF)CACS-64 REF layout
CACS-96 (96 channels) - snap for BrainAmpDC (with REF)CACS-96 REF layout
CACS-128 (128 channels) - snap for BrainAmpDC (with REF)CACS-128 REF layout

actiCap Snap — for LiveAmp

CACS-21 (21 channels) - snap for LiveAmp (with REF)CACS-21 REF layout
CACS-32 (32 channels) - snap for LiveAmp (with REF)CACS-32 REF layout
CACS-64 (64 channels) - snap for LiveAmp (with REF)CACS-64 REF layout

actiCap Snap — for actiCHamp Plus

CACS-21 (21 channels) - snap for actiCHamp Plus (no REF)CACS-21 NO REF layout
CACS-32 (32 channels) - snap for actiCHamp Plus (no REF)CACS-32 NO REF layout
CACS-64 (64 channels) - snap for actiCHamp Plus (no REF)CACS-64 NO REF layout
CACS-96 (96 channels) - snap for actiCHamp Plus (no REF)CACS-96 NO REF layout
CACS-128 (128 channels) - snap for actiCHamp Plus (no REF)CACS-128 NO REF layout
CACS-160 (160 channels) - snap for actiCHamp Plus (no REF)CACS-160 NO REF layout

actiCap Snap for LiveAmp (CLACS)

CLACS-32 (32 channels) - actiCap snap for LiveAmpCLACS-32 layout

EasyCap

EasyCap montage configurations (M-series):

easycapM1easycapM1 layout
easycapM3easycapM3 layout
easycapM7easycapM7 layout
easycapM10easycapM10 layout
easycapM11easycapM11 layout
easycapM14easycapM14 layout
easycapM15easycapM15 layout
easycapM16easycapM16 layout
easycapM17easycapM17 layout
easycapM20easycapM20 layout
easycapM22easycapM22 layout
easycapM23easycapM23 layout
easycapM24easycapM24 layout
easycapM25easycapM25 layout
easycapM64easycapM64 layout

Coordinate Systems

Polar Coordinates (Source of Truth)

  • Incidence (inc): Vertical angle in degrees from the vertex (Cz = 0°)

    • 0° = vertex (top of head)

    • 90° = equator (ear level)

    • Values > 90° indicate positions below the equator (e.g., neck electrodes)

  • Azimuth (azi): Horizontal angle in degrees

    • 0° = right hemisphere

    • ±90° = midline (front/back)

    • ±180° = left hemisphere

Cartesian Coordinates

Cartesian coordinates are computed on-demand from polar coordinates:

  • 2D (x2, y2): Topographic projection for 2D plotting

    • By default, preserve_radial_distance=true maintains anatomical accuracy

    • Electrodes with inc > 90° appear outside the unit circle

  • 3D (x3, y3, z3): Spherical projection for 3D visualization

    • Normalized to unit sphere

Layout management and manipulation:

EegFun.read_layout Function
julia
read_layout(file::String)

Reads a layout file in CSV format and returns a DataFrame containing the layout information.

Arguments

  • file::String: The path to the CSV file containing the layout data.

Returns

  • DataFrame: A DataFrame containing the layout data, with columns for electrode labels, incidence angles, azimuth angles, and calculated Cartesian coordinates (if applicable).

Throws

  • EegFunError: If the file does not exist or cannot be accessed.
source
EegFun.validate_layout Function
julia
validate_layout(layout::Layout) -> Layout

Validate that a layout contains all required columns and data.

This function checks that the layout DataFrame contains the minimum required columns for EEG layout operations.

Arguments

  • layout::Layout: The layout object to validate

Returns

  • Layout: The validated layout object

Throws

  • ArgumentError: If required columns are missing

Required Columns

  • :label: Electrode labels (Symbol type)

  • :inc: Incidence angles in degrees

  • :azi: Azimuth angles in degrees

Examples

julia
layout = read_layout("biosemi64.csv")
validated_layout = validate_layout(layout)
source
EegFun.polar_to_cartesian_xy! Function
julia
polar_to_cartesian_xy!(layout::Layout; normalization_radius::Float64=1.0, preserve_radial_distance::Bool=true)

Converts polar coordinates (incidence and azimuth angles) from a layout into Cartesian coordinates (x, y).

Arguments

  • layout::Layout: A Layout containing the layout information with columns for incidence angles (:inc) and azimuth angles (:azi).

  • normalization_radius::Real: Maximum radius for electrode positions (default: 1.0). Only used when preserve_radial_distance=false.

  • preserve_radial_distance::Bool: If true, preserves true radial distances from polar coordinates, allowing electrodes with inc>90° to appear outside the unit circle (default: true). When false, normalizes all electrodes to fit within normalization_radius.

Throws

  • ArgumentError: If required :inc and :azi columns are missing or contain non-numeric values.

Modifies

  • The input layout is modified in place to include new columns x2 and y2, which represent the Cartesian coordinates calculated from the polar coordinates.

  • Clears any existing neighbour information since coordinates have changed.

Returns

  • Nothing. The function modifies the layout directly.

Notes

  • When preserve_radial_distance=true, electrodes imported from EEGLAB with inc>90° (e.g., eye electrodes beyond the scalp) will appear outside the standard head circle, matching EEGLAB's topoplot rendering.
source
EegFun.polar_to_cartesian_xyz! Function
julia
polar_to_cartesian_xyz!(layout::Layout)

Converts polar coordinates (incidence and azimuth angles) from a layout into Cartesian coordinates (x, y, z).

Arguments

  • layout::Layout: A Layout containing the layout information with columns for incidence angles (:inc) and azimuth angles (:azi).

Throws

  • ArgumentError: If required :inc and :azi columns are missing or contain non-numeric values.

Modifies

  • The input layout is modified in place to include new columns x3, y3, and z3, which represent the Cartesian coordinates calculated from the polar coordinates.

  • Clears any existing neighbour information since coordinates have changed.

Returns

  • Nothing. The function modifies the layout directly.
source
EegFun.get_neighbours_xy! Function
julia
get_neighbours_xy!(layout::Layout, distance_criterion::Real)

Get neighbors with automatic computation if needed (mutating version).

This function automatically calculates 2D neighbors if they don't exist or if the distance criterion has changed. It caches the results for efficiency.

Arguments

  • layout::Layout: The layout object

  • distance_criterion::Real: The distance criterion for neighbors in normalized coordinate units (e.g., 0.3–0.5; where 1.0 = the scalp equator at 90° incidence). Think of this as a fraction of the head radius: a value of 0.4 means “neighbours within 40% of the head radius.”

Modifies

  • layout: Updates neighbor information and criterion

Examples

julia
get_neighbours_xy!(layout, 0.4)
source
EegFun.get_neighbours_xyz! Function
julia
get_neighbours_xyz!(layout::Layout, distance_criterion::Real)

Get neighbors with automatic computation if needed (mutating version).

This function automatically calculates 3D neighbors if they don't exist or if the distance criterion has changed. It caches the results for efficiency.

Arguments

  • layout::Layout: The layout object

  • distance_criterion::Real: The distance criterion for neighbors in normalized coordinate units (e.g., 0.3–0.5; where 1.0 = the scalp equator at 90° incidence). Think of this as a fraction of the head radius: a value of 0.4 means “neighbours within 40% of the head radius.”

source
EegFun.rename_channel! Function
julia
rename_channel!(dat::EegData, rename_dict::Dict{Symbol, Symbol})

Rename channels in EEG data using a dictionary mapping old names to new names. Modifies the data in place by updating both the data columns and the layout.

Arguments

  • dat::EegData: The EEG data object to modify

  • rename_dict::Dict{Symbol, Symbol}: Dictionary mapping old channel names to new names

Returns

  • nothing (modifies the data in place)

Examples

julia
# Rename Fp1 to Fpz and Fp2 to Fpz
rename_dict = Dict(:Fp1 => :Fpz, :Fp2 => :Fpz)
rename_channel!(dat, rename_dict)

# Rename a single channel
rename_channel!(dat, Dict(:Cz => :Cz_new))

Notes

  • Only channels that exist in the data will be renamed

  • If multiple channels would be renamed to the same name, an error is thrown to prevent duplicates

  • Updates both the data columns and the layout labels

  • Clears any cached neighbour information in the layout since channel names have changed

  • Properly handles swaps (e.g., Dict(:A => :B, :B => :A) correctly exchanges the channels)

source
julia
rename_channel!(layout::Layout, rename_dict::Dict{Symbol, Symbol})

Rename channels in a Layout object using a dictionary mapping old names to new names. Modifies the layout in place.

Arguments

  • layout::Layout: The layout object to modify

  • rename_dict::Dict{Symbol, Symbol}: Dictionary mapping old channel names to new names

Returns

  • nothing (modifies the layout in place)

Examples

julia
# Rename Fp1 to Fpz and Fp2 to Fpz
rename_dict = Dict(:Fp1 => :Fpz, :Fp2 => :Fpz)
rename_channel!(layout, rename_dict)

# Rename a single channel
rename_channel!(layout, Dict(:Cz => :Cz_new))

Throws

  • EegFunError: If multiple channels would be renamed to the same name (duplicate prevention)

Notes

  • Only channels that exist in the layout will be renamed

  • Clears any cached neighbour information since channel names have changed

source

Layout visualization:

EegFun.plot_layout_2d Function
julia
plot_layout_2d(layout::Layout; neighbours::Bool=false, correlation_matrix::Union{DataFrame, Nothing}=nothing, display_plot::Bool=true, kwargs...)

Create a new figure and plot a 2D EEG electrode layout.

Arguments

  • layout: Layout containing electrode positions

  • neighbours: Boolean to show interactive neighbour connections (default: false). Ignored if correlation_matrix is provided.

  • correlation_matrix: Optional DataFrame from correlation_matrix() to show correlation values on hover (default: nothing). When provided, neighbours is ignored.

  • display_plot: Boolean to display the plot (default: true)

Keyword Arguments

All keyword arguments below have sensible defaults. You can override any by passing the corresponding keyword argument.

  • head_linewidth::Int64=2: Line width of the head shape outline.

  • head_radius::Int64=1: Radius of the head shape (normalized units).

  • head_color::Symbol=black: Color of the head shape outline.

Keyword Arguments

All keyword arguments below have sensible defaults. You can override any by passing the corresponding keyword argument.

  • point_plot::Bool=true: Whether to plot electrode points.

  • point_markersize::Int64=12: Size of electrode point markers.

  • point_color::Symbol=black: Color of electrode points.

  • point_marker::Symbol=circle: Marker style for electrode points.

Keyword Arguments

All keyword arguments below have sensible defaults. You can override any by passing the corresponding keyword argument.

  • label_plot::Bool=true: Whether to plot electrode labels.

  • label_fontsize::Int64=20: Font size for electrode labels.

  • label_xoffset::Int64=0: X-axis offset for electrode labels.

  • label_zoffset::Int64=0: Z-axis offset for electrode labels (3D only).

  • label_yoffset::Int64=0: Y-axis offset for electrode labels.

  • label_color::Symbol=black: Color of electrode labels.

Returns

  • The figure and axis objects

Example

julia
layout = read_layout("./layouts/biosemi64.csv")
polar_to_cartesian_xy!(layout)
plot_layout_2d(layout)
# With neighbour interactivity
plot_layout_2d(layout, neighbours=true)
# With correlation matrix
cm = correlation_matrix(dat)
plot_layout_2d(layout, correlation_matrix=cm)
source
EegFun.plot_layout_3d Function
julia
plot_layout_3d(layout::Layout; neighbours::Bool=false, display_plot::Bool=true, kwargs...)

Create a new figure and plot a 3D EEG electrode layout.

Arguments

  • layout: Layout containing electrode positions

  • neighbours: Boolean to show interactive neighbour connections (default: false)

  • display_plot: Boolean to display the plot (default: true)

Keyword Arguments

All keyword arguments below have sensible defaults. You can override any by passing the corresponding keyword argument.

  • head_linewidth::Int64=2: Line width of the head shape outline.

  • head_radius::Int64=1: Radius of the head shape (normalized units).

  • head_color::Symbol=black: Color of the head shape outline.

Keyword Arguments

All keyword arguments below have sensible defaults. You can override any by passing the corresponding keyword argument.

  • point_plot::Bool=true: Whether to plot electrode points.

  • point_markersize::Int64=12: Size of electrode point markers.

  • point_color::Symbol=black: Color of electrode points.

  • point_marker::Symbol=circle: Marker style for electrode points.

Keyword Arguments

All keyword arguments below have sensible defaults. You can override any by passing the corresponding keyword argument.

  • label_plot::Bool=true: Whether to plot electrode labels.

  • label_fontsize::Int64=20: Font size for electrode labels.

  • label_xoffset::Int64=0: X-axis offset for electrode labels.

  • label_zoffset::Int64=0: Z-axis offset for electrode labels (3D only).

  • label_yoffset::Int64=0: Y-axis offset for electrode labels.

  • label_color::Symbol=black: Color of electrode labels.

Returns

  • The figure and axis objects

Example

julia
layout = read_layout("./layouts/biosemi64.csv")
polar_to_cartesian_xyz!(layout)
plot_layout_3d(layout)
# With neighbour interactivity
plot_layout_3d(layout, neighbours=true)
source

See Also