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