Code covered by the BSD License  

Highlights from
Connected topoplot

image thumbnail
from Connected topoplot by Praneeth Namburi
Visualize networks in your EEG data

topoplot_connect(displayStruct, loc_file)
function [] = topoplot_connect(displayStruct, loc_file)
% NOTE: The cartoon head is drawn using code in topoplot.m file from EEGLAB
% v6.01b (http://sccn.ucsd.edu/eeglab/). 
%
% Reference:
% Delorme A & Makeig S (2004) EEGLAB: an open source toolbox for analysis
% of single-trial EEG dynamics. Journal of Neuroscience Methods 134:9-21 
%
% Usage:
%
% >> topoplot_connect(ds, EEG.chanlocs);
%
% *ds* is the display strcture with the folowing fields:
%
% * *ds.chanPairs* (required) - N x 2 matrix, with N being the number of 
% connected channel pairs. For example, ds.chanPairs = [7, 12; 13 20]; 
% specifies two connected channel pairs (7, 12) and (13, 20).
% * *ds.connectStrength* (optional) - N x 1 matrix, a vector specifying
% connection strengths. If unspecified, then the connections will be
% rendered in a color at the center of the current colormap.
% * *ds.connectStrengthLimits* (optional) - 1 x 2 matrix specifying minimum
% and maximum values of connection strengths to display. If it is not 
% specified, then the minimum and maximum values from ds.connectStrength 
% are used.
%
% EEG.chanlocs is a structure specifying channel locations (or an locs
% filename)
%
% For comments and/or suggestions, please send me an email at
% praneeth@mit.edu
%

BACKCOLOR = [1 1 1];  % EEGLAB standard
rmax = 0.5;             % actual head radius - Don't change this!
CIRCGRID   = 201;       % number of angles to use in drawing circles
AXHEADFAC = 1.3;        % head to axes scaling factor
HEADCOLOR = [0 0 0];    % default head color (black)
EMARKER = '.';          % mark electrode locations with small disks
ECOLOR = [0 0 0];       % default electrode color = black
EMARKERSIZE = [];       % default depends on number of electrodes, set in code
EMARKERLINEWIDTH = 1;   % default edge linewidth for emarkers
HLINEWIDTH = 1.7;         % default linewidth for head, nose, ears
HEADRINGWIDTH    = .007;% width of the cartoon head ring

%
%%%%%%%%%%%%%%%%%%%% Read the channel location information %%%%%%%%%%%%%%%%%%%%%%%%
%
if ischar(loc_file)
    [~, ~, Th Rd indices] = readlocs( loc_file,'filetype','loc');
elseif isstruct(loc_file) % a locs struct
    [~, ~, Th Rd indices] = readlocs( loc_file );
    % Note: Th and Rd correspond to indices channels-with-coordinates only
else
    error('loc_file must be a EEG.locs struct or locs filename');
end
Th = pi/180*Th;                              % convert degrees to radians
plotchans = indices;
%
%%%%%%%%%%%%%%%%%%% remove infinite and NaN values %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%

[x,y]     = pol2cart(Th,Rd);  % transform electrode locations from polar to cartesian coordinates
plotchans = abs(plotchans);   % reverse indicated channel polarities
Rd        = Rd(plotchans);
x         = x(plotchans);
y         = y(plotchans);
plotrad = min(1.0,max(Rd)*1.02);            % default: just outside the outermost electrode location
plotrad = max(plotrad,0.5);                 % default: plot out to the 0.5 head boundary
headrad = rmax;
pltchans = find(Rd <= plotrad); % plot channels inside plotting circle
x     = x(pltchans);
y     = y(pltchans);
squeezefac = rmax/plotrad;
x    = x*squeezefac;
y    = y*squeezefac;

%
%%%%%%%%%%%%%%%%%%%%%%% Draw blank head %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
cla
hold on
set(gca,'Xlim',[-rmax rmax]*AXHEADFAC,'Ylim',[-rmax rmax]*AXHEADFAC)

%
%%%%%%%%%%%%%%%%%%% Plot filled ring to mask jagged grid boundary %%%%%%%%%%%%%%%%%%%%%%%%%%%
%
hwidth = HEADRINGWIDTH;                   % width of head ring
hin  = squeezefac*headrad*(1- hwidth/2);  % inner head ring radius
circ = linspace(0,2*pi,CIRCGRID);
rx = sin(circ);
ry = cos(circ);

%
%%%%%%%%%%%%%%%%%%%%%%%%% Plot cartoon head, ears, nose %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
headx = [[rx(:)' rx(1) ]*(hin+hwidth)  [rx(:)' rx(1)]*hin];
heady = [[ry(:)' ry(1) ]*(hin+hwidth)  [ry(:)' ry(1)]*hin];

patch(headx,heady,ones(size(headx)),HEADCOLOR,'edgecolor',HEADCOLOR); hold on

%%%%%%%%%%%%%%%%%%% Plot ears and nose %%%%%%%%%%%%%%%%%%%%%%%%%%%
%
base  = rmax-.0046;
basex = 0.18*rmax;                   % nose width
tip   = 1.15*rmax;
tiphw = .04*rmax;                    % nose tip half width
tipr  = .01*rmax;                    % nose tip rounding
q = .04; % ear lengthening
EarX  = [.497-.005  .510  .518  .5299 .5419  .54    .547   .532   .510   .489-.005]; % rmax = 0.5
EarY  = [q+.0555 q+.0775 q+.0783 q+.0746 q+.0555 -.0055 -.0932 -.1313 -.1384 -.1199];
sf    = headrad/plotrad;

plot3([basex;tiphw;0;-tiphw;-basex]*sf,[base;tip-tipr;tip;tip-tipr;base]*sf,...
    2*ones(size([basex;tiphw;0;-tiphw;-basex])),...
    'Color',HEADCOLOR,'LineWidth',HLINEWIDTH);                 % plot nose
plot3(EarX*sf,EarY*sf,2*ones(size(EarX)),'color',HEADCOLOR,'LineWidth',HLINEWIDTH)    % plot left ear
plot3(-EarX*sf,EarY*sf,2*ones(size(EarY)),'color',HEADCOLOR,'LineWidth',HLINEWIDTH)   % plot right ear

%
% %%%%%%%%%%%%%%%%%%% Show electrode information %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
plotax = gca;
axis square                                           % make plotax square
axis off

pos = get(gca,'position');
set(plotax,'position',pos);

xlm = get(gca,'xlim');
set(plotax,'xlim',xlm);

ylm = get(gca,'ylim');
set(plotax,'ylim',ylm);                               % copy position and axis limits again


if isempty(EMARKERSIZE)
    EMARKERSIZE = 10;
    if length(y)>=32
        EMARKERSIZE = 8;
    elseif length(y)>=48
        EMARKERSIZE = 6;
    elseif length(y)>=64
        EMARKERSIZE = 5;
    elseif length(y)>=80
        EMARKERSIZE = 4;
    elseif length(y)>=100
        EMARKERSIZE = 3;
    elseif length(y)>=128
        EMARKERSIZE = 3;
    elseif length(y)>=160
        EMARKERSIZE = 3;
    end
end
%
%%%%%%%%%%%%%%%%%%%%%%%% Mark electrode locations only %%%%%%%%%%%%%%%%%%%%%%%%%%
%
ELECTRODE_HEIGHT = 2.1;  % z value for plotting electrode information (above the surf)
plot3(y,x,ones(size(x))*ELECTRODE_HEIGHT,...
    EMARKER,'Color',ECOLOR,'markersize',EMARKERSIZE,'linewidth',EMARKERLINEWIDTH);

% praneeth - starts
numChanPairs = size(displayStruct.chanPairs, 1);
cM = colormap;
if ~isfield(displayStruct, 'connectStrength')
    cmapPos = ceil(size(cM, 1)/2)*ones(size(displayStruct.chanPairs, 1), 1);
else
    if ~isfield(displayStruct, 'connectStrengthLimits')
        displayStruct.connectStrengthLimits = [min(displayStruct.connectStrength), max(displayStruct.connectStrength)];
    end
    xp = displayStruct.connectStrengthLimits(1);
    yp = displayStruct.connectStrengthLimits(2);
    displayStruct.connectStrength(displayStruct.connectStrength < xp) = xp;
    displayStruct.connectStrength(displayStruct.connectStrength > yp) = yp;
    if xp == yp
        cmapPos = ceil(size(cM, 1)/2)*ones(size(displayStruct.chanPairs, 1), 1);
    else
        cmapPos = round((displayStruct.connectStrength - xp)/(yp - xp)*(size(cM, 1) - 1) + 1);
    end
end

for kk = 1:numChanPairs
    plot3(y(displayStruct.chanPairs(kk, :)), x(displayStruct.chanPairs(kk, :)), [ELECTRODE_HEIGHT, ELECTRODE_HEIGHT], 'LineWidth', 2, 'Color', cM(cmapPos(kk), :));
end
% praneeth - ends
set(gcf, 'color', BACKCOLOR);
return;

Contact us