Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

plot_topoplotseries improvements #68

Merged
merged 3 commits into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 32 additions & 11 deletions src/eeg-series.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,18 @@ end
"""
function eeg_topoplot_series(data::DataFrame,
Δbin;
col_y=:estimate,
col_label=:label,
y=:estimate,
label=:label,
col=:time,
row=nothing,
figure = NamedTuple(),
combinefun=mean,
row_labels = false,
col_labels = false,
topoplot_attributes...
)
Plot a series of topoplots. The function automatically takes the `combinefun=mean` over the `:time`` column of `data` in `Δbin` steps.
Dataframe `data` needs columns `:time` and `col_y(=:erp)`, and `col_label(=:label)`.
Dataframe `data` needs columns `:time` and `y(=:erp)`, and `label(=:label)`.
If `data` is a `Matrix`, it is automatically cast to a dataframe, time-bins are then in samples, labels are `string.(1:size(data,1))`
`
Δbin in `:time`-units, specifise the time-steps.
Expand All @@ -32,6 +34,8 @@ All other keyword arguments are forwarded to the EEG_TopoPlot (eeg_toplot) recip
`col` and `row` specify the field to split by columns and rows. By default `col=:time`, to split by the time field and `row=nothing`. Useful
to split by a condition e.g. `...(...,col=:time, row=:condition)` would result in multiple (as many as different values in df.condition) rows of topoplot series
`figure` allows to include information for the figure generation. Alternatively you can provide a fig object `eeg_topoplot_series!(fig,data::DataFrame,Δbin; kwargs..)`
`row_labels` and `col_labels` indicate whether there should be labels in the the plots in the first column indicating the row-value and in the last row to indicate the time (typically timerange)

# Examples
Desc
```julia-repl
Expand Down Expand Up @@ -69,11 +73,14 @@ see eeg_topoplot_series(data,Δbin) for help
"""
function eeg_topoplot_series!(fig, data::DataFrame,
Δbin;
col_y=:erp,
col_label=:label,
y=:erp,
label=:label,
col=:time,
row=nothing,
combinefun=mean,
col_labels = false,
row_labels = false,
rasterize_heatmap = true,
topoplot_attributes...)

# cannot be made easier right now, but Simon promised a simpler solution "soonish"
Expand All @@ -86,12 +93,12 @@ function eeg_topoplot_series!(fig, data::DataFrame,

# aggregate the data over time-bins
data_mean = df_timebin(data, Δbin;
col_y=col_y,
col_y=y,
fun=combinefun,
grouping=[col_label, col, row])
grouping=[label, col, row])

# using same colormap + contour levels for all plots
(q_min, q_max) = Statistics.quantile(data_mean[:, col_y], [0.001, 0.999])
(q_min, q_max) = Statistics.quantile(data_mean[:, y], [0.001, 0.999])
# make them symmetrical
q_min = q_max = max(abs(q_min), abs(q_max))
q_min = -q_min
Expand All @@ -116,12 +123,26 @@ function eeg_topoplot_series!(fig, data::DataFrame,
sel = sel .&& (data_mean[:, row] .== select_row[r]) # subselect
end
df_single = data_mean[sel, :]

# select labels
labels = df_single[:, col_label]
labels = df_single[:, label]
# select data
d_vec = df_single[:, col_y]
d_vec = df_single[:, y]
# plot it
eeg_topoplot!(ax, d_vec, labels; topoplot_attributes...)
ax2 = eeg_topoplot!(ax, d_vec, labels; topoplot_attributes...)

if rasterize_heatmap
ax2.plots[1].plots[1].rasterize = true
end
if r == length(select_row) && col_labels
ax.xlabel = string(df_single.time[1])
ax.xlabelvisible = true
end
if c == 1 && length(select_row)>1 && row_labels
#@show df_single
ax.ylabel = string(df_single.row[1])
ax.ylabelvisible = true
end
end
end
colgap!(fig.layout, 0)
Expand Down
20 changes: 15 additions & 5 deletions src/plot_topoplotseries.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ Plot a Topoplot Series.
## Arguments:
- `f::Union{GridPosition, Figure}`: Figure or GridPosition that the plot should be drawn into
- `plotData::DataFrame`: DataFrame with data, needs a `time` column
- `Δbin::Real`: A number for how many samples should be moved together to one topoplot
- `Δbin::Real`: A number for how large one bin should be. Δbin is in units of the `plotData.time` column
- `kwargs...`: Additional styling behavior. Often used:
`plot_topoplotseries(df;mapping=(;col=:time,row=:conditionA))`

## Extra Data Behavior (...;extra=(;[key]=value)):
`combinefun` (default `mean`) can be used to specify how the samples within `Δbin` are combined.

`bin_labels` (default `true`) - plot the time-window bin size as xlabels at the last row of the plot
`rasterize_heatmaps` (deault `true`) - when saving a svg - enforce rasterization of the plot heatmap. This has the benefit that all lines/points are vectors, except the interpolated heatmap. This is typically what you want, because else you get ~500x500 vectors per topoplot, which makes everything super slow...


## Return Value:
Expand All @@ -39,16 +40,25 @@ function plot_topoplotseries!(f::Union{GridPosition,Figure}, plotData::DataFrame
plotData.label = plotData.channel
end

eeg_topoplot_series!(f, plotData, Δbin;
col_y=config.mapping.y,
col_label=:label,
ftopo = eeg_topoplot_series!(f, plotData, Δbin;
y=config.mapping.y,
label=:label,
col=config.mapping.col,
row=config.mapping.row,
col_labels = config.extra.col_labels,
row_labels = config.extra.row_labels,
rasterize_heatmaps = config.extra.rasterize_heatmaps,
combinefun=config.extra.combinefun,
positions=positions,
config.visual...
)

if config.layout.showLegend
@show "leegeeend"
d = ftopo.content[1].scene.plots[1]

Colorbar(f[1,end+1],colormap=d.colormap,colorrange=d.colorrange,height=100)
end
return f

end
3 changes: 3 additions & 0 deletions src/plotconfig.jl
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ function PlotConfig(T::Val{:topoplotseries})
cfg = PlotConfig(:topoplot)
config_kwargs!(cfg, extra=(
combinefun=mean,
col_labels=true,
row_labels = true,
rasterize_heatmaps=true
), layout=(
showLegend=false, # what does it mean to have a topoplotseries legend?
), visual=(; label_text=false # true doesnt work again
Expand Down