Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implements plotfunction #47 #56

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
test/test_images
test/Manifest.toml
docs/Manifest.toml
docs/.CondaPkg
deps/build.log
6 changes: 3 additions & 3 deletions docs/src/eeg.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,20 @@ TopoPlots.eeg_topoplot



So for the standard 10/20 montage, one can drop the `positions` attribute:
For the standard 10/20 montage, one can drop the `positions` attribute:
```@example 1
using TopoPlots, CairoMakie

labels = TopoPlots.CHANNELS_10_20
TopoPlots.eeg_topoplot(rand(19), labels; axis=(aspect=DataAspect(),), label_text=true, label_scatter=(markersize=10, strokewidth=2,))
TopoPlots.eeg_topoplot(rand(19); labels=labels, axis=(aspect=DataAspect(),), label_text=true, label_scatter=(markersize=10, strokewidth=2,))
```

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

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

```@docs
Expand Down
26 changes: 24 additions & 2 deletions docs/src/general.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ using TopoPlots, CairoMakie, ScatteredInterpolation, NaturalNeighbours

data, positions = TopoPlots.example_data()

f = Figure(resolution=(1000, 1250))
f = Figure(size=(1000, 1250))

interpolators = [
DelaunayMesh() CloughTocher();
SplineInterpolator() NullInterpolator();
ScatteredInterpolationMethod(ThinPlate()) ScatteredInterpolationMethod(Shepard(3));
NaturalNeighboursMethod(Sibson(1)) NaturalNeighboursMethod(Triangle());
#NaturalNeighboursMethod(Sibson(1)) NaturalNeighboursMethod(Triangle());
]

data_slice = data[:, 360, 1]
Expand Down Expand Up @@ -146,3 +146,25 @@ TopoPlots.topoplot(
label_scatter=(; strokewidth=2),
contours=(linewidth=2, color=:white))
```


## 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.

```@example 1
f = Figure()

TopoPlots.topoplot(f[1,1],
rand(10), rand(Point2f, 10),
axis=(; aspect=DataAspect()),
plotfnc! = contourf!, plotfnc_kwargs_filter=[:colormap])

TopoPlots.topoplot(f[1,2],
rand(10), rand(Point2f, 10),
axis=(; aspect=DataAspect()),
plotfnc! = surface!) # surface can take all default kwargs similar to heatmap!

f

```
180 changes: 180 additions & 0 deletions docs/src/topo_series.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
### A Pluto.jl notebook ###
# v0.19.9

using Markdown
using InteractiveUtils

# ╔═╡ 2fafb0da-f3a9-11ec-0ddf-6725344070fe
begin
using Pkg
Pkg.activate("../../devEnv") # docs
#Pkg.add("PyMNE")
#Pkg.add(path="../../../TopoPlotsjl/")
Pkg.develop(path="../../../TopoPlotsjl/")
#Pkg.add("DataFrames")
#Pkg.add("AlgebraOfGraphics")
#Pkg.add("StatsBase")
#Pkg.add("CategoricalArrays")

#Pkg.add("JLD2")

#Pkg.add("CairoMakie")
end

# ╔═╡ c4a25915-c7f5-453a-a4f0-4b40ebedea4c
using Revise

# ╔═╡ 59b87673-02d2-4deb-90be-74d923d170eb
using TopoPlots


# ╔═╡ 452a245c-773a-4303-a970-f2592c3e879f
begin
#using TopoPlots
#using ../../../Topoplotsjl
using CairoMakie
using DataFrames


end


# ╔═╡ 77dc1ba9-9484-485b-a49d-9aa231ef4983
using Statistics

# ╔═╡ 311f10ff-deb8-4f82-8b12-d5b643656828
using PyMNE

# ╔═╡ 9fa5c598-3578-4989-9585-29fd32ae1056
using Distributions

# ╔═╡ 6cda29dc-7086-4079-83c6-3650204a82ff
pathof(TopoPlots)

# ╔═╡ e0cc560f-d3e8-415b-b22d-6bca23ef093c
revise(TopoPlots)

# ╔═╡ f4b81740-d907-42ae-a0df-f46fb2f2cb15
begin

data = Array{Float32}(undef, 64, 400, 3)
#read!(TopoPlots.assetpath("example-data.bin"), data)
read!(splitdir(pathof(TopoPlots))[1]*"/../assets/example-data.bin",data)

positions = Vector{Point2f}(undef, 64)
read!(splitdir(pathof(TopoPlots))[1]*"/../assets/layout64.bin",positions)
#read!(TopoPlots.assetpath("layout64.bin"), positions)

end;


# ╔═╡ 42f7755b-80f4-4185-8d21-42e11730e0fc
begin
using Random
pos = positions[1:10]
eeg_topoplot(rand(MersenneTwister(1),length(pos)), string.(1:length(pos));positions=pos,pad_value=0.)
end

# ╔═╡ aad784ee-6bb7-4f3c-8444-be050456ddea
eeg_topoplot(data[:, 340, 1], string.(1:length(positions));positions=positions)

# ╔═╡ 237e4f4a-cdf2-4bac-8096-de8050251745
eeg_topoplot(data[:, 340, 1], string.(1:length(positions));positions=positions,pad_value=0.1)

# ╔═╡ f522329b-3653-4059-9955-8cd05570e923
topoplot(rand(MersenneTwister(1),length(pos)),pos)

# ╔═╡ a9d2a2e2-6c8c-4cfc-9fed-b5e082cb44af
let
mon = PyMNE.channels.make_standard_montage("standard_1020")

posMat = (Matrix(hcat(pos...)).-0.5).*0.5
#pos = PyMNE.channels.make_eeg_layout(mon).pos
PyMNE.viz.plot_topomap(rand(MersenneTwister(1),length(pos)),posMat',cmap="RdBu_r",extrapolate="box",border=-1)
end

# ╔═╡ c358633f-8d18-4c5e-80f7-ab972e8860be
Pkg.status("TopoPlots")

# ╔═╡ c0a2ad2e-ccce-4e80-b52c-75f1428ed182
e1eg_topoplot(data[:, 340, 1], string.(1:length(positions));positions=positions,interpolation = TopoPlots.NormalMixtureInterpolator() )

# ╔═╡ d7620a42-d54c-4244-a820-d15aecdae626
@time TopoPlots.eeg_topoplot_series(data[:,:,1],40;topoplotCfg=(positions=positions,label_scatter=false))

# ╔═╡ ec59c704-ae33-4a62-82ce-63acc6b17793
f, ax, pl = TopoPlots.eeg_topoplot(1:length(TopoPlots.CHANNELS_10_20),TopoPlots.CHANNELS_10_20; interpolation=TopoPlots.NullInterpolator(),)

# ╔═╡ f3d1f3cc-f7c9-4ef4-ba4f-3d32f2509cad
let
# 4 coordinates with one peak
positions = Point2f[(-1, 0), (0, -1), (1, 0), (0, 1)]
i = 1
peak_xy = positions[i]
data = zeros(length(positions))
data[i] = 1.1
fig = topoplot(data, positions)
# tighten the limits so that the limits of the axis and the data will match
tightlimits!(fig.axis)

# retrieve the interpolated data
m = fig.plot.plots[].color[]
# get the limits of the axes and data
rect = fig.axis.targetlimits[]
minx, miny = minimum(rect)
maxx, maxy = maximum(rect)
# recreate the coordinates of the data
x = range(minx, maxx, length=size(m, 1))
y = range(miny, maxy, length=size(m, 2))
xys = Point2f.(x, y')

# find the highest point
_, i = findmax(x -> isnan(x) ? -Inf : x, m)
xy = xys[i]
@show peak_xy
@show xy
#@test isapprox(xy, peak_xy; atol=0.02)
@show isapprox(xy, peak_xy; atol=0.02)
fig
end

# ╔═╡ 872ac6a4-ddaa-4dfb-a40d-9d5ea55bdb3d
let
f = Figure()
axis = Axis(f[1, 1], aspect = 1)
xlims!(low = -2, high = 2)
ylims!(low = -2, high = 2)

data = [0, 0, 0]
pos1 = [Point2f(-1, -1), Point2f(-1.0, 0.0), Point2f(0, -1)]
pos2 = [Point2f(1, 1), Point2f(1.0, 0.0), Point2f(0, 1)]

pos1 = pos1 .- mean(pos1)
pos2 = pos2 .- mean(pos2)
eeg_topoplot!(axis, data, positions=pos1)
eeg_topoplot!(axis, data, positions=pos2)
f
end

# ╔═╡ Cell order:
# ╠═2fafb0da-f3a9-11ec-0ddf-6725344070fe
# ╠═6cda29dc-7086-4079-83c6-3650204a82ff
# ╠═c4a25915-c7f5-453a-a4f0-4b40ebedea4c
# ╠═e0cc560f-d3e8-415b-b22d-6bca23ef093c
# ╠═59b87673-02d2-4deb-90be-74d923d170eb
# ╠═452a245c-773a-4303-a970-f2592c3e879f
# ╠═f4b81740-d907-42ae-a0df-f46fb2f2cb15
# ╠═77dc1ba9-9484-485b-a49d-9aa231ef4983
# ╠═aad784ee-6bb7-4f3c-8444-be050456ddea
# ╠═237e4f4a-cdf2-4bac-8096-de8050251745
# ╠═42f7755b-80f4-4185-8d21-42e11730e0fc
# ╠═f522329b-3653-4059-9955-8cd05570e923
# ╠═311f10ff-deb8-4f82-8b12-d5b643656828
# ╠═a9d2a2e2-6c8c-4cfc-9fed-b5e082cb44af
# ╠═c358633f-8d18-4c5e-80f7-ab972e8860be
# ╠═9fa5c598-3578-4989-9585-29fd32ae1056
# ╠═c0a2ad2e-ccce-4e80-b52c-75f1428ed182
# ╠═d7620a42-d54c-4244-a820-d15aecdae626
# ╠═ec59c704-ae33-4a62-82ce-63acc6b17793
# ╠═f3d1f3cc-f7c9-4ef4-ba4f-3d32f2509cad
# ╠═872ac6a4-ddaa-4dfb-a40d-9d5ea55bdb3d
4 changes: 2 additions & 2 deletions src/TopoPlots.jl
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ export GeomExtrapolation, NullExtrapolation
@compile_workload begin
# all calls in this block will be precompiled, regardless of whether
# they belong to your package or not (on Julia 1.8 and higher)
eeg_topoplot(view(data, :, 340, 1); positions)
eeg_topoplot(data[:, 340, 1]; positions)
eeg_topoplot(view(data, :, 340, 1); positions)
eeg_topoplot(data[:, 340, 1]; positions)
end
end

Expand Down
11 changes: 8 additions & 3 deletions src/core-recipe.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
labels = nothing,
label_text = false,
label_scatter = false,
contours = false
contours = false,
plotfnc! = heatmap!,
plotfnc_kwargs_filter= [:colorrange, :colormap, :interpolate],
)
end

Expand All @@ -39,6 +41,8 @@ Creates an irregular interpolation for each `data[i]` point at `positions[i]`.
* 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_filter = [: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
Expand Down Expand Up @@ -116,8 +120,9 @@ function Makie.plot!(p::TopoPlot)
# z[mask] .= NaN
return z
end

heatmap!(p, xg, yg, data, colormap=p.colormap, colorrange=colorrange, interpolate=true)
kwargs_all = Dict(:colorrange => colorrange, :colormap => p.colormap, :interpolate => true)

p.plotfnc![](p, xg, yg, data; (p.plotfnc_kwargs_filter[].=>getindex.(Ref(kwargs_all),p.plotfnc_kwargs_filter[]))...)
contours = to_value(p.contours)
attributes = @plot_or_defaults contours Attributes(color=(:black, 0.5), linestyle=:dot, levels=6)
if !isnothing(attributes) && !(p.interpolation[] isa NullInterpolator)
Expand Down
Loading
Loading