Hi everyone. I’m trying to make an EEG topographical plot, something like this:
The steps, in general are (without the aesthetics and circular appearance):
- Turn polar coordinates to Cartesian coordinates
- Interpolate data onto coordinates
- …?
So far I’ve tried to keep it pretty simple, but still can’t manage. I was trying to adapt some MATLAB code but just couldn’t manage to implement the steps. Can you see something that I’m missing?
using MAT, Plots, Random, Measures
using FFTW, DSP
using ScatteredInterpolation
using Statistics
using StatsBase
plotly()
# I/O for the EEG mat file, using MAT package
EEG = matread("sampleEEGdata.mat")
EEG = EEG["EEG"]
function pol2cart(th,r,z=1)
x = r.*cos.(th)
y = r.*sin.(th)
return (x, y, z)
end
# Introduction to Topographical Plots
timepoint2plot = 100 # in ms
trial2plot = Int(sample(1:EEG["trials"]))
color_limit = 20
# Convert time point from ms to index and get relevant EEG data
_, timepointidx = findmin(dropdims(abs.(EEG["times"].-timepoint2plot), dims=1))
timepoint_trial_data = EEG["data"][:,timepointidx, trial2plot][:,1]
# First step is to get X and Y coordinates of electrodes
# These must be converted to polar coordinates
th = (π/180) .*EEG["chanlocs"]["theta"][1,:]
radi = EEG["chanlocs"]["radius"][1,:]
electrode_locs_X, electrode_locs_Y = pol2cart(th, radi)
# Interpolate to get nice surface
interpolation_level = 100 # you can try changing this number, but 100 is probably good
interpX = range(
minimum(electrode_locs_X),
maximum(electrode_locs_X),
length=interpolation_level
)
interpY = range(
minimum(electrode_locs_Y),
maximum(electrode_locs_Y),
length=interpolation_level
)
# testing ScatteredInterpolation.jl
points = [electrode_locs_X' ; electrode_locs_Y']
samples = timepoint_trial_data
n = 100
x = interpX
y = interpY
X = repeat(x, n)[:]
Y = repeat(y', n)[:]
gridPoints = [X Y]'
itp = interpolate(Multiquadratic(), points, samples)
interpolated = evaluate(itp, gridPoints)
gridded = reshape(interpolated, n, n)
p2 = contour(x, y, gridded)
The matlab code was:
% First step is to get X and Y coordinates of electrodes
% These must be converted to polar coordinates
th=pi/180*[EEG.chanlocs.theta];
[electrode_locs_X,electrode_locs_Y] = pol2cart(th,[EEG.chanlocs.radius]);
% interpolate to get nice surface
interpolation_level = 100; % you can try changing this number, but 100 is probably good
interpX = linspace(min(electrode_locs_X),max(electrode_locs_X),interpolation_level);
interpY = linspace(min(electrode_locs_Y),max(electrode_locs_Y),interpolation_level);
% meshgrid is a function that creates 2D grid locations based on 1D inputs
[gridX,gridY] = meshgrid(interpX,interpY);
% now interpolate the data on a 2D grid
interpolated_EEG_data = griddata(electrode_locs_Y,electrode_locs_X,double(squeeze(EEG.data(:,timepointidx,trial2plot))),gridX,gridY);
contourf(interpY,interpX,interpolated_EEG_data,100,'linecolor','none');
I get the following: (Julia plot on the left, MATLAB on the right)
Does anyone have any better approaches on getting the final product?