Skip to content

Commit

Permalink
Merge pull request #219 from unfoldtoolbox/data_input
Browse files Browse the repository at this point in the history
fixed issues with more general data input #213:
- data inputs for `plot_channelimage(::DataFrame)`, `plot_erpgrid(::DataFrame)`, `plot_parallelcoordinates(::Matrix)`, `plot_topoplot(::Vector)`
- mistakes in signatures for `plot_butterfly` and `plot_erp`, moving some actions inside code from signatures
- updated docstrings
- adding sorting methods in arguments for channel image, arguments `sorting_variables` and `sorting_reverse`
- more tests for checking length mismatch of arguments in `plot_topoplot`, `plot_erpgrid` and `plot_channelimage`
- adding `ch_names::Vector{String}` into arguments for `plot_erpgrid`

Other
- fixed #227 
- fixed #218 
- fixed #221 
- typos in docs
  • Loading branch information
vladdez authored Sep 11, 2024
2 parents d6dbb7a + 3b89404 commit 7677752
Show file tree
Hide file tree
Showing 32 changed files with 471 additions and 196 deletions.
2 changes: 1 addition & 1 deletion 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.6"
version = "0.5.7"

[deps]
AlgebraOfGraphics = "cbdf2221-f076-402e-a563-3d30da359d67"
Expand Down
6 changes: 6 additions & 0 deletions docs/literate/how_to/hide_deco.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ include("../../../example_data.jl")
data, pos = example_data("TopoPlots.jl")
dat, evts = UnfoldSim.predef_eeg(; noiselevel = 10, return_epoched = true)

# # Hiding

#=
First, you can specify the axis settings with `axis = (; ...)`.
Expand Down Expand Up @@ -54,6 +56,10 @@ plot_erpimage!(
dat;
layout = (; hidespines = (), hidedecorations = (), use_colorbar = false),
)


# # Showing

#=
Some plots hide features by default. This could be reverted by setting the variables to `nothing`
=#
Expand Down
2 changes: 1 addition & 1 deletion docs/literate/how_to/mult_vis_in_fig.jl
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ plot_erpgrid!(

dat_e, evts, times = example_data("sort_data")
plot_erpimage!(gf, times, dat_e; sortvalues = evts.Δlatency)
plot_channelimage!(gg, data[:, :, 1], positions[1:30], raw_ch_names;)
plot_channelimage!(gg, data[1:30, :, 1], positions[1:30], raw_ch_names;)
r1, positions = example_data()
r2 = deepcopy(r1)
r2.coefname .= "B" # create a second category
Expand Down
2 changes: 1 addition & 1 deletion docs/literate/tutorials/channel_image.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ raw_ch_names = ["FP1", "F3", "F7", "FC3", "C3", "C5", "P3", "P7", "P9", "PO7",
"C4", "C6", "P4", "P8", "P10", "PO8", "PO4", "O2"]


plot_channelimage(data, pos, raw_ch_names;)
plot_channelimage(data[1:30, :], pos, raw_ch_names;)

# # Configurations for Channel image

Expand Down
3 changes: 1 addition & 2 deletions docs/literate/tutorials/erp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ plot_erp(results)
plot_erp(
res_effects;
mapping = (; y = :yhat, color = :continuous, group = :continuous),
legend = (; nbanks = 2),
layout = (; show_legend = true, legend_position = :right),
layout = (; show_legend = false),
categorical_color = false, # perceives color (here: continuous) as contionus
categorical_group = true, # separates lines, if `false` all lines will be connected
)
Expand Down
14 changes: 7 additions & 7 deletions docs/literate/tutorials/parallelcoordinates.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# # Parallel Coordinates

# **Parallel Coordinates Plot** (PCP) is a plot type used to visualize EEG activity for some channels.
# It can fully represent condition and channel dimensions using lines. It can also partially represent time and trials
# Each vertical axis represent voltage level for a channel.
# Each line represent a trial, color represent a condition.
# It can fully represent condition and channel dimensions using lines. It can also partially represent time and trials.

# Each vertical axis represents a voltage level for a channel.
# Each line represents a trial, each colour represents a condition.

# # Setup
# Package loading
Expand All @@ -28,6 +29,7 @@ nothing #hide
plot_parallelcoordinates(
subset(results_plot, :channel => x -> x .<= 5);
mapping = (; color = :coefname),
ax_labels = ["FP1", "F3", "F7", "FC3", "C3"],
)

# # Additional features
Expand All @@ -36,9 +38,9 @@ plot_parallelcoordinates(

#=
On the first image, there is no normalization and the extremes of all axes are the same and equal to the max and min values across all chanells.
On the second image, there is a `minmax normalization``, so each axis has its own extremes based on the min and max of the data.
On the second image, there is a `minmax normalization`, so each axis has its own extremes based on the min and max of the data.
Typically, parallelplots are normalized per axis. Whether this makes sense for estimating channel x, we do not know.
Typically, parallel plots are normalized per axis. Whether this makes sense for estimating channel x, we do not know.
=#

f = Figure()
Expand Down Expand Up @@ -158,15 +160,13 @@ plot_parallelcoordinates(
f[1, 1],
uf_5chan;
mapping = (; color = :coefname),
layout = (; legend_position = :right),
visual = (; alpha = 0.1),
axis = (; title = "alpha = 0.1"),
)
plot_parallelcoordinates(
f[2, 1],
uf_5chan,
mapping = (; color = :coefname),
layout = (; legend_position = :right),
visual = (; alpha = 0.9),
axis = (; title = "alpha = 0.9"),
)
Expand Down
14 changes: 8 additions & 6 deletions docs/literate/tutorials/topoplot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ using DataFrames

# Data loading

data, positions = TopoPlots.example_data()
dat, positions = TopoPlots.example_data()

# The size of `data` is 64×400×3. This means:
# - 64 channels;
Expand All @@ -29,9 +29,9 @@ data, positions = TopoPlots.example_data()
# # Plot Topoplots

# Here we select a time point in 340 msec and the mean estimate.
plot_topoplot(data[:, 340, 1]; positions = positions)
plot_topoplot(dat[1:4, 340, 1]; positions = positions[1:4])

df = DataFrame(:estimate => data[:, 340, 1])
df = DataFrame(:estimate => dat[:, 340, 1])
plot_topoplot(df; positions = positions)


Expand Down Expand Up @@ -73,15 +73,17 @@ f = Figure(size = (500, 500))
labs4 = ["O1", "F2", "F3", "P4"]
plot_topoplot!(
f[1, 1],
data[1:4, 340, 1];
dat[1:4, 340, 1];
positions = positions[1:4],
visual = (; label_scatter = false),
labels = labs4,
axis = (; title = "no channel scatter"),
)

plot_topoplot!(
f[1, 2],
data[1:4, 340, 1];
dat[1:4, 340, 1];
positions = positions[1:4],
visual = (; label_text = true, label_scatter = (markersize = 15, strokewidth = 2)),
labels = labs4,
axis = (; title = "channel scatter with text"),
Expand All @@ -93,4 +95,4 @@ f

# ```@docs
# plot_topoplot
# ```
# ```
21 changes: 21 additions & 0 deletions docs/literate/tutorials/topoplotseries.jl
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,27 @@ plot_topoplotseries(
),
)

# ## Adjusting column gaps
# Using `colgap` in `with_theme` helps to adjust column gaps.

with_theme(colgap = 5) do
plot_topoplotseries(df, bin_num = 5; positions = positions)
end

# However it doesn't work with subsets. Here you need to use `topoplot_axes.limits`.

begin
f = Figure()
plot_topoplotseries!(
f[1, 1],
df,
bin_num = 5;
positions = positions,
topoplot_axes = (; limits = (-0.05, 1.05, -0.1, 1.05)),
)
f
end

# ## Adjusting contours
# Topographic contour is a line drawn on a topographic map to indicate an increase or decrease in voltage.
# A contour level is an area with a specific range of voltage. By default, the number of contour levels is 6, which means that the topography plot is divided into 6 areas depending on their voltage values.
Expand Down
2 changes: 1 addition & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ makedocs(;
"ERP grid" => "generated/tutorials/erp_grid.md",
"ERP image" => "generated/tutorials/erpimage.md",
"Channel image" => "generated/tutorials/channel_image.md",
"Parallel plot" => "generated/tutorials/parallelcoordinates.md",
"Parallel coordinates" => "generated/tutorials/parallelcoordinates.md",
"Design matrix" => "generated/tutorials/designmatrix.md",
"Circular topoplots" => "generated/tutorials/circ_topo.md",
],
Expand Down
5 changes: 3 additions & 2 deletions src/eeg_series.jl
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,8 @@ function label_management(ax, cat_or_cont_columns, df_single, col)
if cat_or_cont_columns == "cat"
ax.xlabel = string(to_value(df_single)[1, col])
else
ax.xlabel = string(to_value(df_single).cont_cuts[1, :][])
tmp_labels = to_value(df_single).cont_cuts[1, :][]
ax.xlabel = string(tmp_labels)
end
end

Expand Down Expand Up @@ -312,6 +313,6 @@ function data_binning(df; col_y = :erp, fun = mean, grouping = [])
grouping = grouping[.!isnothing.(grouping)]
df_grouped = groupby(df, unique([:cont_cuts, grouping...]))
df_combined = combine(df_grouped, col_y => fun)
rename!(df_combined, names(df_combined)[end] => col_y) # renames estimate_fun to estimate
rename!(df_combined, names(df_combined)[end] => col_y) # renames estimate_fun to estimate
return df_combined
end
2 changes: 1 addition & 1 deletion src/layout_helper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ function apply_layout_settings!(

if (config.layout.show_legend)
if isnothing(fig)
@error "Legend needs figure parameter"
@error "Legend needs `Figure` parameter"
else
# set f[] position depending on legend_position
legend_position =
Expand Down
26 changes: 12 additions & 14 deletions src/plot_butterfly.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ using DataFrames
using TopoPlots
using LinearAlgebra
"""
plot_butterfly(plot_data::DataFrame; kwargs...)
plot_butterfly(plot_data::AbstractMatrix; kwargs...)
plot_butterfly(times::Vector, plot_data::AbstractMatrix; kwargs...)
plot_butterfly!(f::FigLike, plot_data::AbstractMatrix; kwargs...)
plot_butterfly(plot_data::Union{DataFrame, AbstractMatrix}; kwargs...)
plot_butterfly(times::Vector, plot_data::Union{DataFrame, AbstractMatrix}; kwargs...)
plot_butterfly!(f::Union{GridPosition, GridLayout, Figure}, plot_data::Union{DataFrame, AbstractMatrix}; kwargs...)
Plot a Butterfly plot.
Expand All @@ -19,7 +18,7 @@ Plot a Butterfly plot.
Additional styling behavior. \\
Often used as: `plot_butterfly(df; visual = (; colormap = :romaO))`.
## Keyword argumets (kwargs)
## Keyword arguments (kwargs)
- `positions::Array = []` \\
Adds a topoplot as an inset legend to the provided channel positions. Must be the same length as `plot_data`.
To change the colors of the channel lines use the `topoposition_to_color` function.
Expand All @@ -39,18 +38,12 @@ Plot a Butterfly plot.
$(_docstring(:butterfly))
see also [`plot_erp`](@ref erp_vis)
"""
plot_butterfly(plot_data::DataFrame; kwargs...) =
plot_butterfly(plot_data::Union{<:AbstractDataFrame,AbstractMatrix}; kwargs...) =
plot_butterfly!(Figure(), plot_data; kwargs...)

plot_butterfly(plot_data::AbstractMatrix; kwargs...) = plot_butterfly(
eeg_array_to_dataframe(plot_data);
axis = (; xlabel = "Time [samples]"),
kwargs...,
)

function plot_butterfly!(
f::Union{GridPosition,GridLayout,<:Figure},
plot_data::DataFrame;
plot_data::Union{<:AbstractDataFrame,AbstractMatrix};
positions = nothing,
labels = nothing,
topolegend = true,
Expand All @@ -64,12 +57,17 @@ function plot_butterfly!(
mapping = (;),
kwargs...,
)

config = PlotConfig(:butterfly)
config_kwargs!(config; mapping, kwargs...)
plot_data = deepcopy(plot_data) # to avoid change of data in REPL

if isa(plot_data, AbstractMatrix{<:Real})
plot_data = eeg_array_to_dataframe(plot_data)
config_kwargs!(config; axis = (; xlabel = "Time [samples]"))
end
# resolve columns with data
config.mapping = resolve_mappings(plot_data, config.mapping)

#remove mapping values with `nothing`
deleteKeys(nt::NamedTuple{names}, keys) where {names} =
NamedTuple{filter(x -> x ∉ keys, names)}(nt)
Expand Down
Loading

0 comments on commit 7677752

Please sign in to comment.