From 17d3f7fd9d4cf9a7dcea65e346881e345ec1c1f6 Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev Date: Wed, 7 Aug 2024 14:24:00 +0000 Subject: [PATCH 01/35] more generalisation --- src/plot_channelimage.jl | 24 ++++++++++++++++-------- src/plot_erp.jl | 4 ++-- test/test_channelimage.jl | 21 +++++++++++++++++++-- 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/plot_channelimage.jl b/src/plot_channelimage.jl index 4129daca1..e93679c17 100644 --- a/src/plot_channelimage.jl +++ b/src/plot_channelimage.jl @@ -2,7 +2,7 @@ plot_channelimage!(f::Union{GridPosition, GridLayout, Figure}, data::Matrix{<:Real}, position::Vector{Point{2,Float32}}, ch_names::Vector{String}; kwargs...) plot_channelimage(data::Matrix{<:Real}, position::Vector{Point{2,Float32}}, ch_names::Vector{String}; kwargs...) -Channel image +Plot a Channel image ## Arguments @@ -14,6 +14,8 @@ Channel image A vector with EEG layout coordinates. - `ch_names::Vector{String}`\\ Vector with channel names. +- `times::?`\\ + Time range on x-axis. $(_docstring(:channelimage)) @@ -32,30 +34,36 @@ function plot_channelimage!( data::Matrix{<:Real}, position::Vector{Point{2,Float32}}, ch_names::Vector{String}; + times = range(-0.3, 1.2, length = size(data, 2)), kwargs..., ) config = PlotConfig(:channelimage) config_kwargs!(config; kwargs...) + if length(position) != length(ch_names) + error( + "Length of positions and channel names are not equal: $(length(position)) and $(length(ch_names))", + ) + end x = [i[1] for i in position] y = [i[2] for i in position] x = round.(x; digits = 2) - y = Integer.(round.((y .- mean(y)) * 20)) * -1 - x = Integer.(round.((x .- mean(x)) * 20)) - d = zip(x, y, ch_names, 1:20) - a = sort!(DataFrame(d), [:2, :1], rev = [true, false]) + y = Integer.(round.((y .- mean(y)) * length(y))) * -1 + x = Integer.(round.((x .- mean(x)) * length(y))) + d = DataFrame(zip(x, y, ch_names, 1:length(ch_names))) + + a = sort!(d, [:2, :1], rev = [true, false]) b = a[!, :4] c = a[!, :3] c = [string(x) for x in c] - ix = range(-0.3, 1.2, length = size(data, 2)) - iy = 1:20 + iy = 1:length(ch_names) iz = mean(data, dims = 3)[b, :, 1]' gin = f[1, 1] = GridLayout() ax = Axis(gin[1, 1], xlabel = config.axis.xlabel, ylabel = config.axis.ylabel) - hm = Makie.heatmap!(ix, iy, iz, colormap = config.visual.colormap) + hm = Makie.heatmap!(times, iy, iz, colormap = config.visual.colormap) ax.yticks = iy ax.ytickformat = xc -> c ax.yticklabelsize = config.axis.yticklabelsize diff --git a/src/plot_erp.jl b/src/plot_erp.jl index b215832f8..3637d097c 100644 --- a/src/plot_erp.jl +++ b/src/plot_erp.jl @@ -186,7 +186,7 @@ end function topoplot_legend(axis, topomarkersize, unique_val, colors, all_positions) all_positions = unique(all_positions) - topoMatrix = eeg_head_matrix(all_positions, (0.5, 0.5), 0.5) + topo_matrix = eeg_head_matrix(all_positions, (0.5, 0.5), 0.5) un = unique(unique_val) special_colors = @@ -202,7 +202,7 @@ function topoplot_legend(axis, topomarkersize, unique_val, colors, all_positions interpolation = NullInterpolator(), # inteprolator that returns only 0, which is put to white in the special_colorsmap colorrange = (0, length(all_positions)), # add the 0 for the white-first color colormap = special_colors, - head = (color = :black, linewidth = 1, model = topoMatrix), + head = (color = :black, linewidth = 1, model = topo_matrix), label_scatter = (markersize = topomarkersize, strokewidth = 0.5), ) diff --git a/test/test_channelimage.jl b/test/test_channelimage.jl index 26eefc98f..074566c1a 100644 --- a/test/test_channelimage.jl +++ b/test/test_channelimage.jl @@ -1,13 +1,30 @@ dat, pos = TopoPlots.example_data() + dat = dat[:, :, 1] pos = pos[1:30] -@testset "channel image basic" begin +#df, pos = example_data("TopoPlots.jl") + +@testset "Channel image: 3 arguments, data as Matrix" begin plot_channelimage(dat, pos, raw_ch_names;) end -@testset "channel image with Figure" begin +@testset "Channel image: 4 arguments, data as Matrix" begin f = Figure() plot_channelimage!(f, dat, pos, raw_ch_names;) end + +#= @testset "Channel image: 3 arguments, data as DataFrame" begin + plot_channelimage(df, pos, raw_ch_names;) +end =# + +@testset "Channel image: error of unequal length of pos and ch_names" begin + err1 = nothing + t() = error(plot_channelimage(dat, pos[1:10], raw_ch_names;)) + + try + t() + catch err1 + end +end From 6128d128695ffaa407b72ab6936ccc7e9a6a0c52 Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev Date: Thu, 8 Aug 2024 15:23:36 +0000 Subject: [PATCH 02/35] data input and option for sorting methods for channel image --- src/plot_channelimage.jl | 81 ++++++++++++++++++++++++--------------- test/test_channelimage.jl | 51 ++++++++++++++++++++++-- 2 files changed, 99 insertions(+), 33 deletions(-) diff --git a/src/plot_channelimage.jl b/src/plot_channelimage.jl index e93679c17..dee7de163 100644 --- a/src/plot_channelimage.jl +++ b/src/plot_channelimage.jl @@ -1,6 +1,6 @@ """ - plot_channelimage!(f::Union{GridPosition, GridLayout, Figure}, data::Matrix{<:Real}, position::Vector{Point{2,Float32}}, ch_names::Vector{String}; kwargs...) - plot_channelimage(data::Matrix{<:Real}, position::Vector{Point{2,Float32}}, ch_names::Vector{String}; kwargs...) + plot_channelimage!(f::Union{GridPosition, GridLayout, Figure}, data::Matrix{<:Real}, positions::Vector{Point{2,Float32}}, ch_names::Vector{String}; kwargs...) + plot_channelimage(data::Union{DataFrame, AbstractMatrix}, positions::Vector{Point{2,Float32}}, ch_names::Vector{String}; kwargs...) Plot a Channel image @@ -8,14 +8,19 @@ Plot a Channel image - `f::Union{GridPosition, GridLayout, Figure}`\\ `Figure`, `GridLayout`, or `GridPosition` to draw the plot. -- `data::DataFrame`\\ - DataFrame with data. -- `position::Vector{Point{2,Float32}}`\\ +- `data::Union{DataFrame, AbstractMatrix}`\\ + DataFrame or Matrix with data. +- `positions::Vector{Point{2,Float32}}`\\ A vector with EEG layout coordinates. - `ch_names::Vector{String}`\\ Vector with channel names. -- `times::?`\\ +- `times::Vector = range(-0.3, 1.2, length = size(data, 2))`\\ Time range on x-axis. +- `sorting_variables::Vector = [:y, :x]`\\ + Method to sort channels on y-axis.\\ + For instance, you can sort by channel positions on the scalp (x, y) or channel name. +- `sorting_reverse::Vector = [:false, :false]`\\ + Should sorting variables be reversed or not? $(_docstring(:channelimage)) @@ -23,7 +28,7 @@ $(_docstring(:channelimage)) """ plot_channelimage( - data::Matrix{<:Real}, + data::Union{DataFrame,AbstractMatrix}, position::Vector{Point{2,Float32}}, ch_names::Vector{String}; kwargs..., @@ -31,45 +36,61 @@ plot_channelimage( function plot_channelimage!( f::Union{GridPosition,GridLayout,Figure}, - data::Matrix{<:Real}, - position::Vector{Point{2,Float32}}, + data::Union{DataFrame,AbstractMatrix}, + positions::Vector{Point{2,Float32}}, ch_names::Vector{String}; times = range(-0.3, 1.2, length = size(data, 2)), + sorting_variables = [:y, :x], + sorting_reverse = [:false, :false], kwargs..., ) config = PlotConfig(:channelimage) config_kwargs!(config; kwargs...) - if length(position) != length(ch_names) + if length(positions) != length(ch_names) error( - "Length of positions and channel names are not equal: $(length(position)) and $(length(ch_names))", + "Length of positions and channel names are not equal: $(length(positions)) and $(length(ch_names))", + ) + end + if size(data, 1) != length(positions) + error( + "Number of data rows and positions length are not equal: $(size(data, 1)) and $(length(positions))", + ) + end + if length(sorting_variables) != length(sorting_reverse) + error( + "Length of sorting_variables and sorting_reverse are not equal: $(length(sorting_variables)) and $(length(sorting_reverse))", ) end - x = [i[1] for i in position] - y = [i[2] for i in position] + x = [i[1] for i in positions] + y = [i[2] for i in positions] - x = round.(x; digits = 2) - y = Integer.(round.((y .- mean(y)) * length(y))) * -1 - x = Integer.(round.((x .- mean(x)) * length(y))) - d = DataFrame(zip(x, y, ch_names, 1:length(ch_names))) + sorted_data = + DataFrame(:x => x, :y => y, :ch_names => ch_names, :index => 1:length(ch_names)) - a = sort!(d, [:2, :1], rev = [true, false]) - b = a[!, :4] - c = a[!, :3] - c = [string(x) for x in c] + sort!(sorted_data, sorting_variables, rev = sorting_reverse) + sorted_names = sorted_data[!, :ch_names] + sorted_names = [string(x) for x in sorted_names] + sorted_indecies = sorted_data[!, :index] - iy = 1:length(ch_names) - iz = mean(data, dims = 3)[b, :, 1]' + if typeof(data) == DataFrame + data = Matrix(data) + end + iz = mean(data, dims = 3)[sorted_indecies, :, 1]' #how it could be 3 dimensions if my data is 2D? - gin = f[1, 1] = GridLayout() - ax = Axis(gin[1, 1], xlabel = config.axis.xlabel, ylabel = config.axis.ylabel) - hm = Makie.heatmap!(times, iy, iz, colormap = config.visual.colormap) - ax.yticks = iy - ax.ytickformat = xc -> c - ax.yticklabelsize = config.axis.yticklabelsize + gl = f[1, 1] = GridLayout() + ax = Axis( + gl[1, 1], + xlabel = config.axis.xlabel, + ylabel = config.axis.ylabel, + yticks = 1:length(ch_names), + ytickformat = xc -> sorted_names, + yticklabelsize = config.axis.yticklabelsize, + ) + hm = Makie.heatmap!(times, 1:length(ch_names), iz, colormap = config.visual.colormap) Makie.Colorbar( - gin[1, 2], + gl[1, 2], hm, label = config.colorbar.label, labelrotation = config.colorbar.labelrotation, diff --git a/test/test_channelimage.jl b/test/test_channelimage.jl index 074566c1a..57f11e655 100644 --- a/test/test_channelimage.jl +++ b/test/test_channelimage.jl @@ -3,6 +3,8 @@ dat, pos = TopoPlots.example_data() dat = dat[:, :, 1] pos = pos[1:30] +df, pos2 = example_data("TopoPlots.jl") +Matrix(df2) #df, pos = example_data("TopoPlots.jl") @testset "Channel image: 3 arguments, data as Matrix" begin @@ -15,9 +17,13 @@ end end -#= @testset "Channel image: 3 arguments, data as DataFrame" begin - plot_channelimage(df, pos, raw_ch_names;) -end =# +@testset "Channel image: 3 arguments, data as DataFrame" begin + f = Figure(size = (400, 800)) + array = [string(i) for i = 1:64] + df2 = unstack(df[:, [:estimate, :time, :channel]], :channel, :time, :estimate) + select!(df2, Not(:channel)) + plot_channelimage!(f, df2, pos2, array;) +end @testset "Channel image: error of unequal length of pos and ch_names" begin err1 = nothing @@ -28,3 +34,42 @@ end =# catch err1 end end + +@testset "Channel image: sorting by y" begin + plot_channelimage( + dat, + pos, + raw_ch_names; + sorting_variables = [:y], + sorting_reverse = [:true], + ) +end + +@testset "Channel image: sorting by ch_names" begin + plot_channelimage( + dat, + pos, + raw_ch_names; + sorting_variables = [:ch_names], + sorting_reverse = [:true], + ) +end + +@testset "Channel image: error of unequal sorting_variables and sorting_reverse" begin + err1 = nothing + t() = error(plot_channelimage(dat, pos, raw_ch_names; sorting_variables = [:y])) + try + t() + catch err1 + end +end + +@testset "Channel image: error of unequal data and sorting_reverse" begin + err1 = nothing + t() = + error(plot_channelimage(dat[:, 1:100], pos, raw_ch_names; sorting_variables = [:y])) + try + t() + catch err1 + end +end From 371357d7effc6e5cebc59d1f970036e55f614005 Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev Date: Thu, 8 Aug 2024 15:41:33 +0000 Subject: [PATCH 03/35] bug --- test/test_channelimage.jl | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/test/test_channelimage.jl b/test/test_channelimage.jl index 57f11e655..ebd61f489 100644 --- a/test/test_channelimage.jl +++ b/test/test_channelimage.jl @@ -4,16 +4,15 @@ dat = dat[:, :, 1] pos = pos[1:30] df, pos2 = example_data("TopoPlots.jl") -Matrix(df2) -#df, pos = example_data("TopoPlots.jl") + @testset "Channel image: 3 arguments, data as Matrix" begin - plot_channelimage(dat, pos, raw_ch_names;) + plot_channelimage(dat[1:30, :], pos, raw_ch_names;) end @testset "Channel image: 4 arguments, data as Matrix" begin f = Figure() - plot_channelimage!(f, dat, pos, raw_ch_names;) + plot_channelimage!(f, dat[1:30, :], pos, raw_ch_names;) end @@ -27,7 +26,7 @@ end @testset "Channel image: error of unequal length of pos and ch_names" begin err1 = nothing - t() = error(plot_channelimage(dat, pos[1:10], raw_ch_names;)) + t() = error(plot_channelimage(dat[1:30, :], pos[1:10], raw_ch_names;)) try t() @@ -37,7 +36,7 @@ end @testset "Channel image: sorting by y" begin plot_channelimage( - dat, + dat[1:30, :], pos, raw_ch_names; sorting_variables = [:y], @@ -47,7 +46,7 @@ end @testset "Channel image: sorting by ch_names" begin plot_channelimage( - dat, + dat[1:30, :], pos, raw_ch_names; sorting_variables = [:ch_names], @@ -57,7 +56,8 @@ end @testset "Channel image: error of unequal sorting_variables and sorting_reverse" begin err1 = nothing - t() = error(plot_channelimage(dat, pos, raw_ch_names; sorting_variables = [:y])) + t() = + error(plot_channelimage(dat[1:30, :], pos, raw_ch_names; sorting_variables = [:y])) try t() catch err1 @@ -66,8 +66,7 @@ end @testset "Channel image: error of unequal data and sorting_reverse" begin err1 = nothing - t() = - error(plot_channelimage(dat[:, 1:100], pos, raw_ch_names; sorting_variables = [:y])) + t() = error(plot_channelimage(dat, pos, raw_ch_names; sorting_variables = [:y])) try t() catch err1 From d4a37553f4d70d6b186d214837e63f477239066d Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev Date: Thu, 8 Aug 2024 16:04:32 +0000 Subject: [PATCH 04/35] bug2 --- docs/literate/how_to/mult_vis_in_fig.jl | 2 +- docs/literate/tutorials/channel_image.jl | 2 +- test/test_complexplots.jl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/literate/how_to/mult_vis_in_fig.jl b/docs/literate/how_to/mult_vis_in_fig.jl index b9b0d57f7..079339dc0 100644 --- a/docs/literate/how_to/mult_vis_in_fig.jl +++ b/docs/literate/how_to/mult_vis_in_fig.jl @@ -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 diff --git a/docs/literate/tutorials/channel_image.jl b/docs/literate/tutorials/channel_image.jl index d4a001b80..6fb5635f1 100644 --- a/docs/literate/tutorials/channel_image.jl +++ b/docs/literate/tutorials/channel_image.jl @@ -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 diff --git a/test/test_complexplots.jl b/test/test_complexplots.jl index aa3b3ca0b..ba6e09b85 100644 --- a/test/test_complexplots.jl +++ b/test/test_complexplots.jl @@ -69,7 +69,7 @@ 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 From 4695ddb75eb876796237fe9213bf4b08203ad5de Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev Date: Fri, 9 Aug 2024 12:47:18 +0000 Subject: [PATCH 05/35] data input for erpgrid --- src/plot_channelimage.jl | 3 +- src/plot_erpgrid.jl | 21 ++++++++----- test/test_erpgrid.jl | 12 ++++++-- test_data_input.jl | 65 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 11 deletions(-) create mode 100644 test_data_input.jl diff --git a/src/plot_channelimage.jl b/src/plot_channelimage.jl index dee7de163..2afc193fe 100644 --- a/src/plot_channelimage.jl +++ b/src/plot_channelimage.jl @@ -9,7 +9,8 @@ Plot a Channel image - `f::Union{GridPosition, GridLayout, Figure}`\\ `Figure`, `GridLayout`, or `GridPosition` to draw the plot. - `data::Union{DataFrame, AbstractMatrix}`\\ - DataFrame or Matrix with data. + DataFrame or Matrix with data.\\ + Data should has a format of 1 row - 1 channel. - `positions::Vector{Point{2,Float32}}`\\ A vector with EEG layout coordinates. - `ch_names::Vector{String}`\\ diff --git a/src/plot_erpgrid.jl b/src/plot_erpgrid.jl index 1bdd75b69..070b45acb 100644 --- a/src/plot_erpgrid.jl +++ b/src/plot_erpgrid.jl @@ -1,13 +1,14 @@ """ - plot_erpgrid!(f::Union{GridPosition, GridLayout, Figure}, data::Matrix{<:Real}, pos::Vector{Point{2,Float}}; kwargs...) - plot_erpgrid(data::Matrix{<:Real}, pos::Vector{Point{2,Float}}; kwargs...) + plot_erpgrid(data::Union{Matrix{<:Real}, DataFrame}, pos::Vector; kwargs...) + plot_erpgrid!(f::Union{GridPosition, GridLayout, Figure}, data::Union{Matrix{<:Real}, DataFrame}, pos::Vector; kwargs...) Plot an ERP image. ## Arguments - `f::Union{GridPosition, GridLayout, Figure}`\\ `Figure`, `GridLayout`, or `GridPosition` to draw the plot. -- `data::Matrix{<:Real}`\\ - Data for the plot visualization. +- `data::Union{Matrix{<:Real}, DataFrame}`\\ + Data for the plot visualization.\\ + Data should has a format of 1 row - 1 channel. - `pos::Vector{Point{2,Float}}` \\ Electrode positions. @@ -21,13 +22,13 @@ $(_docstring(:erpgrid)) **Return Value:** `Figure` displaying ERP grid. """ -plot_erpgrid(data::Matrix{<:Real}, pos; kwargs...) = +plot_erpgrid(data::Union{Matrix{<:Real},DataFrame}, pos; kwargs...) = plot_erpgrid!(Figure(), data, pos; kwargs...) function plot_erpgrid!( f::Union{GridPosition,GridLayout,Figure}, - data::Matrix{<:Real}, - pos; + data::Union{Matrix{<:Real},DataFrame}, + pos::Vector; drawlabels = false, times = -1:size(data, 2)-2, #arbitrary strat just for fun kwargs..., @@ -35,6 +36,10 @@ function plot_erpgrid!( config = PlotConfig(:erpgrid) config_kwargs!(config; kwargs...) + if typeof(data) == DataFrame #maybe better would be put it into signature + data = Matrix(data) + end + chan_num = size(data, 1) data = data[1:chan_num, :] pos = hcat([[p[1], p[2]] for p in pos]...) @@ -47,7 +52,7 @@ function plot_erpgrid!( rel_zeropoint = argmin(abs.(times)) ./ length(times) for (ix, p) in enumerate(eachcol(pos)) - x = p[1] #- 0.1 + x = p[1] #- 0.1 #some padding needed y = p[2] #- 0.1 # todo: 0.1 should go into plot config ax = Axis( diff --git a/test/test_erpgrid.jl b/test/test_erpgrid.jl index 1dc8cccf4..12c29d5ab 100644 --- a/test/test_erpgrid.jl +++ b/test/test_erpgrid.jl @@ -1,12 +1,20 @@ data, pos = TopoPlots.example_data() data = data[:, :, 1] +df, pos2 = example_data("TopoPlots.jl") + @testset "basic erpgrid: one plot is out of the border" begin - plot_erpgrid(data[1:3, 1:20], pos) + plot_erpgrid(data[1:3, :], pos) end @testset "basic erpgrid" begin - plot_erpgrid(data[1:6, 1:20], pos) + plot_erpgrid(data[1:6, :], pos) +end + +@testset "erpgrid: Data input with DataFrame" begin + df2 = unstack(df[:, [:estimate, :time, :channel]], :channel, :time, :estimate) + select!(df2, Not(:channel)) + plot_erpgrid(df2, pos) end @testset "erpgrid with GridPosition" begin diff --git a/test_data_input.jl b/test_data_input.jl new file mode 100644 index 000000000..430c1b67d --- /dev/null +++ b/test_data_input.jl @@ -0,0 +1,65 @@ +include("../docs/example_data.jl") +df, pos = example_data("TopoPlots.jl") +dat, positions = TopoPlots.example_data() + +@testset "ERP plot: Matrix data" begin + plot_erp(dat[1, :, 1:2]') +end + +@testset "ERP plot: Array data" begin + plot_erp(dat[1, :, 1]) +end + +@testset "butterfly: Matrix as data input" begin + tmp = DataFrame(channel = df.channel, estimate = df.estimate) + grouped = groupby(tmp, :channel) + mat = Matrix(reduce(hcat, [group.estimate for group in grouped])') + plot_butterfly(mat; positions = pos) +end + + +@testset "topoplot: GridSubposition" begin + f = Figure() + data_for_topoplot = UnfoldMakie.eeg_array_to_dataframe(rand(10)') + plot_topoplot!( + f[1, 1][1, 1], + data_for_topoplot; + positions = rand(Point2f, 10), labels = string.(1:10), + ) + f +end + +@testset "toposeries: GridPosition with a title" begin + f = Figure() + ax = Axis(f[1:2, 1:5], aspect = DataAspect(), title = "Just a title") + df = UnfoldMakie.eeg_array_to_dataframe(dat[:, :, 1], string.(1:length(positions))) + + bin_width = 80 + a = plot_topoplotseries!( + f[1:2, 1:5], + df; + bin_width, + positions = positions, + layout = (; use_colorbar = true), + ) + hidespines!(ax) + hidedecorations!(ax, label = false) + + f +end + +@testset "14 topoplots, 4 rows" begin # horrific + df = UnfoldMakie.eeg_array_to_dataframe(dat[:, :, 1], string.(1:length(positions))) + plot_topoplotseries( + df; + bin_num = 14, + nrows = 4, + positions = positions, + visual = (; label_scatter = false), + ) +end + + +@testset "eeg_array_to_dataframe" begin + eeg_array_to_dataframe(rand(2, 2)) +end \ No newline at end of file From 9b89ec622c40c72b44b207f822a053158fbb1c2f Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev <33777074+vladdez@users.noreply.github.com> Date: Fri, 9 Aug 2024 12:54:53 +0000 Subject: [PATCH 06/35] Delete test_data_input.jl --- test_data_input.jl | 65 ---------------------------------------------- 1 file changed, 65 deletions(-) delete mode 100644 test_data_input.jl diff --git a/test_data_input.jl b/test_data_input.jl deleted file mode 100644 index 430c1b67d..000000000 --- a/test_data_input.jl +++ /dev/null @@ -1,65 +0,0 @@ -include("../docs/example_data.jl") -df, pos = example_data("TopoPlots.jl") -dat, positions = TopoPlots.example_data() - -@testset "ERP plot: Matrix data" begin - plot_erp(dat[1, :, 1:2]') -end - -@testset "ERP plot: Array data" begin - plot_erp(dat[1, :, 1]) -end - -@testset "butterfly: Matrix as data input" begin - tmp = DataFrame(channel = df.channel, estimate = df.estimate) - grouped = groupby(tmp, :channel) - mat = Matrix(reduce(hcat, [group.estimate for group in grouped])') - plot_butterfly(mat; positions = pos) -end - - -@testset "topoplot: GridSubposition" begin - f = Figure() - data_for_topoplot = UnfoldMakie.eeg_array_to_dataframe(rand(10)') - plot_topoplot!( - f[1, 1][1, 1], - data_for_topoplot; - positions = rand(Point2f, 10), labels = string.(1:10), - ) - f -end - -@testset "toposeries: GridPosition with a title" begin - f = Figure() - ax = Axis(f[1:2, 1:5], aspect = DataAspect(), title = "Just a title") - df = UnfoldMakie.eeg_array_to_dataframe(dat[:, :, 1], string.(1:length(positions))) - - bin_width = 80 - a = plot_topoplotseries!( - f[1:2, 1:5], - df; - bin_width, - positions = positions, - layout = (; use_colorbar = true), - ) - hidespines!(ax) - hidedecorations!(ax, label = false) - - f -end - -@testset "14 topoplots, 4 rows" begin # horrific - df = UnfoldMakie.eeg_array_to_dataframe(dat[:, :, 1], string.(1:length(positions))) - plot_topoplotseries( - df; - bin_num = 14, - nrows = 4, - positions = positions, - visual = (; label_scatter = false), - ) -end - - -@testset "eeg_array_to_dataframe" begin - eeg_array_to_dataframe(rand(2, 2)) -end \ No newline at end of file From dd536b3b3e69ec66a7bc43145f2a971ddc44b0a3 Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev Date: Mon, 12 Aug 2024 11:22:06 +0000 Subject: [PATCH 07/35] erp grid with channel image and more checking tests --- src/plot_erpgrid.jl | 70 +++++++++++++++++++++++++++----------------- test/runtests.jl | 4 +++ test/test_erpgrid.jl | 43 ++++++++++++++++++++++----- 3 files changed, 82 insertions(+), 35 deletions(-) diff --git a/src/plot_erpgrid.jl b/src/plot_erpgrid.jl index 070b45acb..b370b21e1 100644 --- a/src/plot_erpgrid.jl +++ b/src/plot_erpgrid.jl @@ -1,6 +1,6 @@ """ - plot_erpgrid(data::Union{Matrix{<:Real}, DataFrame}, pos::Vector; kwargs...) - plot_erpgrid!(f::Union{GridPosition, GridLayout, Figure}, data::Union{Matrix{<:Real}, DataFrame}, pos::Vector; kwargs...) + plot_erpgrid(data::Union{Matrix{<:Real}, DataFrame}, positions::Vector; kwargs...) + plot_erpgrid!(f::Union{GridPosition, GridLayout, Figure}, data::Union{Matrix{<:Real}, DataFrame}, positions::Vector; kwargs...) Plot an ERP image. ## Arguments @@ -9,8 +9,10 @@ Plot an ERP image. - `data::Union{Matrix{<:Real}, DataFrame}`\\ Data for the plot visualization.\\ Data should has a format of 1 row - 1 channel. -- `pos::Vector{Point{2,Float}}` \\ +- `positions::Vector{Point{2,Float}}` \\ Electrode positions. +- `ch_names::Vector{String}`\\ + Vector with channel names. ## Keyword argumets (kwargs) - `drawlabels::Bool = false`\\ @@ -22,46 +24,64 @@ $(_docstring(:erpgrid)) **Return Value:** `Figure` displaying ERP grid. """ -plot_erpgrid(data::Union{Matrix{<:Real},DataFrame}, pos; kwargs...) = - plot_erpgrid!(Figure(), data, pos; kwargs...) +plot_erpgrid( + data::Union{Matrix{<:Real},DataFrame}, + positions::Vector, + ch_names::Vector{String}; + kwargs..., +) = plot_erpgrid!(Figure(), data, positions, ch_names::Vector{String}; kwargs...) + +plot_erpgrid!( + f::Union{GridPosition,GridLayout,Figure}, + data::Union{Matrix{<:Real},DataFrame}, + positions; + kwargs..., +) = plot_erpgrid!(f, data, positions, string.(1:length(positions)); kwargs...) + +plot_erpgrid(data::Union{Matrix{<:Real},DataFrame}, positions; kwargs...) = + plot_erpgrid!(Figure(), data, positions, string.(1:length(positions)); kwargs...) function plot_erpgrid!( f::Union{GridPosition,GridLayout,Figure}, data::Union{Matrix{<:Real},DataFrame}, - pos::Vector; + positions::Vector, + ch_names::Vector{String}; drawlabels = false, - times = -1:size(data, 2)-2, #arbitrary strat just for fun + times = -1:size(data, 2)-2, #arbitrary kwargs..., ) config = PlotConfig(:erpgrid) config_kwargs!(config; kwargs...) - if typeof(data) == DataFrame #maybe better would be put it into signature + if typeof(data) == DataFrame #maybe better would be put it into signature? data = Matrix(data) end - - chan_num = size(data, 1) - data = data[1:chan_num, :] - pos = hcat([[p[1], p[2]] for p in pos]...) - - pos = pos[:, 1:chan_num] - minmaxrange = (maximum(pos, dims = 2) - minimum(pos, dims = 2)) - pos = (pos .- mean(pos, dims = 2)) ./ minmaxrange .+ 0.5 + if length(positions) != length(ch_names) + error( + "Length of positions and channel names are not equal: $(length(positions)) and $(length(ch_names))", + ) + end + if size(data, 1) != length(positions) + error( + "Number of data rows and positions length are not equal: $(size(data, 1)) and $(length(positions))", + ) + end + positions = hcat([[p[1], p[2]] for p in positions]...) + minmaxrange = (maximum(positions, dims = 2) - minimum(positions, dims = 2)) #should be different for x and y + positions = (positions .- mean(positions, dims = 2)) ./ minmaxrange .+ 0.5 axlist = [] rel_zeropoint = argmin(abs.(times)) ./ length(times) - - for (ix, p) in enumerate(eachcol(pos)) - x = p[1] #- 0.1 #some padding needed - y = p[2] #- 0.1 - # todo: 0.1 should go into plot config + for (ix, p) in enumerate(eachcol(positions)) + x = p[1] + y = p[2] ax = Axis( f[1, 1], width = Relative(0.2), height = Relative(0.2), halign = x, valign = y, - )# title = raw_ch_names[1:30]) + ) if drawlabels text!( ax, @@ -69,7 +89,7 @@ function plot_erpgrid!( 1, color = :gray, fontsize = 12, - text = string.(ix), + text = ch_names[ix], align = (:left, :top), space = :relative, ) @@ -108,9 +128,5 @@ function plot_erpgrid!( rotation = π / 2, fontsize = 12, ) - # testing - #ax0 = Axis(f[1, 1], backgroundcolor=:green)# - #hidespines!(ax0) - #hidedecorations!(ax0) f end diff --git a/test/runtests.jl b/test/runtests.jl index e241a6d0c..4a8364163 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -38,6 +38,10 @@ end include("test_toposeries2.jl") end +@testset "ERP grid" begin + include("test_erpgrid.jl") +end + @testset "Parallel coordinates plot" begin include("test_pcp.jl") end diff --git a/test/test_erpgrid.jl b/test/test_erpgrid.jl index 12c29d5ab..a7caf4fbd 100644 --- a/test/test_erpgrid.jl +++ b/test/test_erpgrid.jl @@ -3,33 +3,41 @@ data = data[:, :, 1] df, pos2 = example_data("TopoPlots.jl") -@testset "basic erpgrid: one plot is out of the border" begin - plot_erpgrid(data[1:3, :], pos) +@testset "erpgrid: one plot is out of the border" begin + plot_erpgrid(data[1:3, :], pos[1:3]) end -@testset "basic erpgrid" begin - plot_erpgrid(data[1:6, :], pos) +@testset "erpgrid: data input with Matrix" begin + plot_erpgrid(data[1:6, :], pos[1:6]) end -@testset "erpgrid: Data input with DataFrame" begin +@testset "erpgrid: data input with DataFrame" begin df2 = unstack(df[:, [:estimate, :time, :channel]], :channel, :time, :estimate) select!(df2, Not(:channel)) plot_erpgrid(df2, pos) end -@testset "erpgrid with GridPosition" begin +@testset "erpgrid: drawlabels" begin + plot_erpgrid(data, pos; drawlabels = true) +end + +@testset "erpgrid: drawlabels with user_defined channel names" begin + plot_erpgrid(data[1:6, :], pos[1:6], raw_ch_names[1:6]; drawlabels = true) +end + +@testset "erpgrid: GridPosition" begin f = Figure() plot_erpgrid!(f[1, 1], data, pos) f end -@testset "erpgrid change labels of legend" begin +@testset "erpgrid: change x and y labels" begin f = Figure() plot_erpgrid!(f[1, 1], data, pos; axis = (; xlabel = "s", ylabel = "µV")) f end -@testset "erpgrid plot in GridLayout" begin +@testset "erpgrid: GridLayout" begin f = Figure(size = (1200, 1400)) ga = f[1, 1] = GridLayout() gb = f[2, 1] = GridLayout() @@ -49,3 +57,22 @@ end end f end + + +@testset "erpgrid: error of unequal data and positions" begin + err1 = nothing + t() = error(plot_erpgrid(data[1:6, :], pos[1:7], raw_ch_names[1:6]; drawlabels = true)) + try + t() + catch err1 + end +end + +@testset "erpgrid: error of unequal ch_names and positions" begin + err1 = nothing + t() = error(plot_erpgrid(data[1:6, :], pos[1:6], raw_ch_names[1:7]; drawlabels = true)) + try + t() + catch err1 + end +end From 5e5d1f5221a0f2a134f7eddea38253de765f759a Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev <33777074+vladdez@users.noreply.github.com> Date: Mon, 12 Aug 2024 12:39:38 +0000 Subject: [PATCH 08/35] Update test/runtests.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- test/runtests.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index 4a8364163..15db1fa7e 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -40,7 +40,7 @@ end @testset "ERP grid" begin include("test_erpgrid.jl") -end +end @testset "Parallel coordinates plot" begin include("test_pcp.jl") From cae029ecb8010ad67906e186c0530a368f7eac9b Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev Date: Mon, 12 Aug 2024 14:03:00 +0000 Subject: [PATCH 09/35] data input for pcp and some docs --- .../literate/tutorials/parallelcoordinates.jl | 12 ++++--- docs/make.jl | 2 +- src/layout_helper.jl | 2 +- src/plot_erpgrid.jl | 2 +- src/plot_parallelcoordinates.jl | 25 ++++++++------- src/plotconfig.jl | 2 +- test/test_pcp.jl | 31 +++++++++++++++---- 7 files changed, 50 insertions(+), 26 deletions(-) diff --git a/docs/literate/tutorials/parallelcoordinates.jl b/docs/literate/tutorials/parallelcoordinates.jl index ac5bfd0df..a8bba8703 100644 --- a/docs/literate/tutorials/parallelcoordinates.jl +++ b/docs/literate/tutorials/parallelcoordinates.jl @@ -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 @@ -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 @@ -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() diff --git a/docs/make.jl b/docs/make.jl index a5d037d04..43a140fe4 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -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", ], diff --git a/src/layout_helper.jl b/src/layout_helper.jl index 6efff5331..628bf8267 100644 --- a/src/layout_helper.jl +++ b/src/layout_helper.jl @@ -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 = diff --git a/src/plot_erpgrid.jl b/src/plot_erpgrid.jl index b370b21e1..62533fe90 100644 --- a/src/plot_erpgrid.jl +++ b/src/plot_erpgrid.jl @@ -1,6 +1,6 @@ """ plot_erpgrid(data::Union{Matrix{<:Real}, DataFrame}, positions::Vector; kwargs...) - plot_erpgrid!(f::Union{GridPosition, GridLayout, Figure}, data::Union{Matrix{<:Real}, DataFrame}, positions::Vector; kwargs...) + plot_erpgrid!(f::Union{GridPosition, GridLayout, Figure}, data::Union{Matrix{<:Real}, DataFrame}, positions::Vector, ch_names::Vector{String}; kwargs...) Plot an ERP image. ## Arguments diff --git a/src/plot_parallelcoordinates.jl b/src/plot_parallelcoordinates.jl index e5323f2b6..b3eb7080f 100644 --- a/src/plot_parallelcoordinates.jl +++ b/src/plot_parallelcoordinates.jl @@ -1,14 +1,17 @@ """ - plot_parallelcoordinates(f::Union{GridPosition, GridLayout, Figure}, data::DataFrame; kwargs) - -Plot a PCP (parallel coordinates plot). + plot_parallelcoordinates(data::Union{DataFrame, AbstractMatrix}; kwargs...) + plot_parallelcoordinates!(f::Union{GridPosition, GridLayout, Figure}, data::Union{DataFrame, AbstractMatrix}; kwargs) + +Plot a PCP (parallel coordinates plot).\\ +Dimensions: conditions, channels, time, trials. + ## Arguments: - `f::Union{GridPosition, GridLayout, Figure}` `Figure`, `GridLayout`, or `GridPosition` to draw the plot. -- `data::Union{DataFrame, Vector{Float32}}`\\ +- `data::Union{DataFrame, AbstractMatrix}`\\ Data for the plot visualization. ## Keyword argumets (kwargs) @@ -41,18 +44,21 @@ $(_docstring(:paracoord)) **Return Value:** `Figure` displaying the Parallel coordinates plot. """ -plot_parallelcoordinates(data::DataFrame; kwargs...) = +plot_parallelcoordinates(data::Union{DataFrame,AbstractMatrix}; kwargs...) = plot_parallelcoordinates(Figure(), data; kwargs...) function plot_parallelcoordinates( f, - data::DataFrame; + data::Union{DataFrame,AbstractMatrix}; ax_ticklabels = :outmost, ax_labels = nothing, normalize = nothing, bend = false, kwargs..., ) + if typeof(data) == Matrix{Float64} + data = eeg_array_to_dataframe(data) + end config = PlotConfig(:paracoord) UnfoldMakie.config_kwargs!(config; kwargs...) @@ -132,7 +138,7 @@ function parallelcoordinates( alpha = 0.3, bend = false, ) - @assert size(data, 2) > 1 "currently more than one line has to be plotted for parallel plot to work" + @assert size(data, 2) > 1 "Currently, for parallel plotting to work, more than one line must be plotted" if isa(color, AbstractVector) @assert size(data, 2) == length(color) end @@ -185,7 +191,7 @@ function parallelcoordinates( color_ix = [findfirst(un_c .== c) for c in color] #@assert length(un_c) == 1 "Only single color found, please don't specify color, " if length(un_c) == 1 - @warn "The only a single unique value found in the specified color vector" + @warn "Only single unique value found in the specified color vector" color = cgrad(colormap, 2)[color_ix] else color = cgrad(colormap, length(un_c))[color_ix] @@ -219,7 +225,6 @@ function parallelcoordinates( hidespines!(ax) hidedecorations!(ax) - # get some defaults - necessary for LinkAxis def = Makie.default_attribute_values(Axis, nothing) axesOptions = (; @@ -234,7 +239,6 @@ function parallelcoordinates( minorticks = def[:yminorticks], ) - # generate the overlay parallel axes axlist = Makie.LineAxis[] for i in eachindex(x_pos) @@ -359,6 +363,5 @@ function Makie.get_ticks(ticks::PCPTicks, scale, formatter, vmin, vmax) ticklabels[1] = "~" * ticklabels[1] ticklabels[end] = "~" * ticklabels[end] end - #@debug tickvalues,ticklabels return tickvalues, ticklabels end diff --git a/src/plotconfig.jl b/src/plotconfig.jl index aad332b66..7d895a44f 100644 --- a/src/plotconfig.jl +++ b/src/plotconfig.jl @@ -291,7 +291,7 @@ function PlotConfig(T::Val{:paracoord}) color = :black, # default linecolor alpha = 0.3, ), - axis = (; ylabel = "Time", title = ""), + axis = (; xlabel = "Channels", ylabel = "Time", title = ""), legend = (; title = "Conditions", merge = true, framevisible = false), # fontsize = 14), mapping = (; x = :channel), ) diff --git a/test/test_pcp.jl b/test/test_pcp.jl index e66916f48..84a3063b8 100644 --- a/test/test_pcp.jl +++ b/test/test_pcp.jl @@ -1,15 +1,34 @@ -include("../docs/example_data.jl") +include("../docs/example_data.jl") # we need more specified example data results_plot, positions = example_data() -@testset "PCP with Figure, 64 channels, 1 condition" begin +@testset "PCP: data input DataFrame" begin + plot_parallelcoordinates(results_plot) +end + +@testset "PCP: data input Matrix" begin + tmp = DataFrame(channel = results_plot.channel, estimate = results_plot.estimate) + grouped = groupby(tmp, :channel) + mat = Matrix(reduce(hcat, [group.estimate for group in grouped])') + plot_parallelcoordinates(mat) +end + +@testset "PCP: Figure, 64 channels, 1 condition" begin plot_parallelcoordinates(results_plot; mapping = (color = :coefname, y = :estimate)) end -@testset "PCP with Figure, 5 channels (filtered), 1 condition" begin +@testset "PCP: Figure, 64 channels, 1 condition, bigger size" begin + plot_parallelcoordinates( + Figure(size = (1200, 800)), + results_plot; + mapping = (color = :coefname, y = :estimate), + ) +end + +@testset "PCP: Figure, 5 channels (filtered), 1 condition" begin results_plot2 = filter(row -> row.channel <= 5, results_plot) # select channels plot_parallelcoordinates(results_plot2; mapping = (color = :coefname, y = :estimate)) end -@testset "PCP with Figure, 5 channels (subsetted), 1 condition" begin +@testset "PCP: Figure, 5 channels (subsetted), 1 condition" begin plot_parallelcoordinates( subset(results_plot, :channel => x -> x .<= 5); mapping = (; color = :coefname), @@ -37,7 +56,7 @@ end f end -@testset "PCP with GridPosition" begin +@testset "PCP: GridPosition" begin f = Figure() plot_parallelcoordinates( f[1, 1], @@ -47,7 +66,7 @@ end f end -@testset "PCP with 3 conditions and 5 channels" begin +@testset "PCP: 3 conditions and 5 channels" begin uf_5chan = example_data("UnfoldLinearModelMultiChannel") plot_parallelcoordinates( uf_5chan; From afbd83d76bf27234661c81c61f967e3baf3883f0 Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev Date: Mon, 12 Aug 2024 15:39:14 +0000 Subject: [PATCH 10/35] issue 227 --- docs/literate/how_to/mult_vis_in_fig.jl | 4 +-- docs/literate/tutorials/topoplot.jl | 6 ++-- src/plot_topoplot.jl | 18 ++++++---- test/test_complexplots.jl | 11 ++---- test/test_topoplot.jl | 46 ++++++++++++++----------- 5 files changed, 45 insertions(+), 40 deletions(-) diff --git a/docs/literate/how_to/mult_vis_in_fig.jl b/docs/literate/how_to/mult_vis_in_fig.jl index 079339dc0..849ab9512 100644 --- a/docs/literate/how_to/mult_vis_in_fig.jl +++ b/docs/literate/how_to/mult_vis_in_fig.jl @@ -80,7 +80,7 @@ plot_erp!( plot_designmatrix!(f[2, 3], designmatrix(uf)) -plot_topoplot!(f[3, 1], data[:, 150, 1]; positions = positions) +plot_topoplot!(f[3, 1], data[:, 150, 1], positions) plot_topoplotseries!( f[4, 1:3], d_topo; @@ -162,7 +162,7 @@ plot_butterfly!( ) hlines!(0, color = :gray, linewidth = 1) vlines!(0, color = :gray, linewidth = 1) -plot_topoplot!(gc, data[:, 340, 1]; positions = positions, axis = (; xlabel = "[340 ms]")) +plot_topoplot!(gc, data[:, 340, 1], positions; axis = (; xlabel = "[340 ms]")) plot_topoplotseries!( gd, diff --git a/docs/literate/tutorials/topoplot.jl b/docs/literate/tutorials/topoplot.jl index 88f625a26..7d96331ad 100644 --- a/docs/literate/tutorials/topoplot.jl +++ b/docs/literate/tutorials/topoplot.jl @@ -73,7 +73,8 @@ f = Figure(size = (500, 500)) labs4 = ["O1", "F2", "F3", "P4"] plot_topoplot!( f[1, 1], - data[1:4, 340, 1]; + data[1:4, 340, 1], + positions; visual = (; label_scatter = false), labels = labs4, axis = (; title = "no channel scatter"), @@ -81,7 +82,8 @@ plot_topoplot!( plot_topoplot!( f[1, 2], - data[1:4, 340, 1]; + data[1:4, 340, 1], + positions; visual = (; label_text = true, label_scatter = (markersize = 15, strokewidth = 2)), labels = labs4, axis = (; title = "channel scatter with text"), diff --git a/src/plot_topoplot.jl b/src/plot_topoplot.jl index 86000fd55..cc1a0d768 100644 --- a/src/plot_topoplot.jl +++ b/src/plot_topoplot.jl @@ -1,6 +1,6 @@ """ - plot_topoplot!(f::Union{GridPosition, GridLayout, Figure}, data, ; positions = nothing, labels = nothing, kwargs...) - plot_topoplot(data; positions = nothing, labels = nothing, kwargs...) + plot_topoplot!(f::Union{GridPosition, GridLayout, Figure}, data, positions::Vector; labels = nothing, kwargs...) + plot_topoplot(data, position::Vector; labels = nothing, kwargs...) Plot a topoplot. ## Arguments @@ -8,7 +8,7 @@ Plot a topoplot. `Figure`, `GridLayout`, or `GridPosition` to draw the plot. - `data::Union{DataFrame, Vector{Float32}}` \\ Data for the plot visualization. -- `positions::Vector{Point{2, Float32}} = nothing`\\ +- `positions::Vector{Point{2, Float32}}`\\ Positions used if `data` is not a `DataFrame`. Positions are generated from `labels` if `positions = nothing`. - `labels::Vector{String} = nothing`\\ Labels used if `data` is not a DataFrame. @@ -17,12 +17,16 @@ $(_docstring(:topoplot)) **Return Value:** `Figure` displaying the Topoplot. """ -plot_topoplot(data::Union{<:AbstractDataFrame,<:AbstractVector}; kwargs...) = - plot_topoplot!(Figure(), data; kwargs...) +plot_topoplot( + data::Union{<:AbstractDataFrame,<:AbstractVector}, + positions::Vector; + kwargs..., +) = plot_topoplot!(Figure(), data, positions; kwargs...) + function plot_topoplot!( f::Union{GridPosition,GridLayout,GridLayoutBase.GridSubposition,Figure}, - data::Union{<:AbstractDataFrame,<:AbstractVector}; - positions = nothing, + data::Union{<:AbstractDataFrame,<:AbstractVector}, + positions::Vector; labels = nothing, kwargs..., ) diff --git a/test/test_complexplots.jl b/test/test_complexplots.jl index ba6e09b85..502618436 100644 --- a/test/test_complexplots.jl +++ b/test/test_complexplots.jl @@ -39,12 +39,7 @@ ) hlines!(0, color = :gray, linewidth = 1) vlines!(0, color = :gray, linewidth = 1) - plot_topoplot!( - gc, - data[:, 340, 1]; - positions = positions, - axis = (; xlabel = "[340 ms]"), - ) + plot_topoplot!(gc, data[:, 340, 1], positions; axis = (; xlabel = "[340 ms]")) plot_topoplotseries!( gd, @@ -127,7 +122,7 @@ end ) plot_butterfly!(f[1, 2], d_topo; positions = positions) - plot_topoplot!(f[2, 1], data[:, 150, 1]; positions = positions) + plot_topoplot!(f[2, 1], data[:, 150, 1], positions) plot_topoplotseries!( f[2, 2], d_topo; @@ -197,7 +192,7 @@ end plot_designmatrix!(f[2, 3], designmatrix(uf)) - plot_topoplot!(f[3, 1], data[:, 150, 1]; positions = positions) + plot_topoplot!(f[3, 1], data[:, 150, 1], positions) plot_topoplotseries!( f[4, 1:3], d_topo; diff --git a/test/test_topoplot.jl b/test/test_topoplot.jl index cd25dd67d..7240140e9 100644 --- a/test/test_topoplot.jl +++ b/test/test_topoplot.jl @@ -1,48 +1,52 @@ dat, positions = TopoPlots.example_data() +data_for_topoplot = UnfoldMakie.eeg_array_to_dataframe(rand(10)') -@testset "topoplot basic" begin - plot_topoplot(dat[:, 50, 1]; positions = positions, axis = (; title = "topoplot")) +@testset "topoplot: basic" begin + plot_topoplot(dat[:, 50, 1], pos) +end + +@testset "topoplot: data input as DataFrame" begin + plot_topoplot(data_for_topoplot, positions[1:10], axis = (; title = "Topoplot")) +end + +@testset "topoplot: data input as AbstractVector" begin + d = rand(128) + p = rand(Point2f, 128) + plot_topoplot(d, p) +end + +@testset "topoplot: data input as SubDataFrame" begin + d = DataFrame(:estimate => rand(20), :label => string.(1:20)) + d1 = @view(d[1:10, :]) + plot_topoplot(d1, rand(Point2f, 10)) end @testset "topoplot: no legend" begin - plot_topoplot(dat[:, 50, 1]; positions = positions, layout = (; show_legend = false)) + plot_topoplot(dat[:, 50, 1], positions; layout = (; show_legend = false)) end @testset "topoplot: xlabel" begin - plot_topoplot(dat[:, 50, 1]; positions = positions, axis = (; xlabel = "[50 ms]")) + plot_topoplot(dat[:, 50, 1], positions; axis = (; xlabel = "[50 ms]")) end @testset "topoplot: GridLayout" begin f = Figure() - plot_topoplot!(f[1, 1], dat[:, 150, 1]; positions = positions) + plot_topoplot!(f[1, 1], dat[:, 150, 1], positions) f end @testset "topoplot: labels" begin labels = ["s$i" for i = 1:size(dat[:, 150, 1], 1)] - plot_topoplot(dat[:, 150, 1]; positions = positions, labels = labels) + plot_topoplot(dat[:, 150, 1], positions; labels = labels) end @testset "topoplot: GridSubposition" begin f = Figure() - data_for_topoplot = UnfoldMakie.eeg_array_to_dataframe(rand(10)') plot_topoplot!( f[1, 1][1, 1], - data_for_topoplot; - positions = rand(Point2f, 10), + data_for_topoplot, + rand(Point2f, 10); labels = string.(1:10), ) f end - -@testset "topoplot: AbstractMatrix" begin - d = rand(128) - p = rand(Point2f, 128) - plot_topoplot(d; positions = p) -end - -@testset "topoplot: ViewArray" begin - d = DataFrame(:estimate => rand(20), :label => string.(1:20)) - - plot_topoplot(@view(d[1:10, :]); positions = rand(Point2f, 10)) -end From 477d6f504319757356315da298248435b8422edf Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev Date: Mon, 12 Aug 2024 16:23:44 +0000 Subject: [PATCH 11/35] bugs --- docs/literate/how_to/hide_deco.jl | 4 ++-- docs/literate/tutorials/topoplot.jl | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/literate/how_to/hide_deco.jl b/docs/literate/how_to/hide_deco.jl index 514c6e24b..b798fcfc4 100644 --- a/docs/literate/how_to/hide_deco.jl +++ b/docs/literate/how_to/hide_deco.jl @@ -60,8 +60,8 @@ Some plots hide features by default. This could be reverted by setting the varia data, positions = TopoPlots.example_data() plot_topoplot( - data[:, 340, 1]; - positions = positions, + data[:, 340, 1], + positions; layout = (; hidespines = nothing, hidedecorations = nothing), ) diff --git a/docs/literate/tutorials/topoplot.jl b/docs/literate/tutorials/topoplot.jl index 7d96331ad..f9fc81deb 100644 --- a/docs/literate/tutorials/topoplot.jl +++ b/docs/literate/tutorials/topoplot.jl @@ -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; @@ -29,10 +29,10 @@ 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(data[:, 340, 1], positions) df = DataFrame(:estimate => data[:, 340, 1]) -plot_topoplot(df; positions = positions) +plot_topoplot(df, positions) # ## Setting sensor positions @@ -73,8 +73,8 @@ f = Figure(size = (500, 500)) labs4 = ["O1", "F2", "F3", "P4"] plot_topoplot!( f[1, 1], - data[1:4, 340, 1], - positions; + dat[1:4, 340, 1], + positions[1:4]; visual = (; label_scatter = false), labels = labs4, axis = (; title = "no channel scatter"), @@ -82,8 +82,8 @@ plot_topoplot!( plot_topoplot!( f[1, 2], - data[1:4, 340, 1], - positions; + dat[1:4, 340, 1], + positions[1:4]; visual = (; label_text = true, label_scatter = (markersize = 15, strokewidth = 2)), labels = labs4, axis = (; title = "channel scatter with text"), From d645435195fa2b151a2dfd98cb28de85ab24ff17 Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev Date: Mon, 12 Aug 2024 16:29:13 +0000 Subject: [PATCH 12/35] butterfly plot elaboration of datainput --- src/plot_butterfly.jl | 17 ++++++++--------- test/test_butterfly.jl | 1 - 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/plot_butterfly.jl b/src/plot_butterfly.jl index bc5b63af1..6caaa2600 100644 --- a/src/plot_butterfly.jl +++ b/src/plot_butterfly.jl @@ -39,18 +39,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, @@ -64,12 +58,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, Matrix{Float64}) + 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) diff --git a/test/test_butterfly.jl b/test/test_butterfly.jl index c46a70588..bb7a76cca 100644 --- a/test/test_butterfly.jl +++ b/test/test_butterfly.jl @@ -14,7 +14,6 @@ end plot_butterfly(mat; positions = pos) end - @testset "butterfly: GridLayout" begin f = Figure() plot_butterfly!(f[1, 1], df; positions = pos) From cd4b0954f1ffbdb927cf92f94617e7eaaf5da854 Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev Date: Mon, 12 Aug 2024 16:31:41 +0000 Subject: [PATCH 13/35] elaboration 2 --- test/test_butterfly.jl | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/test/test_butterfly.jl b/test/test_butterfly.jl index bb7a76cca..8115eafcc 100644 --- a/test/test_butterfly.jl +++ b/test/test_butterfly.jl @@ -2,23 +2,29 @@ include("../docs/example_data.jl") df, pos = example_data("TopoPlots.jl") +tmp = DataFrame(channel = df.channel, estimate = df.estimate) +grouped = groupby(tmp, :channel) +mat = Matrix(reduce(hcat, [group.estimate for group in grouped])') + @testset "butterfly: DataFrame as data input" begin plot_butterfly(df; positions = pos) #save("dev/UnfoldMakie/default_butterfly.png", f) end @testset "butterfly: Matrix as data input" begin - tmp = DataFrame(channel = df.channel, estimate = df.estimate) - grouped = groupby(tmp, :channel) - mat = Matrix(reduce(hcat, [group.estimate for group in grouped])') plot_butterfly(mat; positions = pos) end -@testset "butterfly: GridLayout" begin +@testset "butterfly: GridLayout for DataFrame" begin f = Figure() plot_butterfly!(f[1, 1], df; positions = pos) end +@testset "butterfly: GridLayout for Matrix" begin + f = Figure() + plot_butterfly!(f[1, 1], mat; positions = pos) +end + @testset "butterfly: witout topolegend" begin plot_butterfly( df; @@ -87,7 +93,6 @@ end ) end - @testset "changing color from ROMA to RGB" begin plot_butterfly( df; From a5fc4f14d3887c1e43ef0d12575c76b62f9f0951 Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev Date: Tue, 13 Aug 2024 16:27:52 +0000 Subject: [PATCH 14/35] bug --- docs/literate/tutorials/topoplot.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/literate/tutorials/topoplot.jl b/docs/literate/tutorials/topoplot.jl index f9fc81deb..d180a1ac9 100644 --- a/docs/literate/tutorials/topoplot.jl +++ b/docs/literate/tutorials/topoplot.jl @@ -29,9 +29,9 @@ dat, 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) +plot_topoplot(dat[:, 340, 1], positions) -df = DataFrame(:estimate => data[:, 340, 1]) +df = DataFrame(:estimate => dat[:, 340, 1]) plot_topoplot(df, positions) From 13ccb6418fd88c77a2b0bf7848480faa0f524225 Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev Date: Tue, 13 Aug 2024 16:34:08 +0000 Subject: [PATCH 15/35] bug 2 --- test/test_topoplot.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_topoplot.jl b/test/test_topoplot.jl index 7240140e9..67bb2746d 100644 --- a/test/test_topoplot.jl +++ b/test/test_topoplot.jl @@ -2,7 +2,7 @@ dat, positions = TopoPlots.example_data() data_for_topoplot = UnfoldMakie.eeg_array_to_dataframe(rand(10)') @testset "topoplot: basic" begin - plot_topoplot(dat[:, 50, 1], pos) + plot_topoplot(dat[:, 50, 1], positions) end @testset "topoplot: data input as DataFrame" begin From a9d803c5e260cdf6aac06be31f134110cdbcc91c Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev Date: Tue, 13 Aug 2024 17:00:42 +0000 Subject: [PATCH 16/35] simplification of signatures --- src/plot_butterfly.jl | 4 ++-- src/plot_erp.jl | 28 +++++++++++++++------------- src/plot_parallelcoordinates.jl | 2 +- test/runtests.jl | 2 +- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/plot_butterfly.jl b/src/plot_butterfly.jl index 6caaa2600..3e6e7d042 100644 --- a/src/plot_butterfly.jl +++ b/src/plot_butterfly.jl @@ -5,7 +5,7 @@ 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!(f::Union{GridPosition, GridLayout, Figure}, plot_data::AbstractMatrix; kwargs...) Plot a Butterfly plot. @@ -62,7 +62,7 @@ function plot_butterfly!( config = PlotConfig(:butterfly) config_kwargs!(config; mapping, kwargs...) plot_data = deepcopy(plot_data) # to avoid change of data in REPL - if isa(plot_data, Matrix{Float64}) + if isa(plot_data, AbstractMatrix{<:Real}) plot_data = eeg_array_to_dataframe(plot_data) config_kwargs!(config; axis = (; xlabel = "Time [samples]")) end diff --git a/src/plot_erp.jl b/src/plot_erp.jl index 3637d097c..a040532b6 100644 --- a/src/plot_erp.jl +++ b/src/plot_erp.jl @@ -2,10 +2,9 @@ using DataFrames using TopoPlots using LinearAlgebra """ - plot_erp!(f::Union{GridPosition, GridLayout, Figure}, plot_data::DataFrame; kwargs...) - plot_erp(times, plot_data::Union{AbstractMatrix,AbstractVector{<:Number}}; kwargs...) - plot_erp(plot_data::Union{DataFrame, <:AbstractMatrix, <:AbstractVector}; kwargs...) - + plot_erp!(f::Union{GridPosition, GridLayout, Figure}, plot_data::Union{DataFrame, AbstractMatrix, AbstractVector{<:Number}}; kwargs...) + plot_erp(times, plot_data::Union{DataFrame, AbstractMatrix, AbstractVector{<:Number}}; kwargs...) + Plot an ERP plot. ## Arguments @@ -42,20 +41,19 @@ $(_docstring(:erp)) **Return Value:** `Figure` displaying the ERP plot. """ -plot_erp(plot_data::DataFrame; kwargs...) = plot_erp!(Figure(), plot_data; kwargs...) +plot_erp(plot_data::Union{DataFrame,AbstractMatrix,AbstractVector{<:Number}}; kwargs...) = + plot_erp!(Figure(), plot_data; kwargs...) -plot_erp(plot_data::Union{AbstractMatrix,AbstractVector{<:Number}}; kwargs...) = plot_erp( - eeg_array_to_dataframe(plot_data'); - axis = (; xlabel = "Time [samples]"), +plot_erp( + times, + plot_data::Union{DataFrame,AbstractMatrix,AbstractVector{<:Number}}; kwargs..., -) - -plot_erp(times, plot_data::Union{AbstractMatrix,AbstractVector{<:Number}}; kwargs...) = - plot_erp(eeg_array_to_dataframe(plot_data'); axis = (; xticks = times), kwargs...) +) = + plot_erp(plot_data; axis = (; xticks = times), kwargs...) function plot_erp!( f::Union{GridPosition,GridLayout,Figure}, - plot_data::DataFrame; + plot_data::Union{DataFrame,AbstractMatrix,AbstractVector{<:Number}}; positions = nothing, labels = nothing, categorical_color = true, @@ -68,6 +66,10 @@ function plot_erp!( config = PlotConfig(:erp) config_kwargs!(config; mapping, kwargs...) plot_data = deepcopy(plot_data) + if isa(plot_data, Union{AbstractMatrix{<:Real},AbstractVector{<:Number}}) + 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) diff --git a/src/plot_parallelcoordinates.jl b/src/plot_parallelcoordinates.jl index b3eb7080f..fa25c7700 100644 --- a/src/plot_parallelcoordinates.jl +++ b/src/plot_parallelcoordinates.jl @@ -56,7 +56,7 @@ function plot_parallelcoordinates( bend = false, kwargs..., ) - if typeof(data) == Matrix{Float64} + if isa(data, AbstractMatrix{<:Real}) data = eeg_array_to_dataframe(data) end config = PlotConfig(:paracoord) diff --git a/test/runtests.jl b/test/runtests.jl index 15db1fa7e..976f86f0c 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -42,7 +42,7 @@ end include("test_erpgrid.jl") end -@testset "Parallel coordinates plot" begin +@testset "Parallel coordinates" begin include("test_pcp.jl") end From ab4abf52f46c42ada6d556dd77235ace01f6fe3f Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev <33777074+vladdez@users.noreply.github.com> Date: Tue, 13 Aug 2024 17:02:15 +0000 Subject: [PATCH 17/35] Update src/plot_erp.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- src/plot_erp.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/plot_erp.jl b/src/plot_erp.jl index a040532b6..c53679a51 100644 --- a/src/plot_erp.jl +++ b/src/plot_erp.jl @@ -48,8 +48,7 @@ plot_erp( times, plot_data::Union{DataFrame,AbstractMatrix,AbstractVector{<:Number}}; kwargs..., -) = - plot_erp(plot_data; axis = (; xticks = times), kwargs...) +) = plot_erp(plot_data; axis = (; xticks = times), kwargs...) function plot_erp!( f::Union{GridPosition,GridLayout,Figure}, From 894895a5c61d1123c66aefdfc11cd3d5116acfaa Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev Date: Tue, 13 Aug 2024 17:20:44 +0000 Subject: [PATCH 18/35] update of signatures in docstrings --- src/plot_butterfly.jl | 7 +++---- src/plot_channelimage.jl | 2 +- src/plot_erpgrid.jl | 2 +- src/plot_topoplot.jl | 4 ++-- src/plot_topoplotseries.jl | 6 +++--- 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/plot_butterfly.jl b/src/plot_butterfly.jl index 3e6e7d042..312ed55fd 100644 --- a/src/plot_butterfly.jl +++ b/src/plot_butterfly.jl @@ -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::Union{GridPosition, GridLayout, Figure}, 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. diff --git a/src/plot_channelimage.jl b/src/plot_channelimage.jl index 2afc193fe..ab4783fba 100644 --- a/src/plot_channelimage.jl +++ b/src/plot_channelimage.jl @@ -1,5 +1,5 @@ """ - plot_channelimage!(f::Union{GridPosition, GridLayout, Figure}, data::Matrix{<:Real}, positions::Vector{Point{2,Float32}}, ch_names::Vector{String}; kwargs...) + plot_channelimage!(f::Union{GridPosition, GridLayout, Figure}, data::Union{DataFrame,AbstractMatrix}, positions::Vector{Point{2,Float32}}, ch_names::Vector{String}; kwargs...) plot_channelimage(data::Union{DataFrame, AbstractMatrix}, positions::Vector{Point{2,Float32}}, ch_names::Vector{String}; kwargs...) Plot a Channel image diff --git a/src/plot_erpgrid.jl b/src/plot_erpgrid.jl index 62533fe90..6db807516 100644 --- a/src/plot_erpgrid.jl +++ b/src/plot_erpgrid.jl @@ -29,7 +29,7 @@ plot_erpgrid( positions::Vector, ch_names::Vector{String}; kwargs..., -) = plot_erpgrid!(Figure(), data, positions, ch_names::Vector{String}; kwargs...) +) = plot_erpgrid!(Figure(), data, positions, ch_names; kwargs...) plot_erpgrid!( f::Union{GridPosition,GridLayout,Figure}, diff --git a/src/plot_topoplot.jl b/src/plot_topoplot.jl index cc1a0d768..3ed6afcb5 100644 --- a/src/plot_topoplot.jl +++ b/src/plot_topoplot.jl @@ -1,6 +1,6 @@ """ - plot_topoplot!(f::Union{GridPosition, GridLayout, Figure}, data, positions::Vector; labels = nothing, kwargs...) - plot_topoplot(data, position::Vector; labels = nothing, kwargs...) + plot_topoplot!(f::Union{GridPosition, GridLayout, Figure}, data::Union{<:AbstractDataFrame,<:AbstractVector}, positions::Vector; labels = nothing, kwargs...) + plot_topoplot(data::Union{<:AbstractDataFrame,<:AbstractVector}, position::Vector; labels = nothing, kwargs...) Plot a topoplot. ## Arguments diff --git a/src/plot_topoplotseries.jl b/src/plot_topoplotseries.jl index 0108faeee..cbc515a67 100644 --- a/src/plot_topoplotseries.jl +++ b/src/plot_topoplotseries.jl @@ -1,6 +1,6 @@ """ - plot_topoplotseries(f::Union{GridPosition, GridLayout, Figure}, data::DataFrame; kwargs...) - plot_topoplotseries!(data::DataFrame; kwargs...) + plot_topoplotseries(f::Union{GridPosition, GridLayout, Figure}, data::Union{<:Observable{<:DataFrame},DataFrame}; kwargs...) + plot_topoplotseries!(data::Union{<:Observable{<:DataFrame},DataFrame}; kwargs...) Multiple miniature topoplots in regular distances. ## Arguments @@ -47,7 +47,7 @@ $(_docstring(:topoplotseries)) **Return Value:** `Figure` displaying the Topoplot series. """ -plot_topoplotseries(data::DataFrame; kwargs...) = +plot_topoplotseries(data::Union{<:Observable{<:DataFrame},DataFrame}; kwargs...) = plot_topoplotseries!(Figure(), data; kwargs...) #@deprecate plot_topoplotseries(data::DataFrame, Δbin; kwargs...) plot_topoplotseries(data::DataFrame; bin_width, kwargs...) From b069f492c4c95eeb7da54d79fc3d5ab0dd4cd03e Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev Date: Wed, 14 Aug 2024 13:31:04 +0000 Subject: [PATCH 19/35] finishing remarks --- src/plot_erpimage.jl | 6 +++--- src/plot_topoplotseries.jl | 2 -- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/plot_erpimage.jl b/src/plot_erpimage.jl index 89c8d0247..f77a316c4 100644 --- a/src/plot_erpimage.jl +++ b/src/plot_erpimage.jl @@ -1,5 +1,5 @@ """ - plot_erpimage!(f::Union{GridPosition, GridLayout, Figure}, data::Matrix{Float64}; kwargs...) + plot_erpimage!(f::Union{GridPosition, GridLayout, Figure}, data::AbstractMatrix{Float64}; kwargs...) plot_erpimage!(f::Union{GridPosition, GridLayout, Figure}, data::Observable{<:AbstractMatrix}; kwargs...) plot_erpimage!(f::Union{GridPosition, GridLayout, Figure}, times::Observable{<:AbstractVector}, data::Observable{<:AbstractMatrix{<:Real}}; kwargs...) @@ -43,9 +43,10 @@ $(_docstring(:erpimage)) **Return Value:** `Figure` displaying the ERP image. """ plot_erpimage(data; kwargs...) = plot_erpimage!(Figure(), data; kwargs...) + plot_erpimage( times::AbstractVector, - data::Union{<:Observable{Matrix{<:Real}},Matrix{<:Real}}; + data::Union{<:Observable{Matrix{<:Real}}, AbstractMatrix{<:Real}}; kwargs..., ) = plot_erpimage!(Figure(), times, data; kwargs...) @@ -59,7 +60,6 @@ plot_erpimage!( kwargs..., ) = plot_erpimage!(f, @lift(1:size($data, 1)), data; kwargs...) - _as_observable(x) = Observable(x) _as_observable(x::Observable) = x diff --git a/src/plot_topoplotseries.jl b/src/plot_topoplotseries.jl index cbc515a67..f2d108acd 100644 --- a/src/plot_topoplotseries.jl +++ b/src/plot_topoplotseries.jl @@ -50,8 +50,6 @@ $(_docstring(:topoplotseries)) plot_topoplotseries(data::Union{<:Observable{<:DataFrame},DataFrame}; kwargs...) = plot_topoplotseries!(Figure(), data; kwargs...) -#@deprecate plot_topoplotseries(data::DataFrame, Δbin; kwargs...) plot_topoplotseries(data::DataFrame; bin_width, kwargs...) - function plot_topoplotseries!( f::Union{GridPosition,GridLayout,Figure,GridLayoutBase.GridSubposition}, data::Union{<:Observable{<:DataFrame},DataFrame}; From e25ed3d864ea2ca88454e7afc42013cdb38d0011 Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev <33777074+vladdez@users.noreply.github.com> Date: Wed, 14 Aug 2024 13:35:02 +0000 Subject: [PATCH 20/35] Update src/plot_erpimage.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- src/plot_erpimage.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plot_erpimage.jl b/src/plot_erpimage.jl index f77a316c4..54abb5a36 100644 --- a/src/plot_erpimage.jl +++ b/src/plot_erpimage.jl @@ -46,7 +46,7 @@ plot_erpimage(data; kwargs...) = plot_erpimage!(Figure(), data; kwargs...) plot_erpimage( times::AbstractVector, - data::Union{<:Observable{Matrix{<:Real}}, AbstractMatrix{<:Real}}; + data::Union{<:Observable{Matrix{<:Real}},AbstractMatrix{<:Real}}; kwargs..., ) = plot_erpimage!(Figure(), times, data; kwargs...) From 5459118c30ab4462914be6a797b069f3f4806ef9 Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev Date: Wed, 14 Aug 2024 15:17:09 +0000 Subject: [PATCH 21/35] typos --- src/plot_butterfly.jl | 2 +- src/plot_circular_topoplots.jl | 2 +- src/plot_designmatrix.jl | 2 +- src/plot_erp.jl | 2 +- src/plot_erpgrid.jl | 2 +- src/plot_erpimage.jl | 2 +- src/plot_parallelcoordinates.jl | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/plot_butterfly.jl b/src/plot_butterfly.jl index 312ed55fd..6346eac0b 100644 --- a/src/plot_butterfly.jl +++ b/src/plot_butterfly.jl @@ -18,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. diff --git a/src/plot_circular_topoplots.jl b/src/plot_circular_topoplots.jl index a22f4452a..635a8bc14 100644 --- a/src/plot_circular_topoplots.jl +++ b/src/plot_circular_topoplots.jl @@ -10,7 +10,7 @@ Plot a circular EEG topoplot. - `data::DataFrame`\\ DataFrame with data keys (columns `:y, :yhat, :estimate`), and :position (columns `:pos, :position, :positions`). -## Keyword argumets (kwargs) +## Keyword arguments (kwargs) - `predictor::Vector{Any} = :predictor`\\ The circular predictor value, defines position of topoplot across the circle. Mapped around `predictor_bounds`. diff --git a/src/plot_designmatrix.jl b/src/plot_designmatrix.jl index bea1fb62a..c516840be 100644 --- a/src/plot_designmatrix.jl +++ b/src/plot_designmatrix.jl @@ -10,7 +10,7 @@ Plot a designmatrix. - `data::Unfold.DesignMatrix`\\ Data for the plot visualization. -## Keyword argumets (kwargs) +## Keyword arguments (kwargs) - `standardize_data::Bool = true`\\ Indicates whether the data is standardized by pointwise division of the data with its sampled standard deviation. - `sort_data::Bool = true`\\ diff --git a/src/plot_erp.jl b/src/plot_erp.jl index c53679a51..21a6bb781 100644 --- a/src/plot_erp.jl +++ b/src/plot_erp.jl @@ -17,7 +17,7 @@ Plot an ERP plot. Additional styling behavior. \\ Often used as: `plot_erp(df; mapping = (; color = :coefname, col = :conditionA))`. -## Keyword argumets (kwargs) +## Keyword arguments (kwargs) - `categorical_color::Bool = true`\\ Treat `:color` as categorical variable in case of numeric `:color` column. diff --git a/src/plot_erpgrid.jl b/src/plot_erpgrid.jl index 6db807516..ef06456ac 100644 --- a/src/plot_erpgrid.jl +++ b/src/plot_erpgrid.jl @@ -14,7 +14,7 @@ Plot an ERP image. - `ch_names::Vector{String}`\\ Vector with channel names. -## Keyword argumets (kwargs) +## Keyword arguments (kwargs) - `drawlabels::Bool = false`\\ Draw channels labels over each waveform. - `times::Vector = 1:size(data, 2)`\\ diff --git a/src/plot_erpimage.jl b/src/plot_erpimage.jl index 54abb5a36..5cf4d1abb 100644 --- a/src/plot_erpimage.jl +++ b/src/plot_erpimage.jl @@ -13,7 +13,7 @@ Plot an ERP image. - `data::Union{DataFrame, Vector{Float32}}`\\ Data for the plot visualization. -## Keyword argumets (kwargs) +## Keyword arguments (kwargs) - `erpblur::Number = 10`\\ Number indicating how much blur is applied to the image. \\ Gaussian blur of the `ImageFiltering` module is used.\\ diff --git a/src/plot_parallelcoordinates.jl b/src/plot_parallelcoordinates.jl index fa25c7700..9192148c1 100644 --- a/src/plot_parallelcoordinates.jl +++ b/src/plot_parallelcoordinates.jl @@ -14,7 +14,7 @@ Dimensions: conditions, channels, time, trials. - `data::Union{DataFrame, AbstractMatrix}`\\ Data for the plot visualization. -## Keyword argumets (kwargs) +## Keyword arguments (kwargs) - `normalize::Symbol = nothing`\\ If `:minmax`, normalize each axis to their respective min-max range. - `ax_labels::Vector{String} = nothing`\\ From b0fef3c8ba72cc1132b459a26acad831b4380d91 Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev Date: Thu, 15 Aug 2024 09:28:40 +0000 Subject: [PATCH 22/35] structure in hide_deco --- docs/literate/how_to/hide_deco.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/literate/how_to/hide_deco.jl b/docs/literate/how_to/hide_deco.jl index b798fcfc4..d0458b303 100644 --- a/docs/literate/how_to/hide_deco.jl +++ b/docs/literate/how_to/hide_deco.jl @@ -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 = (; ...)`. @@ -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` =# From 178c49f4fc06c00cf256bf6fd9314757503b5098 Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev Date: Thu, 15 Aug 2024 12:52:38 +0000 Subject: [PATCH 23/35] new tests for future PRs --- src/eeg_series.jl | 5 +++-- src/plot_erp.jl | 3 +-- src/plot_topoplotseries.jl | 2 ++ test/test_erp_effects.jl | 15 +++++++++++++++ test/test_toposeries1.jl | 19 +++++++++++++++++-- 5 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/eeg_series.jl b/src/eeg_series.jl index 995995623..9712e90e4 100644 --- a/src/eeg_series.jl +++ b/src/eeg_series.jl @@ -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 @@ -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 diff --git a/src/plot_erp.jl b/src/plot_erp.jl index 21a6bb781..63bcfc17c 100644 --- a/src/plot_erp.jl +++ b/src/plot_erp.jl @@ -69,7 +69,6 @@ function plot_erp!( 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` @@ -143,7 +142,7 @@ function plot_erp!( f_grid = f[1, 1:4] - # draw a normal ERP lineplot + # draw a standart ERP lineplot drawing = draw!(f_grid, plot_equation; axis = config.axis) if config.layout.show_legend == true config_kwargs!(config; mapping, layout = (; show_legend = false)) diff --git a/src/plot_topoplotseries.jl b/src/plot_topoplotseries.jl index f2d108acd..ea2335e7d 100644 --- a/src/plot_topoplotseries.jl +++ b/src/plot_topoplotseries.jl @@ -42,6 +42,8 @@ Multiple miniature topoplots in regular distances. `mapping.col` - specify x-value, can be any continuous or categorical variable.\\ `mapping.row` - specify y-value, can be any continuous or categorical variable (not implemented yet).\\ `mapping.layout` - arranges topoplots by rows when equals `:time`.\\ +- `visual.colorrange::2-element Vector{Int64}`, `colorbar.colorrange::2-element Vector{Int64}`\\ + First is resposnible for colorrange in topoplots, second - in colorbars. Ideally they should be the same. $(_docstring(:topoplotseries)) diff --git a/test/test_erp_effects.jl b/test/test_erp_effects.jl index bad0a2de9..4edca0255 100644 --- a/test/test_erp_effects.jl +++ b/test/test_erp_effects.jl @@ -1,3 +1,4 @@ +using Unfold: eventnames using AlgebraOfGraphics: group include("../docs/example_data.jl") m = example_data("UnfoldLinearModel") @@ -91,3 +92,17 @@ end ), ) end + +@testset "Effect plot: xlabelvisible is not working" begin + eff_same = effects(Dict(:condition => ["car", "face"], :duration => 200), m) + plot_erp( + res_effects2; + mapping = (; col = :eventname),#, color = :condition), why it doesn't work??? + axis = (; titlevisible = false, + xlabelvisible = false, + ylabelvisible = false, + yticklabelsvisible = false) + ) +end +using DataStructures +counter(eff_same.condition) \ No newline at end of file diff --git a/test/test_toposeries1.jl b/test/test_toposeries1.jl index 4b74fdc56..c7c26b0d2 100644 --- a/test/test_toposeries1.jl +++ b/test/test_toposeries1.jl @@ -149,6 +149,16 @@ end ) end +@testset "toposeries: visual.colorrange and colorbar.colorrange" begin + plot_topoplotseries( + df; + bin_width, + positions = positions, + colorbar = (; colorrange = (-1, 1)), + visual = (; colorrange = (-1, 1)), + ) +end + @testset "toposeries: adjusted ylim_topo" begin plot_topoplotseries( df; @@ -224,7 +234,7 @@ end ) end -@testset "adjustable colorbar" begin +@testset "adjustable colorbar" begin #need to be elaborated f = Figure() plot_topoplotseries!( f[1, 1], @@ -234,6 +244,11 @@ end colorbar = (; height = 100, width = 30), axis = (; aspect = AxisAspect(1)), ) - Box(f[1, 1], color = (:red, 0.2), strokewidth = 0) + #Box(f[1, 1], color = (:red, 0.2), strokewidth = 0) f end + +@testset "toposeries: precision" begin + df.time = df.time .+ 0.5555 + plot_topoplotseries(df; bin_num = 5, positions = positions) +end \ No newline at end of file From 17746045efeb90a090533ab0ac85cc9122638605 Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev Date: Thu, 15 Aug 2024 13:12:24 +0000 Subject: [PATCH 24/35] format --- test/test_erp_effects.jl | 14 +++++++------- test/test_toposeries1.jl | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/test_erp_effects.jl b/test/test_erp_effects.jl index 4edca0255..7c4a619d3 100644 --- a/test/test_erp_effects.jl +++ b/test/test_erp_effects.jl @@ -96,13 +96,13 @@ end @testset "Effect plot: xlabelvisible is not working" begin eff_same = effects(Dict(:condition => ["car", "face"], :duration => 200), m) plot_erp( - res_effects2; + res_effects2; mapping = (; col = :eventname),#, color = :condition), why it doesn't work??? - axis = (; titlevisible = false, - xlabelvisible = false, - ylabelvisible = false, - yticklabelsvisible = false) + axis = (; + titlevisible = false, + xlabelvisible = false, + ylabelvisible = false, + yticklabelsvisible = false, + ), ) end -using DataStructures -counter(eff_same.condition) \ No newline at end of file diff --git a/test/test_toposeries1.jl b/test/test_toposeries1.jl index c7c26b0d2..2d42bba84 100644 --- a/test/test_toposeries1.jl +++ b/test/test_toposeries1.jl @@ -251,4 +251,4 @@ end @testset "toposeries: precision" begin df.time = df.time .+ 0.5555 plot_topoplotseries(df; bin_num = 5, positions = positions) -end \ No newline at end of file +end From e25f166301e1b858d7aee0f3bea9912977fc160f Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev Date: Fri, 16 Aug 2024 12:45:00 +0000 Subject: [PATCH 25/35] new test for issue 230 --- test/test_erp_effects.jl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/test_erp_effects.jl b/test/test_erp_effects.jl index 7c4a619d3..9b1112395 100644 --- a/test/test_erp_effects.jl +++ b/test/test_erp_effects.jl @@ -74,6 +74,16 @@ end ) end + +@testset "Effect plot: should be no gap instead of legend" begin + plot_erp( + res_effects2; + mapping = (; color = :continuous, group = :continuous), + categorical_color = false, + ) +end + + @testset "Effect plot: move legend" begin plot_erp( res_effects2; From d5d72e0809eb8cd6af39a9d1a7af69a653da3db6 Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev Date: Fri, 6 Sep 2024 14:42:09 +0000 Subject: [PATCH 26/35] issue 221 --- docs/literate/tutorials/topoplotseries.jl | 16 ++++++++++++++++ test/test_toposeries1.jl | 18 ++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/docs/literate/tutorials/topoplotseries.jl b/docs/literate/tutorials/topoplotseries.jl index 1a3e67a83..4b81d428c 100644 --- a/docs/literate/tutorials/topoplotseries.jl +++ b/docs/literate/tutorials/topoplotseries.jl @@ -78,6 +78,22 @@ plot_topoplotseries( ), ) +# ## Adjusting column gaps +# Using `colgap` in `with_theme` helps to adjust column gaps. + +with_theme(colgap = 50) 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. diff --git a/test/test_toposeries1.jl b/test/test_toposeries1.jl index 2d42bba84..775ee60d2 100644 --- a/test/test_toposeries1.jl +++ b/test/test_toposeries1.jl @@ -252,3 +252,21 @@ end df.time = df.time .+ 0.5555 plot_topoplotseries(df; bin_num = 5, positions = positions) end + +@testset "toposeries: colgap" begin + with_theme(colgap = 50) do + plot_topoplotseries(df, bin_num = 5; positions = positions) + end +end + +@testset "toposeries: colgap for subsets" 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 From d8d9272b5b0c59e219846f40f38f20909e5c4019 Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev <33777074+vladdez@users.noreply.github.com> Date: Fri, 6 Sep 2024 14:47:30 +0000 Subject: [PATCH 27/35] Update docs/literate/tutorials/topoplotseries.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- docs/literate/tutorials/topoplotseries.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/literate/tutorials/topoplotseries.jl b/docs/literate/tutorials/topoplotseries.jl index 4b81d428c..dd50ee693 100644 --- a/docs/literate/tutorials/topoplotseries.jl +++ b/docs/literate/tutorials/topoplotseries.jl @@ -81,7 +81,7 @@ plot_topoplotseries( # ## Adjusting column gaps # Using `colgap` in `with_theme` helps to adjust column gaps. -with_theme(colgap = 50) do +with_theme(colgap = 50) do plot_topoplotseries(df, bin_num = 5; positions = positions) end From 96144c47a1250579ca19aadf4a2be5a7076744a4 Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev <33777074+vladdez@users.noreply.github.com> Date: Fri, 6 Sep 2024 14:48:06 +0000 Subject: [PATCH 28/35] Update docs/literate/tutorials/topoplotseries.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- docs/literate/tutorials/topoplotseries.jl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/literate/tutorials/topoplotseries.jl b/docs/literate/tutorials/topoplotseries.jl index dd50ee693..c14e8ba24 100644 --- a/docs/literate/tutorials/topoplotseries.jl +++ b/docs/literate/tutorials/topoplotseries.jl @@ -89,8 +89,13 @@ end 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))) + plot_topoplotseries!( + f[1, 1], + df, + bin_num = 5; + positions = positions, + topoplot_axes = (; limits = (-0.05, 1.05, -0.1, 1.05)), + ) f end From 3c61b5b536d4a3f4fc0c4ddaddde61d5b9c2e1e3 Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev Date: Tue, 10 Sep 2024 17:20:51 +0000 Subject: [PATCH 29/35] revert plot_topoplot until next instructions@ --- docs/literate/how_to/hide_deco.jl | 4 +-- docs/literate/how_to/mult_vis_in_fig.jl | 4 +-- docs/literate/tutorials/erp.jl | 3 +- .../literate/tutorials/parallelcoordinates.jl | 2 -- docs/literate/tutorials/topoplot.jl | 2 +- docs/literate/tutorials/topoplotseries.jl | 2 +- src/plot_topoplot.jl | 16 ++++++----- test/test_complexplots.jl | 17 ++--------- test/test_erp.jl | 9 ++++++ test/test_erp_effects.jl | 1 - test/test_topoplot.jl | 28 ++++++++++++------- 11 files changed, 46 insertions(+), 42 deletions(-) diff --git a/docs/literate/how_to/hide_deco.jl b/docs/literate/how_to/hide_deco.jl index d0458b303..99d8c67d8 100644 --- a/docs/literate/how_to/hide_deco.jl +++ b/docs/literate/how_to/hide_deco.jl @@ -66,8 +66,8 @@ Some plots hide features by default. This could be reverted by setting the varia data, positions = TopoPlots.example_data() plot_topoplot( - data[:, 340, 1], - positions; + data[:, 340, 1]; + positions = positions, layout = (; hidespines = nothing, hidedecorations = nothing), ) diff --git a/docs/literate/how_to/mult_vis_in_fig.jl b/docs/literate/how_to/mult_vis_in_fig.jl index 849ab9512..079339dc0 100644 --- a/docs/literate/how_to/mult_vis_in_fig.jl +++ b/docs/literate/how_to/mult_vis_in_fig.jl @@ -80,7 +80,7 @@ plot_erp!( plot_designmatrix!(f[2, 3], designmatrix(uf)) -plot_topoplot!(f[3, 1], data[:, 150, 1], positions) +plot_topoplot!(f[3, 1], data[:, 150, 1]; positions = positions) plot_topoplotseries!( f[4, 1:3], d_topo; @@ -162,7 +162,7 @@ plot_butterfly!( ) hlines!(0, color = :gray, linewidth = 1) vlines!(0, color = :gray, linewidth = 1) -plot_topoplot!(gc, data[:, 340, 1], positions; axis = (; xlabel = "[340 ms]")) +plot_topoplot!(gc, data[:, 340, 1]; positions = positions, axis = (; xlabel = "[340 ms]")) plot_topoplotseries!( gd, diff --git a/docs/literate/tutorials/erp.jl b/docs/literate/tutorials/erp.jl index 227fce93c..9f3f8a9ea 100644 --- a/docs/literate/tutorials/erp.jl +++ b/docs/literate/tutorials/erp.jl @@ -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 ) diff --git a/docs/literate/tutorials/parallelcoordinates.jl b/docs/literate/tutorials/parallelcoordinates.jl index a8bba8703..7783cac5a 100644 --- a/docs/literate/tutorials/parallelcoordinates.jl +++ b/docs/literate/tutorials/parallelcoordinates.jl @@ -160,7 +160,6 @@ plot_parallelcoordinates( f[1, 1], uf_5chan; mapping = (; color = :coefname), - layout = (; legend_position = :right), visual = (; alpha = 0.1), axis = (; title = "alpha = 0.1"), ) @@ -168,7 +167,6 @@ plot_parallelcoordinates( f[2, 1], uf_5chan, mapping = (; color = :coefname), - layout = (; legend_position = :right), visual = (; alpha = 0.9), axis = (; title = "alpha = 0.9"), ) diff --git a/docs/literate/tutorials/topoplot.jl b/docs/literate/tutorials/topoplot.jl index d180a1ac9..56345d1ca 100644 --- a/docs/literate/tutorials/topoplot.jl +++ b/docs/literate/tutorials/topoplot.jl @@ -32,7 +32,7 @@ dat, positions = TopoPlots.example_data() plot_topoplot(dat[:, 340, 1], positions) df = DataFrame(:estimate => dat[:, 340, 1]) -plot_topoplot(df, positions) +plot_topoplot(df; positions = positions) # ## Setting sensor positions diff --git a/docs/literate/tutorials/topoplotseries.jl b/docs/literate/tutorials/topoplotseries.jl index c14e8ba24..9c12cb578 100644 --- a/docs/literate/tutorials/topoplotseries.jl +++ b/docs/literate/tutorials/topoplotseries.jl @@ -81,7 +81,7 @@ plot_topoplotseries( # ## Adjusting column gaps # Using `colgap` in `with_theme` helps to adjust column gaps. -with_theme(colgap = 50) do +with_theme(colgap = 5) do plot_topoplotseries(df, bin_num = 5; positions = positions) end diff --git a/src/plot_topoplot.jl b/src/plot_topoplot.jl index 3ed6afcb5..5e66ae21d 100644 --- a/src/plot_topoplot.jl +++ b/src/plot_topoplot.jl @@ -1,6 +1,6 @@ """ - plot_topoplot!(f::Union{GridPosition, GridLayout, Figure}, data::Union{<:AbstractDataFrame,<:AbstractVector}, positions::Vector; labels = nothing, kwargs...) - plot_topoplot(data::Union{<:AbstractDataFrame,<:AbstractVector}, position::Vector; labels = nothing, kwargs...) + plot_topoplot!(f::Union{GridPosition, GridLayout, Figure}, data::Union{<:AbstractDataFrame,<:AbstractVector}; positions::Vector, labels = nothing, kwargs...) + plot_topoplot(data::Union{<:AbstractDataFrame,<:AbstractVector}; position::Vector, labels = nothing, kwargs...) Plot a topoplot. ## Arguments @@ -18,16 +18,15 @@ $(_docstring(:topoplot)) **Return Value:** `Figure` displaying the Topoplot. """ plot_topoplot( - data::Union{<:AbstractDataFrame,<:AbstractVector}, - positions::Vector; + data::Union{<:AbstractDataFrame,<:AbstractVector}; kwargs..., -) = plot_topoplot!(Figure(), data, positions; kwargs...) +) = plot_topoplot!(Figure(), data; kwargs...) function plot_topoplot!( f::Union{GridPosition,GridLayout,GridLayoutBase.GridSubposition,Figure}, - data::Union{<:AbstractDataFrame,<:AbstractVector}, - positions::Vector; + data::Union{<:AbstractDataFrame,<:AbstractVector}; labels = nothing, + positions = nothing, kwargs..., ) config = PlotConfig(:topoplot) @@ -40,6 +39,9 @@ function plot_topoplot!( data = data[:, config.mapping.y] end + if isnothing(positions) && !isnothing(labels) + positions = TopoPlots.labels2positions(labels) + end positions = get_topo_positions(; positions = positions, labels = labels) eeg_topoplot!(axis, data, labels; positions, config.visual...) diff --git a/test/test_complexplots.jl b/test/test_complexplots.jl index 502618436..504ad3286 100644 --- a/test/test_complexplots.jl +++ b/test/test_complexplots.jl @@ -136,12 +136,7 @@ end times = -0.099609375:0.001953125:1.0 plot_erpimage!(f[3, 2], times, d_singletrial) - plot_parallelcoordinates( - f[4, 2], - uf_5chan; - mapping = (; color = :coefname), - layout = (; legend_position = :right), - ) + plot_parallelcoordinates(f[4, 2], uf_5chan; mapping = (; color = :coefname)) for (label, layout) in zip( ["A", "B", "C", "D", "E", "F", "G", "H"], @@ -209,16 +204,10 @@ end categorical_color = false, categorical_group = true, mapping = (; y = :yhat, color = :continuous, group = :continuous), - legend = (; nbanks = 2), - layout = (; show_legend = true, legend_position = :right), + layout = (; show_legend = true), ) - plot_parallelcoordinates( - f[3, 2:3], - uf_5chan; - mapping = (; color = :coefname), - layout = (; legend_position = :right), - ) + plot_parallelcoordinates(f[3, 2:3], uf_5chan; mapping = (; color = :coefname)) plot_erpimage!(f[1, 4:5], times, d_singletrial) plot_circular_topoplots!( diff --git a/test/test_erp.jl b/test/test_erp.jl index 0e6785c52..5f19b9bf8 100644 --- a/test/test_erp.jl +++ b/test/test_erp.jl @@ -116,6 +116,15 @@ end ) end +#= @testset "ERP plot: with colorbar and legend 2" begin + plot_erp( + res_effects2; + mapping = (; color = :continuous, group = :continuous), + categorical_color = false, + categorical_group = false, + ) +end =# + @testset "ERP plot: rename legend" begin f = Figure() results = coeftable(m) diff --git a/test/test_erp_effects.jl b/test/test_erp_effects.jl index 9b1112395..59eb817eb 100644 --- a/test/test_erp_effects.jl +++ b/test/test_erp_effects.jl @@ -10,7 +10,6 @@ res_effects2 = effects(Dict(:condition => ["car", "face"], :continuous => -5:5), res_effects; mapping = (; y = :yhat, color = :continuous, group = :continuous), legend = (; nbanks = 2), - layout = (; legend_position = :right), categorical_color = false, categorical_group = true, ) diff --git a/test/test_topoplot.jl b/test/test_topoplot.jl index 67bb2746d..76508b89c 100644 --- a/test/test_topoplot.jl +++ b/test/test_topoplot.jl @@ -2,51 +2,59 @@ dat, positions = TopoPlots.example_data() data_for_topoplot = UnfoldMakie.eeg_array_to_dataframe(rand(10)') @testset "topoplot: basic" begin - plot_topoplot(dat[:, 50, 1], positions) + plot_topoplot(dat[:, 50, 1]; positions) end @testset "topoplot: data input as DataFrame" begin - plot_topoplot(data_for_topoplot, positions[1:10], axis = (; title = "Topoplot")) + plot_topoplot( + data_for_topoplot; + positions = positions[1:10], + axis = (; title = "Topoplot"), + ) end @testset "topoplot: data input as AbstractVector" begin d = rand(128) p = rand(Point2f, 128) - plot_topoplot(d, p) + plot_topoplot(d; positions = p) end @testset "topoplot: data input as SubDataFrame" begin d = DataFrame(:estimate => rand(20), :label => string.(1:20)) d1 = @view(d[1:10, :]) - plot_topoplot(d1, rand(Point2f, 10)) + plot_topoplot(d1; positions = rand(Point2f, 10)) end @testset "topoplot: no legend" begin - plot_topoplot(dat[:, 50, 1], positions; layout = (; show_legend = false)) + plot_topoplot(dat[:, 50, 1]; positions = positions, layout = (; show_legend = false)) end @testset "topoplot: xlabel" begin - plot_topoplot(dat[:, 50, 1], positions; axis = (; xlabel = "[50 ms]")) + plot_topoplot(dat[:, 50, 1]; positions = positions, axis = (; xlabel = "[50 ms]")) end @testset "topoplot: GridLayout" begin f = Figure() - plot_topoplot!(f[1, 1], dat[:, 150, 1], positions) + plot_topoplot!(f[1, 1], dat[:, 150, 1]; positions = positions) f end @testset "topoplot: labels" begin labels = ["s$i" for i = 1:size(dat[:, 150, 1], 1)] - plot_topoplot(dat[:, 150, 1], positions; labels = labels) + plot_topoplot(dat[:, 150, 1], positions = positions; labels = labels) end @testset "topoplot: GridSubposition" begin f = Figure() plot_topoplot!( f[1, 1][1, 1], - data_for_topoplot, - rand(Point2f, 10); + data_for_topoplot; + positions = rand(Point2f, 10), labels = string.(1:10), ) f end + +@testset "topoplot: positions through labels" begin + plot_topoplot(dat[1:19, 50, 1]; labels = TopoPlots.CHANNELS_10_20) +end From 11611b9bee1c510f13c80d2c7c3e52f7165d8463 Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev <33777074+vladdez@users.noreply.github.com> Date: Tue, 10 Sep 2024 17:26:58 +0000 Subject: [PATCH 30/35] Update src/plot_topoplot.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- src/plot_topoplot.jl | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/plot_topoplot.jl b/src/plot_topoplot.jl index 5e66ae21d..0747b2d61 100644 --- a/src/plot_topoplot.jl +++ b/src/plot_topoplot.jl @@ -17,10 +17,8 @@ $(_docstring(:topoplot)) **Return Value:** `Figure` displaying the Topoplot. """ -plot_topoplot( - data::Union{<:AbstractDataFrame,<:AbstractVector}; - kwargs..., -) = plot_topoplot!(Figure(), data; kwargs...) +plot_topoplot(data::Union{<:AbstractDataFrame,<:AbstractVector}; kwargs...) = + plot_topoplot!(Figure(), data; kwargs...) function plot_topoplot!( f::Union{GridPosition,GridLayout,GridLayoutBase.GridSubposition,Figure}, From c757f7a8e741630ad1b2aecfaa54d15dcc3c76e3 Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev Date: Tue, 10 Sep 2024 17:51:25 +0000 Subject: [PATCH 31/35] bugs --- docs/literate/tutorials/topoplot.jl | 10 +++++----- test/test_complexplots.jl | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/literate/tutorials/topoplot.jl b/docs/literate/tutorials/topoplot.jl index 56345d1ca..e8a466683 100644 --- a/docs/literate/tutorials/topoplot.jl +++ b/docs/literate/tutorials/topoplot.jl @@ -29,7 +29,7 @@ dat, positions = TopoPlots.example_data() # # Plot Topoplots # Here we select a time point in 340 msec and the mean estimate. -plot_topoplot(dat[:, 340, 1], positions) +plot_topoplot(dat[:, 340, 1]; positions = positions[1:4]) df = DataFrame(:estimate => dat[:, 340, 1]) plot_topoplot(df; positions = positions) @@ -73,8 +73,8 @@ f = Figure(size = (500, 500)) labs4 = ["O1", "F2", "F3", "P4"] plot_topoplot!( f[1, 1], - dat[1:4, 340, 1], - positions[1:4]; + dat[1:4, 340, 1]; + positions = positions[1:4]; visual = (; label_scatter = false), labels = labs4, axis = (; title = "no channel scatter"), @@ -82,8 +82,8 @@ plot_topoplot!( plot_topoplot!( f[1, 2], - dat[1:4, 340, 1], - positions[1:4]; + 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"), diff --git a/test/test_complexplots.jl b/test/test_complexplots.jl index 504ad3286..94b241f7f 100644 --- a/test/test_complexplots.jl +++ b/test/test_complexplots.jl @@ -39,7 +39,7 @@ ) hlines!(0, color = :gray, linewidth = 1) vlines!(0, color = :gray, linewidth = 1) - plot_topoplot!(gc, data[:, 340, 1], positions; axis = (; xlabel = "[340 ms]")) + plot_topoplot!(gc, data[:, 340, 1]; positions = positions, axis = (; xlabel = "[340 ms]")) plot_topoplotseries!( gd, @@ -121,8 +121,8 @@ end stderror = true, ) - plot_butterfly!(f[1, 2], d_topo; positions = positions) - plot_topoplot!(f[2, 1], data[:, 150, 1], positions) + plot_butterfly!(f[1, 2], d_topo, positions = positions) + plot_topoplot!(f[2, 1], data[:, 150, 1]; positions = positions) plot_topoplotseries!( f[2, 2], d_topo; @@ -187,7 +187,7 @@ end plot_designmatrix!(f[2, 3], designmatrix(uf)) - plot_topoplot!(f[3, 1], data[:, 150, 1], positions) + plot_topoplot!(f[3, 1], data[:, 150, 1]; positions = positions) plot_topoplotseries!( f[4, 1:3], d_topo; From 90607dce478e5275a6077a968f824f7f3dbde900 Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev Date: Tue, 10 Sep 2024 18:07:59 +0000 Subject: [PATCH 32/35] bug2 --- docs/literate/tutorials/topoplot.jl | 4 ++-- test/test_complexplots.jl | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/literate/tutorials/topoplot.jl b/docs/literate/tutorials/topoplot.jl index e8a466683..a83ba7529 100644 --- a/docs/literate/tutorials/topoplot.jl +++ b/docs/literate/tutorials/topoplot.jl @@ -74,7 +74,7 @@ labs4 = ["O1", "F2", "F3", "P4"] plot_topoplot!( f[1, 1], dat[1:4, 340, 1]; - positions = positions[1:4]; + positions = positions[1:4], visual = (; label_scatter = false), labels = labs4, axis = (; title = "no channel scatter"), @@ -83,7 +83,7 @@ plot_topoplot!( plot_topoplot!( f[1, 2], dat[1:4, 340, 1]; - positions = positions[1:4]; + positions = positions[1:4], visual = (; label_text = true, label_scatter = (markersize = 15, strokewidth = 2)), labels = labs4, axis = (; title = "channel scatter with text"), diff --git a/test/test_complexplots.jl b/test/test_complexplots.jl index 94b241f7f..82ca44a53 100644 --- a/test/test_complexplots.jl +++ b/test/test_complexplots.jl @@ -39,7 +39,12 @@ ) hlines!(0, color = :gray, linewidth = 1) vlines!(0, color = :gray, linewidth = 1) - plot_topoplot!(gc, data[:, 340, 1]; positions = positions, axis = (; xlabel = "[340 ms]")) + plot_topoplot!( + gc, + data[:, 340, 1]; + positions = positions, + axis = (; xlabel = "[340 ms]"), + ) plot_topoplotseries!( gd, From bdd9195be9a8bd21b6b35e9e8e4e536f5e18261d Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev Date: Tue, 10 Sep 2024 18:36:08 +0000 Subject: [PATCH 33/35] bug3 --- docs/literate/tutorials/topoplot.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/literate/tutorials/topoplot.jl b/docs/literate/tutorials/topoplot.jl index a83ba7529..3578c3354 100644 --- a/docs/literate/tutorials/topoplot.jl +++ b/docs/literate/tutorials/topoplot.jl @@ -29,7 +29,7 @@ dat, positions = TopoPlots.example_data() # # Plot Topoplots # Here we select a time point in 340 msec and the mean estimate. -plot_topoplot(dat[:, 340, 1]; positions = positions[1:4]) +plot_topoplot(dat[1:4, 340, 1]; positions = positions[1:4]) df = DataFrame(:estimate => dat[:, 340, 1]) plot_topoplot(df; positions = positions) @@ -96,3 +96,5 @@ f # ```@docs # plot_topoplot # ``` + + \ No newline at end of file From 26397830445b9fb96aa79e01596ca0a5e408e67b Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev <33777074+vladdez@users.noreply.github.com> Date: Tue, 10 Sep 2024 21:00:50 +0200 Subject: [PATCH 34/35] Update docs/literate/tutorials/topoplot.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- docs/literate/tutorials/topoplot.jl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/literate/tutorials/topoplot.jl b/docs/literate/tutorials/topoplot.jl index 3578c3354..abb67b0c2 100644 --- a/docs/literate/tutorials/topoplot.jl +++ b/docs/literate/tutorials/topoplot.jl @@ -95,6 +95,4 @@ f # ```@docs # plot_topoplot -# ``` - - \ No newline at end of file +# ``` \ No newline at end of file From 3b89404c159dd5378d760e0aee34d4ccb46aba59 Mon Sep 17 00:00:00 2001 From: Vladimir Mikheev <33777074+vladdez@users.noreply.github.com> Date: Wed, 11 Sep 2024 13:29:28 +0200 Subject: [PATCH 35/35] Update Project.toml --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index ae4449947..d27ac0ac6 100644 --- a/Project.toml +++ b/Project.toml @@ -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"