How to move object across axis?

101 Views Asked by At

I have an interactive plot and I want to move topoplot position across the x-axis according to the slider (or red vertical bar) position.

How can I do that?

In an ideal situation, the topoplot moves until some border (so it would be partially out of the screen).

Also, is it possible to put a line connecting the topolot with a red vertical line?

enter image description here

This is my script with prerequisite functions:

using Makie
using GLMakie
using PyMNE
using JLD2 # loading data
using TopoPlots
using StatsBase # mean/std
using Pipe
using ColorSchemes
using Colors
using LinearAlgebra

function eegHeadMatrix(positions, center, radius)
oldCenter = mean(positions)
oldRadius, _ = findmax(x-> LinearAlgebra.norm(x .- oldCenter), 
positions)
radF = radius/oldRadius
return Makie.Mat4f(radF, 0, 0, 0,
                   0, radF, 0, 0,
                   0, 0, 1, 0,
                   center[1]-oldCenter[1]*radF, center[2]-
                   oldCenter[2]*radF, 0, 1)
end

struct NullInterpolator <: TopoPlots.Interpolator
end

function (ni::NullInterpolator)(
        xrange::LinRange, yrange::LinRange,
        positions::AbstractVector{<: Point{2}}, data::AbstractVector{<:Number})

    return zeros(length(xrange),length(yrange))
end

function posToColor(pos)
    cx = 0.5 - pos[1]
    cy = 0.5 - pos[2]
    rx = cx * 0.7071068 + cy * 0.7071068
    ry = cx * -0.7071068 + cy * 0.7071068
    b = 1.0 - (2*sqrt(cx^2+cy^2))^2
    return RGB(0.5 - rx*1.414, 0.5 - ry*1.414, b)
end

This is the main function

f = Figure(backgroundcolor = RGBf(0.98, 0.98, 0.98), resolution = (1500, 700))

# interaction
xs = range(-0.3, length=size(dat_e, 2), step=1 ./ 128)  
sg = SliderGrid(f[4, 1:2],
    (label="time", range=xs, format = "{:.3f} ms", startvalue = 0),
)
time = sg.sliders[1].value
str = lift(t -> "[$(round(t, digits = 3)) ms]", time)
topo_slice = lift((t, data) -> mean(data[1:30, indexin(t, xs), :], dims=2)[:,1], time, dat_e)

# butterfly plot
ax = Axis(f[2:3, 1:2], xlabel = "Time [s]", ylabel = "Voltage amplitude [µV]")
N = 1:length(pos) #1:4 
hidespines!(ax, :t, :r) 
GLMakie.xlims!(-0.3, 1.2)
hlines!(0, color = :gray, linewidth = 1)
vlines!(0, color = :gray, linewidth = 1)
times = range(-0.3, length=size(dat_e,2), step=1 ./ 128)
specialColors = ColorScheme(vcat(RGB(1,1,1.),[posToColor(pos) for pos in pos[N]]...))

for i in N
    mean_trial = mean(dat_e[i,:,:], dims=2)[:,1]
    lines!(times, mean_trial, color = specialColors[i])
end 
hidedecorations!(ax, label = false, ticks = false, ticklabels = false) 

# text
vlines!(time,  color = :red, linewidth = 1)
text!(time, 8, text = str,  align = (:center, :center))

# topoplot 
topo_axis = Axis(f[1, 1:2], width = 178, height = 178, aspect = DataAspect())
Makie.xlims!(low = -0.2, high = 1.2)
Makie.ylims!(low = -0.2, high = 1.2)
topoMatrix = eegHeadMatrix(pos[N], (0.5, 0.5), 0.5)

topo = eeg_topoplot!(topo_axis, topo_slice, # averaging all trial of 30 participants on Xth msec
    raw.ch_names[1:30]; 
    positions=pos, # produced  automatically from ch_names
    #interpolation=DelaunayMesh(),
    enlarge=1,
    extrapolation=GeomExtrapolation(enlarge=1.0, geometry=Circle),
    label_text=false)
    
hidedecorations!(current_axis())
hidespines!(current_axis())
f
0

There are 0 best solutions below