Skip to content

Commit

Permalink
Merge pull request #247 from unfoldtoolbox/prepublication
Browse files Browse the repository at this point in the history
Prepublication
- #244 Added benchmarking with comparison of UM with MNE and MATLAB to measure speed of creating and updating figures. 
- adding supportive axes for `plot_topoplot`, `plot_topoplotseries`, `plot_butterfly` so now it is possible for users to change interpolations and axes of subplots
- adding Observables into `plot_topoplot`
- #245 was solved by adding `visual.colormap`
- #248 
- #240
- #257 
- #261 - issue with `with_theme`
- `Contribute` page added
- issues templates added
- upgrade Color and ColorTypes
  • Loading branch information
vladdez authored Nov 6, 2024
2 parents 8bdd745 + ba0f99b commit 1a98b84
Show file tree
Hide file tree
Showing 34 changed files with 527 additions and 233 deletions.
38 changes: 38 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Contribution guide
Contributions are very welcome. These could be typos, bug reports, feature requests, speed optimization, better code, and better documentation.
You are very welcome to raise issues and start pull requests.

## Issues
If you notice any bugs, such as crashing code, incorrect results or speed issues, please raise a GitHub issue.

Before filing an issue please
- check that there are no similar existing issues already
- check that your versions are up to date

If you want to report a bug, include your version and system information, as well as stack traces with all relevant information.
If possible, condense your bug into the shortest example possible that the maintainers can replicate, a so called "minimal working example" or MWE.

If you want to suggest a new feature, for example functionality that other plotting packages offer already, include supplementary material such as example images if possible, so it's clear what you are asking for.

## Code contributions (Pull requests)
When opening a pull request, please add a short but meaningful description of the changes/features you implemented. Moreover, please add tests (where appropriate) to ensure that your code is working as expected.

For each feature you want to contribute, please file a separate PR to keep the complexity down and time to merge short.
Add PRs in draft mode if you want to discuss your approach first.


## Adding documentation
1. We recommend to write a Literate.jl document and place it in `docs/literate/FOLDER/FILENAME.jl` with `FOLDER` being `HowTo`, `Explanations`, `Tutorials` or `Intro` ([recommended reading on the 4 categories](https://documentation.divio.com/)).
2. Literate.jl converts the `.jl` file to a `.md` automatically and places it in `docs/src/generated/FOLDER/FILENAME.md`.
3. Edit [make.jl](https://github.com/unfoldtoolbox/Unfold.jl/blob/main/docs/make.jl) with a reference to `docs/src/generated/FOLDER/FILENAME.md`.

## Formatting (Beware of reviewdog :dog:)
We use the [julia-format](https://github.com/julia-actions/julia-format) Github action to ensure that the code follows the formatting rules defined by [JuliaFormatter.jl](https://github.com/domluna/JuliaFormatter.jl).
When opening a pull request [reviewdog](https://github.com/reviewdog/reviewdog) will automatically make formatting suggestions for your code.

## Seeking Help

If you get stuck, here are some options to seek help:

- Use the REPL `?` help mode.
- Check the Documentation.
10 changes: 5 additions & 5 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "UnfoldMakie"
uuid = "69a5ce3b-64fb-4f22-ae69-36dd4416af2a"
authors = ["Vladimir Mikheev", "Daniel Baumgartner", "Sören Döring", "Niklas Gärtner", "Furkan Lokman", "Benedikt Ehinger"]
version = "0.5.8"
version = "0.5.9"

[deps]
AlgebraOfGraphics = "cbdf2221-f076-402e-a563-3d30da359d67"
Expand Down Expand Up @@ -38,16 +38,16 @@ AlgebraOfGraphics = "0.7, 0.8"
BSplineKit = "0.16, 0.17"
CategoricalArrays = "0.10"
ColorSchemes = "3"
ColorTypes = "0.11"
Colors = "0.12"
ColorTypes = "0.11, 0.12"
Colors = "0.12, 0.13"
CoordinateTransformations = "0.6"
DataFrames = "1"
DataStructures = "0.18"
DocStringExtensions = "0.9"
GeometryBasics = "0.4"
GridLayoutBase = "0.9, 0.10, 0.11"
ImageFiltering = "0.7"
Interpolations = "0.14,0.15"
Interpolations = "0.14, 0.15"
LinearAlgebra = "1"
Makie = "0.17, 0.18, 0.19, 0.20, 0.21"
MakieThemes = "0.1"
Expand All @@ -56,7 +56,7 @@ SparseArrays = "1"
StaticArrays = "1"
Statistics = "1"
TopoPlots = "0.1"
Unfold = "0.3, 0.4, 0.5, 0.6, 0.7"
Unfold = "0.6, 0.7"
julia = "1"

[extras]
Expand Down
4 changes: 4 additions & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[deps]
AlgebraOfGraphics = "cbdf2221-f076-402e-a563-3d30da359d67"
BSplineKit = "093aae92-e908-43d7-9660-e50ee39d5a0a"
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
ColorSchemes = "35d6a980-a343-548e-a6ea-1d62b119f2f4"
Expand All @@ -10,10 +11,13 @@ DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
DataFramesMeta = "1313f7d8-7da2-5740-9ea0-a2ca25f37964"
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
FFMPEG_jll = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5"
Glob = "c27321d9-0574-5035-807b-f59d2c89b15c"
Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306"
MakieThemes = "e296ed71-da82-5faf-88ab-0034a9761098"
Observables = "510215fc-4207-5dde-b226-833fc4488ee2"
PyMNE = "6c5003b2-cbe8-491c-a0d1-70088e6a0fd6"
PythonPlot = "274fc56d-3b97-40fa-a1cd-1b4a50311bf9"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
StatsModels = "3eaba693-59b7-5ba5-a881-562e759f1c8d"
Expand Down
2 changes: 1 addition & 1 deletion docs/example_data.jl
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ function example_data(example = "TopoPlots.jl")
dat, evts =
UnfoldSim.predef_eeg(; onset = LogNormalOnset= 3.5, σ = 0.4), noiselevel = 5)
dat_e, times = Unfold.epoch(dat, evts, [-0.1, 1], 100)
evts, dat_e = UnfoldMakie.drop_missing_epochs(evts, dat_e)
evts, dat_e = Unfold.drop_missing_epochs(evts, dat_e)
evts.Δlatency = vcat(diff(evts.latency), 0)
dat_e = dat_e[1, :, :]
#evts = filter(row -> row.Δlatency > 0, evts)
Expand Down
2 changes: 0 additions & 2 deletions docs/literate/how_to/hide_deco.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,13 @@ plot_butterfly!(
f[1, 1],
data;
positions = pos,
topomarkersize = 10,
topo_axis = (; height = Relative(0.4), width = Relative(0.4)),
axis = (; title = "With decorations"),
)
plot_butterfly!(
f[2, 1],
data;
positions = pos,
topomarkersize = 10,
topo_axis = (; height = Relative(0.4), width = Relative(0.4)),
axis = (; title = "Without decorations"),
layout = (; hidedecorations = (:label => true, :ticks => true, :ticklabels => true)),
Expand Down
20 changes: 11 additions & 9 deletions docs/literate/how_to/mult_vis_in_fig.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ using DataFramesMeta
using UnfoldSim
using Unfold
using MakieThemes
set_theme!(theme_ggthemr(:fresh)) # nicer defaults - should maybe be default?


# ## Data input
include("../../../example_data.jl")
Expand All @@ -37,16 +37,19 @@ By using the !-version of the plotting function and inserting a grid position in
# `f = Figure()`

# Now any plot can be added to `f` by placing a grid position, such as `f[1, 1]`.
# Also we used a specified theme `fresh`.

f = Figure()
plot_erp!(f[1, 1], coeftable(uf_deconv))
plot_erp!(
f[1, 2],
effects(Dict(:condition => ["car", "face"]), uf_deconv),
mapping = (; color = :condition),
)
plot_butterfly!(f[2, 1:2], d_topo; positions = positions)
with_theme(theme_ggthemr(:fresh)) do

plot_erp!(f[1, 1], coeftable(uf_deconv))
plot_erp!(
f[1, 2],
effects(Dict(:condition => ["car", "face"]), uf_deconv),
mapping = (; color = :condition),
)
plot_butterfly!(f[2, 1:2], d_topo; positions = positions)
end
f

# # Very complex figure
Expand Down Expand Up @@ -145,7 +148,6 @@ plot_butterfly!(
gb,
d_topo;
positions = pos,
topomarkersize = 10,
topo_axis = (; height = Relative(0.4), width = Relative(0.4)),
)
hlines!(0, color = :gray, linewidth = 1)
Expand Down
119 changes: 119 additions & 0 deletions docs/literate/intro/speed.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# # Speed measurement
# Here we will compare the speed of plotting UnfoldMakie with MNE (Python) and EEGLAB (MATLAB).
#
# Three cases are measured:
# - Single topoplot
# - Topoplot series with 50 topoplots
# - Topoplott animation with 50 timestamps
#
# Note that the results of benchmarking on your computer and on Github may differ.
using UnfoldMakie
using TopoPlots
using PyMNE
using PythonPlot
using BenchmarkTools
using Observables
using CairoMakie

# Data input
dat, positions = TopoPlots.example_data()
df = UnfoldMakie.eeg_array_to_dataframe(dat[:, :, 1], string.(1:length(positions)));

# # Topoplots

# UnfoldMakie.jl
@benchmark plot_topoplot(dat[:, 320, 1]; positions = positions)

# UnfoldMakie.jl with DelaunayMesh
@benchmark plot_topoplot(
dat[:, 320, 1];
positions = positions,
topo_interpolation = (; interpolation = DelaunayMesh()),
)

# MNE
posmat = collect(reduce(hcat, [[p[1], p[2]] for p in positions])')
pypos = Py(posmat).to_numpy()
pydat = Py(dat[:, 320, 1])

@benchmark begin
f = PythonPlot.figure()
PyMNE.viz.plot_topomap(
pydat,
pypos,
sphere = 1.1,
extrapolate = "box",
cmap = "RdBu_r",
sensors = false,
contours = 6,
)
f.show()
end

# # Topoplot series

# Note that UnfoldMakie and MNE have different defaults for displaying topoplot series.
# UnfoldMakie in `plot_topoplot` averages over time samples.
# MNE in `plot_topopmap` displays single samples without averaging.
#
# UnfoldMakie.jl
@benchmark begin
plot_topoplotseries(
df;
bin_num = 50,
positions = positions,
axis = (; xlabel = "Time windows [s]"),
)
end

# MNE
easycap_montage = PyMNE.channels.make_standard_montage("standard_1020")
ch_names = pyconvert(Vector{String}, easycap_montage.ch_names)[1:64]
info = PyMNE.create_info(PyList(ch_names), ch_types = "eeg", sfreq = 1)
info.set_montage(easycap_montage)
simulated_epochs = PyMNE.EvokedArray(Py(dat[:, :, 1]), info)

@benchmark simulated_epochs.plot_topomap(1:50)

# MATLAB
#
# Running MATLAB on a GitHub Action is not easy.
# So we benchmarked three consecutive executions (on a screenshot) on a server with an AMD EPYC 7452 32-core processor.
# Note that Github and the server we used for MATLAB benchmarking are two different computers, which can give different timing results.

# ```@raw html
# <img src="../../../assets/MATLAB_benchmarking.png" align="middle"/>
# ```


# # Animation
# The main advantage of Julia is the speed with which the figures are updated.

timestamps = range(1, 50, step = 1)
framerate = 50

# UnfoldMakie with .gif

@benchmark begin
f = Makie.Figure()
dat_obs = Observable(dat[:, 1, 1])
plot_topoplot!(f[1, 1], dat_obs, positions = positions)
record(f, "topoplot_animation_UM.gif", timestamps; framerate = framerate) do t
dat_obs[] = @view(dat[:, t, 1])
end
end

# ![](topoplot_animation_UM.gif)

# MNE with .gif
@benchmark begin
fig, anim = simulated_epochs.animate_topomap(
times = Py(timestamps),
frame_rate = framerate,
blit = false,
image_interp = "cubic", # same as CloughTocher
)
anim.save("topomap_animation_mne.gif", writer = "ffmpeg", fps = framerate)
end

# ![](topomap_animation_mne.gif)
6 changes: 3 additions & 3 deletions docs/literate/tutorials/butterfly.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ plot_butterfly(df)

plot_butterfly(df; positions = pos)

# You want to change size of topomarkers and size of topoplot:
# You want to change size of topoplot markers and size of topoplot:

plot_butterfly(
df;
positions = pos,
topomarkersize = 10,
topo_attributes = (; label_scatter = (; markersize = 30)),
topo_axis = (; height = Relative(0.4), width = Relative(0.4)),
)

Expand Down Expand Up @@ -103,7 +103,7 @@ plot_butterfly(
visual = (; color = 1:2, colormap = [gray, :red]),
)

# # Column Mappings for Butterfly Plot
# # Column Mappings

# Since butterfly plots use a `DataFrame` as input, the library needs to know the names of the columns used for plotting. You can set these mapping values by calling `plot_butterfly(...; mapping=(; :x=:time))`. Just specify a `NamedTuple`. Note the `;` right after the opening parentheses.

Expand Down
1 change: 1 addition & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ makedocs(;
"Installation" => "generated/intro/installation.md",
"Plot types" => "generated/intro/plot_types.md",
"Code principles" => "generated/intro/code_principles.md",
"Benchmarking" => "generated/intro/speed.md",
],
"ERP Visualizations" => [
"ERP plot" => "generated/tutorials/erp.md",
Expand Down
Binary file added docs/src/assets/MATLAB_benchmarking.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/src/assets/topomap_animation_mne.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/src/assets/topomap_animation_mne.mp4
Binary file not shown.
Binary file added docs/src/assets/topoplot_animation_UM.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/src/assets/topoplot_animation_UM.mp4
Binary file not shown.
4 changes: 3 additions & 1 deletion src/UnfoldMakie.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,10 @@ include("plot_topoplotseries.jl")

include("plot_erp.jl")
include("plot_butterfly.jl")
include("plot_designmatrix.jl")
include("plot_splines.jl")
include("plot_designmatrix.jl")


include("plot_topoplot.jl")
include("plot_erpimage.jl")
include("plot_parallelcoordinates.jl")
Expand Down
Loading

0 comments on commit 1a98b84

Please sign in to comment.