diff --git a/previews/PR63/.documenter-siteinfo.json b/previews/PR63/.documenter-siteinfo.json index 3e9acd9..8340209 100644 --- a/previews/PR63/.documenter-siteinfo.json +++ b/previews/PR63/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.11.1","generation_timestamp":"2024-11-16T22:20:19","documenter_version":"1.8.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.11.1","generation_timestamp":"2024-11-16T22:31:53","documenter_version":"1.8.0"}} \ No newline at end of file diff --git a/previews/PR63/eeg/8972fec8.png b/previews/PR63/eeg/8972fec8.png deleted file mode 100644 index 255ed88..0000000 Binary files a/previews/PR63/eeg/8972fec8.png and /dev/null differ diff --git a/previews/PR63/eeg/e0fb83ed.png b/previews/PR63/eeg/e0fb83ed.png new file mode 100644 index 0000000..e8094e0 Binary files /dev/null and b/previews/PR63/eeg/e0fb83ed.png differ diff --git a/previews/PR63/eeg/index.html b/previews/PR63/eeg/index.html index d7d4614..9294472 100644 --- a/previews/PR63/eeg/index.html +++ b/previews/PR63/eeg/index.html @@ -1,9 +1,9 @@ -EEG · TopoPlots.jl

EEG Topoplots

The eeg_topoplot recipe adds a bit of convenience for plotting Topoplots from EEG data, like drawing a head shape and automatically looking up default positions for known sensors. Otherwise, it supports the same attributes as topoplot.

TopoPlots.eeg_topoplotFunction
eeg_topoplot(data::Vector{<: Real}, labels::Vector{<: AbstractString})

Attributes:

  • positions::Vector{<: Point} = Makie.automatic: Can be calculated from label (channel) names. Currently, only 10/20 montage has default coordinates provided.
  • labels::AbstractVector{<:AbstractString} = Makie.automatic: Add custom labels, when label_text is set to true. If positions is not specified, labels are used to look up the 10/20 coordinates.
  • head = (color=:black, linewidth=3): draw the outline of the head. Set to nothing to not draw the head outline, otherwise set to a namedtuple that get passed down to the line! call that draws the shape.

Some attributes from topoplot are set to different defaults:

  • label_scatter = true
  • contours = true
  • enlarge = 1`

Otherwise the recipe just uses the topoplot defaults and passes through the attributes.

Note

The 10-05 channel locations are "perfect" spherical locations based on https://github.com/sappelhoff/eegpositions/ - the mne-default 10-20 locations are _not, they were warped to a fsaverage head. Which makes the locations provided here good for visualizations, but not good for source localisation.

Note

You MUST set label_text=true for labels to display.

source

For the standard 10/20 (or 10/05) montage, one can drop the positions attribute:

using TopoPlots, CairoMakie
+EEG · TopoPlots.jl

EEG Topoplots

The eeg_topoplot recipe adds a bit of convenience for plotting Topoplots from EEG data, like drawing a head shape and automatically looking up default positions for known sensors. Otherwise, it supports the same attributes as topoplot.

TopoPlots.eeg_topoplotFunction
eeg_topoplot(data::Vector{<: Real}, labels::Vector{<: AbstractString})

Attributes:

  • positions::Vector{<: Point} = Makie.automatic: Can be calculated from label (channel) names. Currently, only 10/20 montage has default coordinates provided.
  • labels::AbstractVector{<:AbstractString} = Makie.automatic: Add custom labels, when label_text is set to true. If positions is not specified, labels are used to look up the 10/20 coordinates.
  • head = (color=:black, linewidth=3): draw the outline of the head. Set to nothing to not draw the head outline, otherwise set to a namedtuple that get passed down to the line! call that draws the shape.

Some attributes from topoplot are set to different defaults:

  • label_scatter = true
  • contours = true
  • enlarge = 1`

Otherwise the recipe just uses the topoplot defaults and passes through the attributes.

Note

The 10-05 channel locations are "perfect" spherical locations based on https://github.com/sappelhoff/eegpositions/ - the mne-default 10-20 locations are _not, they were warped to a fsaverage head. Which makes the locations provided here good for visualizations, but not good for source localisation.

Note

You MUST set label_text=true for labels to display.

source

For the standard 10/20 (or 10/05) montage, one can drop the positions attribute:

using TopoPlots, CairoMakie
 
 labels = TopoPlots.CHANNELS_10_05 # TopoPlots.CHANNELS_10_20 contains the 10/20 subset
 
-f,ax,h = TopoPlots.eeg_topoplot(rand(348); labels=labels, axis=(aspect=DataAspect(),), label_text=true, label_scatter=(markersize=2, strokewidth=2,),colorrange=[-5,5])
Example block output

If the channels aren't 10/05, one can still plot them, but then the positions need to be passed as well:

data, positions = TopoPlots.example_data()
+f,ax,h = TopoPlots.eeg_topoplot(rand(348); labels=labels, axis=(aspect=DataAspect(),), label_text=true, label_scatter=(markersize=2, strokewidth=2,),colorrange=[-5,5])
Example block output

If the channels aren't 10/05, one can still plot them, but then the positions need to be passed as well:

data, positions = TopoPlots.example_data()
 labels = ["s$i" for i in 1:size(data, 1)]
 TopoPlots.eeg_topoplot(data[:, 340, 1]; labels, label_text = true, positions=positions, axis=(aspect=DataAspect(),))
Example block output

Subset of channels

If you only ask to plot a subset of channels, we highly recommend to define your bounding geometry yourself. We follow MNE functionality and normalize the positions prior to interpolation / plotting. If you only use a subset of channels, the positions will be relative to each other, not at absolute coordinates.

f = Figure()
 ax1 = f[1,1] = Axis(f;aspect=DataAspect())
@@ -12,4 +12,4 @@
 TopoPlots.eeg_topoplot!(ax1,[1,0.5,0]; labels=["Cz","Fz","Fp1"],kwlist...)
 TopoPlots.eeg_topoplot!(ax2,[1,0.5,05]; labels=["Cz","Fz","Fp1"], bounding_geometry=Circle(Point2f(0.5,0.5), 0.5),kwlist...)
 
-f
Example block output

As visible in the left plot, the positions are normalized to the bounding geometry. The right plot shows the same data, but with Cz correctly centered.

Example data

TopoPlots.example_dataFunction
example_data()

Load EEG example data.

Returns a two-tuple:

  • data: a (64, 400, 3) Float32 array of channel x timepoint x stat array. Timepoints corresponds to samples at 500Hz from -0.3s to 0.5s relative to stimulus onset. Stats are mean over subjects, standard errors over subjects, and associated p-value from a t-test. For demonstration purposes, the first stat dimension is generally the most applicable.
  • positions: a length-64 Point2f vector of positions for each channel in data.

Data source

Ehinger, B. V., König, P., & Ossandón, J. P. (2015). Predictions of Visual Content across Eye Movements and Their Modulation by Inferred Information. The Journal of Neuroscience, 35(19), 7403–7413. https://doi.org/10.1523/JNEUROSCI.5114-14.2015

source
+f
Example block output

As visible in the left plot, the positions are normalized to the bounding geometry. The right plot shows the same data, but with Cz correctly centered.

Example data

TopoPlots.example_dataFunction
example_data()

Load EEG example data.

Returns a two-tuple:

  • data: a (64, 400, 3) Float32 array of channel x timepoint x stat array. Timepoints corresponds to samples at 500Hz from -0.3s to 0.5s relative to stimulus onset. Stats are mean over subjects, standard errors over subjects, and associated p-value from a t-test. For demonstration purposes, the first stat dimension is generally the most applicable.
  • positions: a length-64 Point2f vector of positions for each channel in data.

Data source

Ehinger, B. V., König, P., & Ossandón, J. P. (2015). Predictions of Visual Content across Eye Movements and Their Modulation by Inferred Information. The Journal of Neuroscience, 35(19), 7403–7413. https://doi.org/10.1523/JNEUROSCI.5114-14.2015

source
diff --git a/previews/PR63/functions/index.html b/previews/PR63/functions/index.html index c6c6f72..7aec1ee 100644 --- a/previews/PR63/functions/index.html +++ b/previews/PR63/functions/index.html @@ -1,2 +1,2 @@ -Function reference · TopoPlots.jl

Function Reference

TopoPlots.enclosing_geometryFunction
enclosing_geometry(G::Type{<: Geometry}, positions, enlarge=1.0)

Returns the Geometry of Type G, that best fits all positions. The Geometry can be enlarged by 1.x, so e.g. enclosing_geometry(Circle, positions, 0.1) will return a Circle that encloses all positions with a padding of 10%.

source
TopoPlots.labels2positionsFunction
labels2positions(labels)

Currently supports 10/20 and 10/05 layout, by looking it up in TopoPlots.CHANNEL_TO_POSITION_10_05.

source
+Function reference · TopoPlots.jl

Function Reference

TopoPlots.enclosing_geometryFunction
enclosing_geometry(G::Type{<: Geometry}, positions, enlarge=1.0)

Returns the Geometry of Type G, that best fits all positions. The Geometry can be enlarged by 1.x, so e.g. enclosing_geometry(Circle, positions, 0.1) will return a Circle that encloses all positions with a padding of 10%.

source
TopoPlots.labels2positionsFunction
labels2positions(labels)

Currently supports 10/20 and 10/05 layout, by looking it up in TopoPlots.CHANNEL_TO_POSITION_10_05.

source
diff --git a/previews/PR63/general/601b8331.png b/previews/PR63/general/601b8331.png deleted file mode 100644 index aa4a59f..0000000 Binary files a/previews/PR63/general/601b8331.png and /dev/null differ diff --git a/previews/PR63/general/906cdf16.png b/previews/PR63/general/906cdf16.png new file mode 100644 index 0000000..ed5748f Binary files /dev/null and b/previews/PR63/general/906cdf16.png differ diff --git a/previews/PR63/general/bd47eab0.png b/previews/PR63/general/bd47eab0.png deleted file mode 100644 index 1b1538e..0000000 Binary files a/previews/PR63/general/bd47eab0.png and /dev/null differ diff --git a/previews/PR63/general/d63fa61b.png b/previews/PR63/general/d63fa61b.png new file mode 100644 index 0000000..719656a Binary files /dev/null and b/previews/PR63/general/d63fa61b.png differ diff --git a/previews/PR63/general/index.html b/previews/PR63/general/index.html index 8bcb56b..15b7272 100644 --- a/previews/PR63/general/index.html +++ b/previews/PR63/general/index.html @@ -1,12 +1,12 @@ General TopoPlots · TopoPlots.jl

Recipe for General TopoPlots

At the core of TopoPlots.jl is the topoplot recipe, which takes an array of measurements and an array of positions, which then creates a heatmap like plot which interpolates between the measurements from the positions.

TopoPlots.topoplotFunction
topoplot(data::Vector{<:Real}, positions::Vector{<: Point2})

Creates an irregular interpolation for each data[i] point at positions[i].

Attributes

  • colormap = Reverse(:RdBu)

  • colorrange = automatic

  • labels::Vector{<:String} = nothing: names for each data point

  • interpolation::Interpolator = CloughTocher(): Applicable interpolators are TopoPlots.CloughTocher, TopoPlots.DelaunayMesh, TopoPlots.NaturalNeighboursMethod, TopoPlots.NullInterpolator, TopoPlots.ScatteredInterpolationMethod, TopoPlots.SplineInterpolator

  • extrapolation = GeomExtrapolation(): Extrapolation method for adding additional points to get less border artifacts

  • bounding_geometry = Circle: A geometry that defines what to mask and the x/y extend of the interpolation. E.g. Rect(0, 0, 100, 200), will create a heatmap(0..100, 0..200, ...). By default, a circle enclosing the positions points will be used.

  • enlarge = 1.2, enlarges the area that is being drawn. E.g., ifbounding_geometryisCircle`, a circle will be fitted to the points and the interpolation area that gets drawn will be 1.2x that bounding circle.

  • interp_resolution = (512, 512): resolution of the interpolation

  • label_text = false:

    • true: add text plot for each position from labels
    • NamedTuple: Attributes get passed to the Makie.text! call.
  • label_scatter = false:

    • true: add point for each position with default attributes
    • NamedTuple: Attributes get passed to the Makie.scatter! call.
  • markersize = 5: size of the points defined by positions, shortcut for label_scatter=(markersize=5,)

  • plotfnc! = heatmap!: function to use for plotting the interpolation

  • plotfnc_kwargs_names = [:colorrange, :colormap, :interpolate]: different plotfnc support different kwargs, this array contains the keys to filter the full list which is [:colorrange, :colormap, :interpolate]

  • contours = false:

    • true: add scatter point for each position
    • NamedTuple: Attributes get passed to the Makie.contour! call.

Example

using TopoPlots, CairoMakie
-topoplot(rand(10), rand(Point2f, 10); contours=(color=:red, linewidth=2))
source

Interpolation

TopoPlots provides access to interpolators from several different Julia packages through its TopoPlots.Interpolator interface.

They can be accessed via plotting, or directly by calling the instantiated interpolator object as is shown below, namely with the arguments (::Interpolator)(xrange::LinRange, yrange::LinRange, positions::AbstractVector{<: Point{2}}, data::AbstractVector{<:Number}). This is similar to using things like Matlab's regrid function. You can find more details in the Interpolation section.

The recipe supports different interpolation methods, namely:

TopoPlots.DelaunayMeshType
DelaunayMesh()

Creates a delaunay triangulation of the points and linearly interpolates between the vertices of the triangle. Really fast interpolation that happens on the GPU (for GLMakie), so optimal for exploring larger timeseries.

Warning

DelaunayMesh won't allow you to add a contour plot to the topoplot.

Danger

DelaunayMesh will not behave accurately if rendered via CairoMakie, because Cairo (and SVG in general) does not support color maps on meshes. The color within each triangle will be based only on the values at the vertices, which causes inaccurate visuals.

source
TopoPlots.NaturalNeighboursMethodType
NaturalNeighboursMethod(; method=Sibson(1), kwargs...)

Interpolator that uses the NaturalNeighbours.jl package to interpolate the data. This uses Delaunay triangulations and the corresponding Voronoi diagram to interpolate the data, and offers a variety of methods like Sibson(::Int), Nearest(), and Triangle().

The advantage of Voronoi-diagram based methods is that they are more robust to irregularly distributed datasets and some discontinuities, which may throw off some polynomial based methods as well as independent distance weighting (kriging). See this Discourse post for more information on why NaturalNeighbours are cool!

To access the methods easily, you should run using NearestNeighbours.

See the NaturalNeighbours documentation for more details.

This method is fully configurable and will forward all arguments to the relevant NaturalNeighbours.jl functions. To understand what the methods do, see the documentation for NaturalNeighbours.jl.

Keyword arguments

The main keyword argument to look at here is method, which is the method to use for the interpolation. The other keyword arguments are simply forwarded to NaturalNeighbours.jl's interpolator.

  • method: The method to use for the interpolation. Defaults to `Sibson(1). Default: NaturalNeighbours.Sibson{1}()

  • parallel: Whether to use multithreading when interpolating. Defaults to true. Default: true

  • project: Whether to project the data onto the Delaunay triangulation. Defaults to true. Default: true

  • derivative_method: The method to use for the differentiation. Defaults to Direct(). May be Direct() or Iterative(). Default: NaturalNeighbours.Direct()

  • use_cubic_terms: Whether to use cubic terms for estimating the second order derivatives. Only relevant for derivative_method == Direct(). Default: true

  • alpha: The weighting parameter used for estimating the second order derivatives. Only relevant for derivative_method == Iterative(). Default: 0.1

source

You can define your own interpolation by subtyping:

TopoPlots.InterpolatorType

Interface for all types <: Interpolator:

interpolator = Interpolator(; kw_specific_to_interpolator)
-interpolator(xrange::LinRange, yrange::LinRange, positions::Vector{Point2}, data::Vector{<: Real})::Matrix{<: Real}
source

and making your interpolator SomeInterpolator callable with the signature

(::SomeInterpolator)(xrange::LinRange, yrange::LinRange, positions::AbstractVector{<: Point{2}}, data::AbstractVector{<:Number}; mask=nothing)

See also Interpolator Comparison.

Extrapolation

There are currently just two extrapolations: None (NullExtrapolation()) and a geometry based one:

Interpolation

TopoPlots provides access to interpolators from several different Julia packages through its TopoPlots.Interpolator interface.

They can be accessed via plotting, or directly by calling the instantiated interpolator object as is shown below, namely with the arguments (::Interpolator)(xrange::LinRange, yrange::LinRange, positions::AbstractVector{<: Point{2}}, data::AbstractVector{<:Number}). This is similar to using things like Matlab's regrid function. You can find more details in the Interpolation section.

The recipe supports different interpolation methods, namely:

TopoPlots.DelaunayMeshType
DelaunayMesh()

Creates a delaunay triangulation of the points and linearly interpolates between the vertices of the triangle. Really fast interpolation that happens on the GPU (for GLMakie), so optimal for exploring larger timeseries.

Warning

DelaunayMesh won't allow you to add a contour plot to the topoplot.

Danger

DelaunayMesh will not behave accurately if rendered via CairoMakie, because Cairo (and SVG in general) does not support color maps on meshes. The color within each triangle will be based only on the values at the vertices, which causes inaccurate visuals.

source
TopoPlots.NaturalNeighboursMethodType
NaturalNeighboursMethod(; method=Sibson(1), kwargs...)

Interpolator that uses the NaturalNeighbours.jl package to interpolate the data. This uses Delaunay triangulations and the corresponding Voronoi diagram to interpolate the data, and offers a variety of methods like Sibson(::Int), Nearest(), and Triangle().

The advantage of Voronoi-diagram based methods is that they are more robust to irregularly distributed datasets and some discontinuities, which may throw off some polynomial based methods as well as independent distance weighting (kriging). See this Discourse post for more information on why NaturalNeighbours are cool!

To access the methods easily, you should run using NearestNeighbours.

See the NaturalNeighbours documentation for more details.

This method is fully configurable and will forward all arguments to the relevant NaturalNeighbours.jl functions. To understand what the methods do, see the documentation for NaturalNeighbours.jl.

Keyword arguments

The main keyword argument to look at here is method, which is the method to use for the interpolation. The other keyword arguments are simply forwarded to NaturalNeighbours.jl's interpolator.

  • method: The method to use for the interpolation. Defaults to `Sibson(1). Default: NaturalNeighbours.Sibson{1}()

  • parallel: Whether to use multithreading when interpolating. Defaults to true. Default: true

  • project: Whether to project the data onto the Delaunay triangulation. Defaults to true. Default: true

  • derivative_method: The method to use for the differentiation. Defaults to Direct(). May be Direct() or Iterative(). Default: NaturalNeighbours.Direct()

  • use_cubic_terms: Whether to use cubic terms for estimating the second order derivatives. Only relevant for derivative_method == Direct(). Default: true

  • alpha: The weighting parameter used for estimating the second order derivatives. Only relevant for derivative_method == Iterative(). Default: 0.1

source

You can define your own interpolation by subtyping:

TopoPlots.InterpolatorType

Interface for all types <: Interpolator:

interpolator = Interpolator(; kw_specific_to_interpolator)
+interpolator(xrange::LinRange, yrange::LinRange, positions::Vector{Point2}, data::Vector{<: Real})::Matrix{<: Real}
source

and making your interpolator SomeInterpolator callable with the signature

(::SomeInterpolator)(xrange::LinRange, yrange::LinRange, positions::AbstractVector{<: Point{2}}, data::AbstractVector{<:Number}; mask=nothing)

See also Interpolator Comparison.

Extrapolation

There are currently just two extrapolations: None (NullExtrapolation()) and a geometry based one:

TopoPlots.GeomExtrapolationType
GeomExtrapolation(
     method = Shepard(), # extrapolation method
     geometry = Rect, # the geometry to fit around the points
     enlarge = 3.0 # the amount to grow the bounding geometry for adding the extra points
 )

Takes positions and data, and returns points and additional datapoints on an enlarged bounding geometry:

extra = GeomExtrapolation()
-extra_positions, extra_data, bounding_geometry, bounding_geometry_enlarged = extra(positions, data)
source

The extrapolations in action:

using CairoMakie, TopoPlots
+extra_positions, extra_data, bounding_geometry, bounding_geometry_enlarged = extra(positions, data)
source

The extrapolations in action:

using CairoMakie, TopoPlots
 
 data, positions = TopoPlots.example_data()
 titles = ["No Extrapolation", "Rect", "Circle"]
@@ -42,7 +42,7 @@
     colorrange=(-1, 1),
     bounding_geometry = Rect,
     label_scatter=(; strokewidth=2),
-    contours=(linewidth=2, color=:white))
Example block output

Different plotfunctions

It is possible to exchange the plotting function, from heatmap! to contourf! or surface!. Due to different keyword arguments, one needs to filter which keywords are passed to the plotting function manually.

f = Figure()
+    contours=(linewidth=2, color=:white))
Example block output

Different plotfunctions

It is possible to exchange the plotting function, from heatmap! to contourf! or surface!. Due to different keyword arguments, one needs to filter which keywords are passed to the plotting function manually.

f = Figure()
 
 TopoPlots.topoplot(f[1,1],
     rand(10), rand(Point2f, 10),
@@ -54,4 +54,4 @@
     axis=(; aspect=DataAspect()),
     plotfnc! = surface!) # surface can take all default kwargs similar to heatmap!
 
-f
Example block output
+fExample block output diff --git a/previews/PR63/index-10ee65f5.png b/previews/PR63/index-10ee65f5.png new file mode 100644 index 0000000..d06be4b Binary files /dev/null and b/previews/PR63/index-10ee65f5.png differ diff --git a/previews/PR63/index-773a5786.png b/previews/PR63/index-773a5786.png deleted file mode 100644 index 0c77301..0000000 Binary files a/previews/PR63/index-773a5786.png and /dev/null differ diff --git a/previews/PR63/index.html b/previews/PR63/index.html index 307c778..7b5a605 100644 --- a/previews/PR63/index.html +++ b/previews/PR63/index.html @@ -5,4 +5,4 @@ topoplot(f[1,2],rand(20), rand(Point2f, 20); contours=(color=:white, linewidth=2), label_scatter=true, bounding_geometry=Rect(0,0,1,1), colormap=:viridis) eeg_topoplot(f[1,3],rand(20),1:20;positions=rand(Point2f, 20), colormap=:Oranges) -fExample block output

Find more documentation for topoplot in Recipe for General TopoPlots.

It also contains some more convenience methods for EEG data, which is explained in EEG Topoplots.

You can also use TopoPlots' interpolators as a simple interface to regrid irregular data. See Interpolation for more details.

+fExample block output

Find more documentation for topoplot in Recipe for General TopoPlots.

It also contains some more convenience methods for EEG data, which is explained in EEG Topoplots.

You can also use TopoPlots' interpolators as a simple interface to regrid irregular data. See Interpolation for more details.

diff --git a/previews/PR63/interpolator_reference/76df416d.png b/previews/PR63/interpolator_reference/76df416d.png new file mode 100644 index 0000000..d574163 Binary files /dev/null and b/previews/PR63/interpolator_reference/76df416d.png differ diff --git a/previews/PR63/interpolator_reference/e9f51c68.png b/previews/PR63/interpolator_reference/e9f51c68.png deleted file mode 100644 index e5d9332..0000000 Binary files a/previews/PR63/interpolator_reference/e9f51c68.png and /dev/null differ diff --git a/previews/PR63/interpolator_reference/index.html b/previews/PR63/interpolator_reference/index.html index 5f5cbdb..ed80142 100644 --- a/previews/PR63/interpolator_reference/index.html +++ b/previews/PR63/interpolator_reference/index.html @@ -41,4 +41,4 @@ ax.subtitle = string(typeof(interpolation.method)) end end -fExample block output +fExample block output