annotate utilities/UTIL_plotMatrix.m @ 0:f233164f4c86

first commit
author Ray Meddis <rmeddis@essex.ac.uk>
date Fri, 27 May 2011 13:19:21 +0100
parents
children c2204b18f4a2
rev   line source
rmeddis@0 1 function UTIL_plotMatrix(toPlot, method)
rmeddis@0 2 % UTIL_plotMatrix general purpose plotting utility for plotting the results
rmeddis@0 3 % of the MAP auditory model.
rmeddis@0 4 % All plots are placed in subplots of a figure (default figure 1).
rmeddis@0 5 % Input arguments:
rmeddis@0 6 % 'toPlot' is matrix (either numeric or logical)
rmeddis@0 7 % 'method' is a structure containing plot instructions
rmeddis@0 8 %
rmeddis@0 9 % surface plots have log z-axis when all values are >1
rmeddis@0 10 %
rmeddis@0 11 % when calling this function, always increment the subPlotNo in method
rmeddis@0 12 % method.subPlotNo=method.subPlotNo+1;
rmeddis@0 13 % method.subPlotNo=method.subPlotNo;
rmeddis@0 14 %
rmeddis@0 15 % mandatory parameters:
rmeddis@0 16 % method.displaydt xValues spacing between data points
rmeddis@0 17 % method.numPlots total number of subPlots in the figure
rmeddis@0 18 % method.subPlotNo number of this plot
rmeddis@0 19 % method.yValues mandatory only for 3D plots
rmeddis@0 20 %
rmeddis@0 21 % optional
rmeddis@0 22 % method.figureNo normally figure(1)
rmeddis@0 23 % method.zValuesRange [min max] value pair to define yaxis limits
rmeddis@0 24 % method.zValuesRange [min max] CLIMS for 3-D plot
rmeddis@0 25 % method.yLabel (string) y-axis label
rmeddis@0 26 % method.xLabel (string) x-axis label
rmeddis@0 27 % method.title (string) subplot title
rmeddis@0 28 % method.bar =1, to force bar histogram (single channel only)
rmeddis@0 29 % method.view 3D plot 'view' settings e.g. [-6 40]
rmeddis@0 30 % method.axes (handle) used for writing to GUIs (specifies panel)
rmeddis@0 31 % method.maxPixels maximum number of pixels (used to speed plotting)
rmeddis@0 32 % method.blackOnWhite =1; % NB inverts display for 2D plots
rmeddis@0 33 % method.forceLog positive values are put on log z-scale
rmeddis@0 34 % method.rasterDotSize min value is 1
rmeddis@0 35 % method.defaultFontSize
rmeddis@0 36 % method.timeStart default=dt
rmeddis@0 37 % method.defaultTextColor default ='w'
rmeddis@0 38 % method.defaultAxesColor default = 'w'
rmeddis@0 39 % method.nCols default=1
rmeddis@0 40 % method.nRows default=method.numPlots
rmeddis@0 41 %
rmeddis@0 42 % useful paste for calling program
rmeddis@0 43 % method.numPlots=method.numPlots;
rmeddis@0 44 % method.subPlotNo=method.subPlotNo+1;
rmeddis@0 45 % method.subPlotNo=method.subPlotNo;
rmeddis@0 46 % dt=dt;
rmeddis@0 47 % method.yValues=method.nonlinCF; % for 3D plots only
rmeddis@0 48 %
rmeddis@0 49 % method.figureNo=1;
rmeddis@0 50 % method.yLabel='useThisLabel';
rmeddis@0 51 % method.xLabel='use this label';
rmeddis@0 52 % method.title='myTitle';
rmeddis@0 53 %
rmeddis@0 54 % UTIL_plotMatrix(toPlot, method)
rmeddis@0 55
rmeddis@0 56 dt=method.displaydt;
rmeddis@0 57 if ~isfield(method,'figureNo') || isempty(method.figureNo)
rmeddis@0 58 method.figureNo=99;
rmeddis@0 59 end
rmeddis@0 60 % if ~isfield(method,'zValuesRange') || isempty(method.zValuesRange)
rmeddis@0 61 % method.zValuesRange=[-inf inf];
rmeddis@0 62 % end
rmeddis@0 63
rmeddis@0 64 % set some defaults
rmeddis@0 65 if ~isfield( method,'plotDivider') || isempty(method.plotDivider)
rmeddis@0 66 method.plotDivider=0;
rmeddis@0 67 end
rmeddis@0 68 if ~isfield( method,'blackOnWhite') || isempty(method.blackOnWhite)
rmeddis@0 69 method.blackOnWhite=0;
rmeddis@0 70 end
rmeddis@0 71 if ~isfield(method,'timeStart')|| isempty(method.timeStart)
rmeddis@0 72 method.timeStart=dt;
rmeddis@0 73 end
rmeddis@0 74 if ~isfield(method,'objectDuration') || isempty(method.objectDuration)
rmeddis@0 75 [nRows nCols]=size(toPlot); method.objectDuration=dt*nCols;
rmeddis@0 76 end
rmeddis@0 77 if ~isfield(method,'defaultFontSize') || isempty(method.defaultFontSize)
rmeddis@0 78 method.defaultFontSize=12;
rmeddis@0 79 end
rmeddis@0 80 if ~isfield(method,'defaultTextColor') || isempty(method.defaultTextColor)
rmeddis@0 81 method.defaultTextColor='k';
rmeddis@0 82 defaultTextColor=method.defaultTextColor;
rmeddis@0 83 else
rmeddis@0 84 defaultTextColor='k';
rmeddis@0 85 end
rmeddis@0 86 if ~isfield( method,'defaultAxesColor') || isempty(method.defaultAxesColor)
rmeddis@0 87 method.defaultAxesColor=defaultTextColor;
rmeddis@0 88 end
rmeddis@0 89 defaultAxesColor=method.defaultAxesColor;
rmeddis@0 90
rmeddis@0 91 % arrangement of plots in rows and columns
rmeddis@0 92 if ~isfield(method,'nCols') || isempty(method.nRows)
rmeddis@0 93 method.nCols=1;
rmeddis@0 94 end
rmeddis@0 95 if ~isfield(method,'nRows') || isempty(method.nRows)
rmeddis@0 96 method.nRows= method.numPlots;
rmeddis@0 97 end
rmeddis@0 98
rmeddis@0 99 if ~isfield(method,'rasterDotSize') || isempty(method.rasterDotSize)
rmeddis@0 100 rasterDotSize=1;
rmeddis@0 101 else
rmeddis@0 102 rasterDotSize=method.rasterDotSize;
rmeddis@0 103 end
rmeddis@0 104
rmeddis@0 105 % user can specify either an independent axis
rmeddis@0 106 % or a subplot of the current figure
rmeddis@0 107 % if both are specified, 'axes' takes priority
rmeddis@0 108 figure(method.figureNo)
rmeddis@0 109 if isfield(method,'axes') && ~isempty(method.axes)
rmeddis@0 110 % select an axis in some location other than 'figure'
rmeddis@0 111 h=axes(method.axes);
rmeddis@0 112 else
rmeddis@0 113 % now using a regular figure
rmeddis@0 114 if method.subPlotNo>method.numPlots;
rmeddis@0 115 error('UTIL_plotMatrix: not enough subplots allocated in figure 1. Check method.numPlots')
rmeddis@0 116 end
rmeddis@0 117 % choose subplot
rmeddis@0 118 subplot(method.nRows,method.nCols,method.subPlotNo), % cla
rmeddis@0 119
rmeddis@0 120 if isfield(method,'segmentNumber') && ~isempty(method.segmentNumber)...
rmeddis@0 121 && method.segmentNumber>1
rmeddis@0 122 % in multi-segment mode do not clear the image
rmeddis@0 123 % from the previous segment
rmeddis@0 124 hold on
rmeddis@0 125 else
rmeddis@0 126 % otherwise a fresh image will be plotted
rmeddis@0 127 hold off
rmeddis@0 128 cla
rmeddis@0 129 end
rmeddis@0 130 end
rmeddis@0 131
rmeddis@0 132 [numYvalues numXvalues]=size(toPlot);
rmeddis@0 133 xValues=method.timeStart:dt:method.timeStart+dt*(numXvalues-1);
rmeddis@0 134
rmeddis@0 135 if isfield(method,'yValues') && ~isempty(method.yValues)
rmeddis@0 136 % yValues is normally a vector specifying channel BF
rmeddis@0 137 yValues=method.yValues;
rmeddis@0 138 else
rmeddis@0 139 yValues=1:numYvalues;
rmeddis@0 140 end
rmeddis@0 141
rmeddis@0 142 % Now start the plot.
rmeddis@0 143 % 3D plotting for 4 or more channels
rmeddis@0 144 % otherwise special cases for fewer channels
rmeddis@0 145
rmeddis@0 146 if ~islogical(toPlot)
rmeddis@0 147 % continuous variables
rmeddis@0 148 switch numYvalues
rmeddis@0 149 case 1 % single vector (black)
rmeddis@0 150 if isfield(method,'bar') && ~isempty(method.bar)
rmeddis@0 151 % histogram
rmeddis@0 152 bar(xValues, toPlot,'k')
rmeddis@0 153 method.bar=[]; % avoid carry over between modules
rmeddis@0 154 else
rmeddis@0 155 % waveform
rmeddis@0 156 plot(xValues, toPlot,'k')
rmeddis@0 157 end
rmeddis@0 158 xlim([0 method.objectDuration])
rmeddis@0 159 if isfield(method,'zValuesRange') ...
rmeddis@0 160 && ~isempty(method.zValuesRange)
rmeddis@0 161 ylim(method.zValuesRange)
rmeddis@0 162 method.zValuesRange=[]; % avoid carry over between modules
rmeddis@0 163 end
rmeddis@0 164 if isfield(method,'yLabel') && ~isempty(method.yLabel)
rmeddis@0 165 ylabel(method.yLabel, 'color', defaultTextColor)
rmeddis@0 166 method.yLabel=[]; % avoid carry over between modules
rmeddis@0 167 end
rmeddis@0 168
rmeddis@0 169 case 2 % 2 x N vector (black and red)
rmeddis@0 170 plot(xValues, toPlot(1,:),'k'), % hold on
rmeddis@0 171 plot(xValues, toPlot(2,:),'r'), % hold off
rmeddis@0 172 xlim([0 method.objectDuration])
rmeddis@0 173 if isfield(method,'zValuesRange') ...
rmeddis@0 174 && ~isempty(method.zValuesRange)
rmeddis@0 175 ylim(method.zValuesRange)
rmeddis@0 176 method.zValuesRange=[]; % avoid carry over between modules
rmeddis@0 177 end
rmeddis@0 178 if isfield(method,'yLabel')&& ~isempty(method.yLabel)
rmeddis@0 179 ylabel(method.yLabel, 'color', defaultTextColor)
rmeddis@0 180 method.yLabel=[]; % avoid carry over between modules
rmeddis@0 181 end
rmeddis@0 182
rmeddis@0 183 case 3 % 3 x N vector (black red and green)
rmeddis@0 184 % this is used for 1 channel DRNL output
rmeddis@0 185 plot(xValues, toPlot(1,:),'k'), hold on
rmeddis@0 186 plot(xValues, toPlot(2,:),'r'), hold on
rmeddis@0 187 plot(xValues, toPlot(3,:),'g'), hold off
rmeddis@0 188 xlim([0 method.objectDuration])
rmeddis@0 189 if isfield(method,'zValuesRange') ...
rmeddis@0 190 && ~isempty(method.zValuesRange)
rmeddis@0 191 ylim(method.zValuesRange)
rmeddis@0 192 end
rmeddis@0 193 if isfield(method,'yLabel') && ~isempty(method.yLabel)
rmeddis@0 194 ylabel(method.yLabel, 'color', defaultTextColor)
rmeddis@0 195 end
rmeddis@0 196
rmeddis@0 197 otherwise % >3 channels: surface plot
rmeddis@0 198 % add white line to separate HSR and LSR
rmeddis@0 199 if method.plotDivider && size(toPlot,1) > 2
rmeddis@0 200 [r c]=size(toPlot);
rmeddis@0 201 % if isempty(method.zValuesRange), method.zValuesRange=0; end
rmeddis@0 202 % mm=method.zValuesRange(2);
rmeddis@0 203 emptyLine=max(max(toPlot))*ones(2,c);
rmeddis@0 204 halfway=round(r/2);
rmeddis@0 205 toPlot=[toPlot(1:halfway,:); emptyLine; toPlot(halfway+1:end,:)];
rmeddis@0 206 end
rmeddis@0 207
rmeddis@0 208 % invert data for black on white matrix plotting
rmeddis@0 209 if method.blackOnWhite
rmeddis@0 210 toPlot=-toPlot;
rmeddis@0 211 end
rmeddis@0 212
rmeddis@0 213 % matrix (analogue) plot
rmeddis@0 214 if isfield(method,'forceLog') && ~isempty(method.forceLog)
rmeddis@0 215 % positive values are put on log z-scale
rmeddis@0 216 toPlot=toPlot+min(min(toPlot))+1;
rmeddis@0 217 toPlot=log(toPlot);
rmeddis@0 218 if isfield(method,'title')
rmeddis@0 219 method.title=[method.title ' (log scale)'];
rmeddis@0 220 else
rmeddis@0 221 method.title= '(log scale)';
rmeddis@0 222 end
rmeddis@0 223 end
rmeddis@0 224
rmeddis@0 225 % zValuesRange
rmeddis@0 226 if isfield(method,'zValuesRange') ...
rmeddis@0 227 && ~isempty(method.zValuesRange)
rmeddis@0 228 % zValuesRange gives the max and min values
rmeddis@0 229 % a=method.zValuesRange(1);
rmeddis@0 230 % b=method.zValuesRange(2);
rmeddis@0 231 % toPlot=(toPlot-a)/(b-a);
rmeddis@0 232 % clims=[0 1];
rmeddis@0 233 clims=(method.zValuesRange);
rmeddis@0 234 imagesc(xValues, yValues, toPlot, clims), axis xy; %NB assumes equally spaced y-values
rmeddis@0 235 else
rmeddis@0 236 % automatically scaled
rmeddis@0 237 imagesc(xValues, yValues, toPlot), axis xy; %NB assumes equally spaced y-values
rmeddis@0 238
rmeddis@0 239 % if ~isfield(method,'zValuesRange')
rmeddis@0 240 % method.zValuesRange=[-inf inf];
rmeddis@0 241 % end
rmeddis@0 242 %
rmeddis@0 243 % if method.blackOnWhite
rmeddis@0 244 % % NB plotted values have negative sign for black on white
rmeddis@0 245 % caxis([-method.zValuesRange(2) -method.zValuesRange(1)])
rmeddis@0 246 % else
rmeddis@0 247 % caxis(method.zValuesRange)
rmeddis@0 248 % end
rmeddis@0 249
rmeddis@0 250 if ~isfield(method,'zValuesRange')...
rmeddis@0 251 || isempty(method.zValuesRange)
rmeddis@0 252 method.zValuesRange=[-inf inf];
rmeddis@0 253 end
rmeddis@0 254
rmeddis@0 255 if method.blackOnWhite
rmeddis@0 256 % NB plotted values have negative sign for black on white
rmeddis@0 257 caxis([-method.zValuesRange(2) -method.zValuesRange(1)])
rmeddis@0 258 else
rmeddis@0 259 caxis(method.zValuesRange)
rmeddis@0 260 end
rmeddis@0 261 end
rmeddis@0 262
rmeddis@0 263 % xaxis
rmeddis@0 264 % NB segmentation may shorten signal duration
rmeddis@0 265 [r c]=size(toPlot);
rmeddis@0 266 imageDuration=c*method.displaydt;
rmeddis@0 267 xlim([0 imageDuration])
rmeddis@0 268 % xlim([0 method.objectDuration])
rmeddis@0 269
rmeddis@0 270 % yaxis
rmeddis@0 271 if isfield(method,'minyMaxy') && ~isempty(method.minyMaxy)
rmeddis@0 272 ylim(method.minyMaxy)
rmeddis@0 273 else
rmeddis@0 274 if max(yValues)>min(yValues)
rmeddis@0 275 ylim([min(yValues) max(yValues)])
rmeddis@0 276 end
rmeddis@0 277 end
rmeddis@0 278 if min(yValues)>1 % put channel array on a log scale
rmeddis@0 279 tickValues=[min(yValues) max(yValues)];
rmeddis@0 280 set(gca,'ytick',tickValues)
rmeddis@0 281 set(gca,'ytickLabel', strvcat(num2str(tickValues')))
rmeddis@0 282 set(gca,'FontSize', method.defaultFontSize)
rmeddis@0 283 end
rmeddis@0 284
rmeddis@0 285 end
rmeddis@0 286
rmeddis@0 287 else % is logical
rmeddis@0 288
rmeddis@0 289 % logical implies spike array. Use raster plot
rmeddis@0 290 [y,x]=find(toPlot); %locate all spikes: y is fiber number ie row
rmeddis@0 291 x=x*dt+method.timeStart; % x is time
rmeddis@0 292 plot(x,y, 'o', 'MarkerSize', rasterDotSize, 'color', 'k')
rmeddis@0 293 if numYvalues>1
rmeddis@0 294 set(gca,'yScale','linear')
rmeddis@0 295 set(gca,'ytick', [1 numYvalues],'FontSize', method.defaultFontSize)
rmeddis@0 296 % show lowest and highest BF value only
rmeddis@0 297 set(gca,'ytickLabel', [min(yValues) max(yValues) ],'FontSize', method.defaultFontSize)
rmeddis@0 298 if method.plotDivider
rmeddis@0 299 % or use labels to identify fiber type
rmeddis@0 300 set(gca,'ytickLabel', {'LSR', 'HSR'},'FontSize', method.defaultFontSize)
rmeddis@0 301 end
rmeddis@0 302 ylim([0 numYvalues+1])
rmeddis@0 303 end
rmeddis@0 304 xlim([0 method.objectDuration])
rmeddis@0 305 if isfield(method,'yLabel') && ~isempty(method.yLabel)
rmeddis@0 306 ylabel(method.yLabel,'FontSize', method.defaultFontSize, 'color', defaultTextColor)
rmeddis@0 307 end
rmeddis@0 308
rmeddis@0 309 % add line to separate HSR and LSR
rmeddis@0 310 if method.plotDivider
rmeddis@0 311 [r c]=size(toPlot);
rmeddis@0 312 halfWayUp=round(r/2);
rmeddis@0 313 hold on
rmeddis@0 314 plot([0 c*method.displaydt],[halfWayUp halfWayUp], 'b')
rmeddis@0 315 hold off
rmeddis@0 316 end
rmeddis@0 317 end
rmeddis@0 318
rmeddis@0 319 set(gca, 'xcolor', defaultAxesColor)
rmeddis@0 320 set(gca, 'ycolor', defaultAxesColor)
rmeddis@0 321
rmeddis@0 322 % add title
rmeddis@0 323 if isfield(method,'title') && ~isempty(method.title)
rmeddis@0 324 title(method.title, 'FontSize', method.defaultFontSize, 'color', defaultTextColor)
rmeddis@0 325 end
rmeddis@0 326
rmeddis@0 327 % label axes
rmeddis@0 328 if ~isfield(method,'axes') || isempty(method.axes)
rmeddis@0 329 % annotate the x-axis only if it is the last plot on a figure created by this utility
rmeddis@0 330 set(gca,'xtick',[],'FontSize', method.defaultFontSize)
rmeddis@0 331 if method.subPlotNo==method.numPlots
rmeddis@0 332 if isfield(method,'xLabel') && ~isempty(method.xLabel)
rmeddis@0 333 % set(gca,'ActivePositionProperty','outerposition')
rmeddis@0 334 % xlabel(method.xLabel)
rmeddis@0 335 xlabel(method.xLabel, 'FontSize', method.defaultFontSize, 'color', defaultTextColor)
rmeddis@0 336 end
rmeddis@0 337 set(gca,'xtickmode','auto') % add timescale to the lowest graph
rmeddis@0 338 end
rmeddis@0 339 end
rmeddis@0 340
rmeddis@0 341 % add user labels to the y-axis if requested
rmeddis@0 342 if isfield(method,'yLabel') && ~isempty(method.yLabel)
rmeddis@0 343 ylabel(method.yLabel, 'color', defaultTextColor)
rmeddis@0 344 end
rmeddis@0 345
rmeddis@0 346 % define color
rmeddis@0 347 if method.blackOnWhite, colormap bone, else colormap jet
rmeddis@0 348 end
rmeddis@0 349
rmeddis@0 350 % drawnow