Mercurial > hg > map
comparison utilities/UTIL_plotMatrix.m @ 38:c2204b18f4a2 tip
End nov big change
| author | Ray Meddis <rmeddis@essex.ac.uk> |
|---|---|
| date | Mon, 28 Nov 2011 13:34:28 +0000 |
| parents | f233164f4c86 |
| children |
comparison
equal
deleted
inserted
replaced
| 37:771a643d5c29 | 38:c2204b18f4a2 |
|---|---|
| 1 function UTIL_plotMatrix(toPlot, method) | 1 function UTIL_plotMatrix(toPlot, method) |
| 2 % UTIL_plotMatrix general purpose plotting utility for plotting the results | 2 % UTIL_plotMatrix general purpose plotting utility for plotting the results |
| 3 % of the MAP auditory model. | 3 % of the MAP auditory model. |
| 4 % All plots are placed in subplots of a figure (default figure 1). | 4 % All plots are placed in subplots of a figure (default figure 1). |
| 5 % | |
| 5 % Input arguments: | 6 % Input arguments: |
| 6 % 'toPlot' is matrix (either numeric or logical) | 7 % 'toPlot' is matrix (either numeric or logical) |
| 7 % 'method' is a structure containing plot instructions | 8 % 'method' is a structure containing plot instructions |
| 8 % | 9 % |
| 9 % surface plots have log z-axis when all values are >1 | |
| 10 % | |
| 11 % when calling this function, always increment the subPlotNo in method | |
| 12 % method.subPlotNo=method.subPlotNo+1; | |
| 13 % method.subPlotNo=method.subPlotNo; | |
| 14 % | |
| 15 % mandatory parameters: | 10 % mandatory parameters: |
| 16 % method.displaydt xValues spacing between data points | 11 % method.displaydt xValues spacing between data points |
| 17 % method.numPlots total number of subPlots in the figure | 12 % method.yValues yaxis labels mandatory only for 3D plots |
| 18 % method.subPlotNo number of this plot | |
| 19 % method.yValues mandatory only for 3D plots | |
| 20 % | 13 % |
| 21 % optional | 14 % optional |
| 22 % method.figureNo normally figure(1) | 15 % method.figureNo default figure(1) |
| 23 % method.zValuesRange [min max] value pair to define yaxis limits | 16 % method.numPlots number of subPlots in the figure (default=1) |
| 24 % method.zValuesRange [min max] CLIMS for 3-D plot | 17 % method.subPlotNo number of this plot (default=1) |
| 25 % method.yLabel (string) y-axis label | 18 % method.zValuesRange [min max] value pair to define yaxis limits |
| 26 % method.xLabel (string) x-axis label | 19 % method.zValuesRange [min max] CLIMS for 3-D plot |
| 27 % method.title (string) subplot title | 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 | |
| 28 % method.bar =1, to force bar histogram (single channel only) | 24 % method.bar =1, to force bar histogram (single channel only) |
| 29 % method.view 3D plot 'view' settings e.g. [-6 40] | 25 % method.view 3D plot 'view' settings e.g. [-6 40] |
| 30 % method.axes (handle) used for writing to GUIs (specifies panel) | 26 % method.axes (handle) where to plot (overules all others) |
| 31 % method.maxPixels maximum number of pixels (used to speed plotting) | 27 % method.maxPixels maximum number of pixels (used to speed plotting) |
| 32 % method.blackOnWhite =1; % NB inverts display for 2D plots | 28 % method.blackOnWhite =1; inverts display for 2D plots |
| 33 % method.forceLog positive values are put on log z-scale | 29 % method.forceLog positive values are put on log z-scale |
| 34 % method.rasterDotSize min value is 1 | 30 % method.rasterDotSize min value is 1 |
| 35 % method.defaultFontSize | 31 % method.defaultFontSize deafult= 12 |
| 36 % method.timeStart default=dt | 32 % method.timeStart default= dt |
| 37 % method.defaultTextColor default ='w' | 33 % method.defaultTextColor default ='k' |
| 38 % method.defaultAxesColor default = 'w' | 34 % method.defaultAxesColor default ='k' |
| 39 % method.nCols default=1 | 35 % method.nCols default = 1 (layout for subplots) |
| 40 % method.nRows default=method.numPlots | 36 % method.nRows default=method.numPlots (layout for subplots |
| 37 % method.segmentNumber plot only this segment while 'hold on' | |
| 41 % | 38 % |
| 42 % useful paste for calling program | 39 % e.g. |
| 43 % method.numPlots=method.numPlots; | |
| 44 % method.subPlotNo=method.subPlotNo+1; | |
| 45 % method.subPlotNo=method.subPlotNo; | |
| 46 % dt=dt; | |
| 47 % method.yValues=method.nonlinCF; % for 3D plots only | |
| 48 % | |
| 49 % method.figureNo=1; | |
| 50 % method.yLabel='useThisLabel'; | |
| 51 % method.xLabel='use this label'; | |
| 52 % method.title='myTitle'; | |
| 53 % | |
| 54 % UTIL_plotMatrix(toPlot, method) | 40 % UTIL_plotMatrix(toPlot, method) |
| 55 | 41 |
| 56 dt=method.displaydt; | 42 dt=method.displaydt; |
| 43 [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 | |
| 57 if ~isfield(method,'figureNo') || isempty(method.figureNo) | 54 if ~isfield(method,'figureNo') || isempty(method.figureNo) |
| 58 method.figureNo=99; | 55 method.figureNo=99; |
| 59 end | 56 end |
| 57 | |
| 60 % if ~isfield(method,'zValuesRange') || isempty(method.zValuesRange) | 58 % if ~isfield(method,'zValuesRange') || isempty(method.zValuesRange) |
| 61 % method.zValuesRange=[-inf inf]; | 59 % method.zValuesRange=[-inf inf]; |
| 62 % end | 60 % end |
| 63 | 61 |
| 64 % set some defaults | 62 % set some defaults |
| 65 if ~isfield( method,'plotDivider') || isempty(method.plotDivider) | |
| 66 method.plotDivider=0; | |
| 67 end | |
| 68 if ~isfield( method,'blackOnWhite') || isempty(method.blackOnWhite) | 63 if ~isfield( method,'blackOnWhite') || isempty(method.blackOnWhite) |
| 69 method.blackOnWhite=0; | 64 method.blackOnWhite=0; |
| 70 end | 65 end |
| 71 if ~isfield(method,'timeStart')|| isempty(method.timeStart) | 66 if ~isfield(method,'timeStart')|| isempty(method.timeStart) |
| 72 method.timeStart=dt; | 67 method.timeStart=dt; |
| 73 end | 68 end |
| 74 if ~isfield(method,'objectDuration') || isempty(method.objectDuration) | 69 if ~isfield(method,'objectDuration') || isempty(method.objectDuration) |
| 75 [nRows nCols]=size(toPlot); method.objectDuration=dt*nCols; | 70 [nRows nCols]=size(toPlot); method.objectDuration=dt*nCols; |
| 76 end | 71 end |
| 77 if ~isfield(method,'defaultFontSize') || isempty(method.defaultFontSize) | 72 if ~isfield(method,'defaultFontSize') || isempty(method.defaultFontSize) |
| 78 method.defaultFontSize=12; | 73 method.defaultFontSize=12; |
| 79 end | 74 end |
| 80 if ~isfield(method,'defaultTextColor') || isempty(method.defaultTextColor) | 75 if ~isfield(method,'defaultTextColor') || isempty(method.defaultTextColor) |
| 81 method.defaultTextColor='k'; | 76 method.defaultTextColor='k'; |
| 82 defaultTextColor=method.defaultTextColor; | 77 defaultTextColor=method.defaultTextColor; |
| 83 else | 78 else |
| 84 defaultTextColor='k'; | 79 defaultTextColor='k'; |
| 85 end | 80 end |
| 86 if ~isfield( method,'defaultAxesColor') || isempty(method.defaultAxesColor) | 81 if ~isfield( method,'defaultAxesColor') || isempty(method.defaultAxesColor) |
| 87 method.defaultAxesColor=defaultTextColor; | 82 method.defaultAxesColor=defaultTextColor; |
| 88 end | 83 end |
| 89 defaultAxesColor=method.defaultAxesColor; | 84 defaultAxesColor=method.defaultAxesColor; |
| 90 | 85 |
| 91 % arrangement of plots in rows and columns | 86 % arrangement of plots in rows and columns |
| 92 if ~isfield(method,'nCols') || isempty(method.nRows) | 87 if ~isfield(method,'nCols') || isempty(method.nRows) |
| 105 % user can specify either an independent axis | 100 % user can specify either an independent axis |
| 106 % or a subplot of the current figure | 101 % or a subplot of the current figure |
| 107 % if both are specified, 'axes' takes priority | 102 % if both are specified, 'axes' takes priority |
| 108 figure(method.figureNo) | 103 figure(method.figureNo) |
| 109 if isfield(method,'axes') && ~isempty(method.axes) | 104 if isfield(method,'axes') && ~isempty(method.axes) |
| 110 % select an axis in some location other than 'figure' | 105 % user defines where to plot it |
| 111 h=axes(method.axes); | 106 axes(method.axes); |
| 107 method.numPlots =1; | |
| 108 method.subPlotNo =1; | |
| 109 | |
| 112 else | 110 else |
| 113 % now using a regular figure | 111 % now using a regular figure |
| 114 if method.subPlotNo>method.numPlots; | 112 if method.subPlotNo>method.numPlots; |
| 115 error('UTIL_plotMatrix: not enough subplots allocated in figure 1. Check method.numPlots') | 113 error('UTIL_plotMatrix: not enough subplots allocated in figure 1. Check method.numPlots') |
| 116 end | 114 end |
| 117 % choose subplot | 115 % choose subplot |
| 118 subplot(method.nRows,method.nCols,method.subPlotNo), % cla | 116 subplot(method.nRows,method.nCols,method.subPlotNo), % cla |
| 119 | 117 |
| 120 if isfield(method,'segmentNumber') && ~isempty(method.segmentNumber)... | 118 if isfield(method,'segmentNumber') && ~isempty(method.segmentNumber)... |
| 121 && method.segmentNumber>1 | 119 && method.segmentNumber>1 |
| 122 % in multi-segment mode do not clear the image | 120 % in multi-segment mode do not clear the image |
| 123 % from the previous segment | 121 % from the previous segment |
| 124 hold on | 122 hold on |
| 125 else | 123 else |
| 126 % otherwise a fresh image will be plotted | 124 % otherwise a fresh image will be plotted |
| 127 hold off | 125 hold off |
| 135 if isfield(method,'yValues') && ~isempty(method.yValues) | 133 if isfield(method,'yValues') && ~isempty(method.yValues) |
| 136 % yValues is normally a vector specifying channel BF | 134 % yValues is normally a vector specifying channel BF |
| 137 yValues=method.yValues; | 135 yValues=method.yValues; |
| 138 else | 136 else |
| 139 yValues=1:numYvalues; | 137 yValues=1:numYvalues; |
| 138 end | |
| 139 | |
| 140 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; | |
| 140 end | 146 end |
| 141 | 147 |
| 142 % Now start the plot. | 148 % Now start the plot. |
| 143 % 3D plotting for 4 or more channels | 149 % 3D plotting for 4 or more channels |
| 144 % otherwise special cases for fewer channels | 150 % otherwise special cases for fewer channels |
| 193 if isfield(method,'yLabel') && ~isempty(method.yLabel) | 199 if isfield(method,'yLabel') && ~isempty(method.yLabel) |
| 194 ylabel(method.yLabel, 'color', defaultTextColor) | 200 ylabel(method.yLabel, 'color', defaultTextColor) |
| 195 end | 201 end |
| 196 | 202 |
| 197 otherwise % >3 channels: surface plot | 203 otherwise % >3 channels: surface plot |
| 198 % add white line to separate HSR and LSR | 204 % add line to separate HSR and LSR |
| 199 if method.plotDivider && size(toPlot,1) > 2 | 205 if method.plotDivider && size(toPlot,1) > 2 |
| 200 [r c]=size(toPlot); | 206 [r c]=size(toPlot); |
| 201 % if isempty(method.zValuesRange), method.zValuesRange=0; end | |
| 202 % mm=method.zValuesRange(2); | |
| 203 emptyLine=max(max(toPlot))*ones(2,c); | 207 emptyLine=max(max(toPlot))*ones(2,c); |
| 204 halfway=round(r/2); | 208 halfway=round(r/2); |
| 205 toPlot=[toPlot(1:halfway,:); emptyLine; toPlot(halfway+1:end,:)]; | 209 toPlot=[toPlot(1:halfway,:); emptyLine; toPlot(halfway+1:end,:)]; |
| 206 end | 210 end |
| 207 | 211 |
| 223 end | 227 end |
| 224 | 228 |
| 225 % zValuesRange | 229 % zValuesRange |
| 226 if isfield(method,'zValuesRange') ... | 230 if isfield(method,'zValuesRange') ... |
| 227 && ~isempty(method.zValuesRange) | 231 && ~isempty(method.zValuesRange) |
| 228 % zValuesRange gives the max and min values | |
| 229 % a=method.zValuesRange(1); | |
| 230 % b=method.zValuesRange(2); | |
| 231 % toPlot=(toPlot-a)/(b-a); | |
| 232 % clims=[0 1]; | |
| 233 clims=(method.zValuesRange); | 232 clims=(method.zValuesRange); |
| 234 imagesc(xValues, yValues, toPlot, clims), axis xy; %NB assumes equally spaced y-values | 233 imagesc(xValues, yValues, toPlot, clims), axis xy; %NB assumes equally spaced y-values |
| 235 else | 234 else |
| 236 % automatically scaled | 235 % automatically scaled |
| 237 imagesc(xValues, yValues, toPlot), axis xy; %NB assumes equally spaced y-values | 236 imagesc(xValues, yValues, toPlot), axis xy; %NB assumes equally spaced y-values |
| 238 | 237 |
| 239 % if ~isfield(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 | |
| 250 if ~isfield(method,'zValuesRange')... | 238 if ~isfield(method,'zValuesRange')... |
| 251 || isempty(method.zValuesRange) | 239 || isempty(method.zValuesRange) |
| 252 method.zValuesRange=[-inf inf]; | 240 method.zValuesRange=[-inf inf]; |
| 253 end | 241 end |
| 254 | 242 |
| 262 | 250 |
| 263 % xaxis | 251 % xaxis |
| 264 % NB segmentation may shorten signal duration | 252 % NB segmentation may shorten signal duration |
| 265 [r c]=size(toPlot); | 253 [r c]=size(toPlot); |
| 266 imageDuration=c*method.displaydt; | 254 imageDuration=c*method.displaydt; |
| 267 xlim([0 imageDuration]) | 255 xlim([0 imageDuration]) |
| 268 % xlim([0 method.objectDuration]) | 256 |
| 269 | |
| 270 % yaxis | 257 % yaxis |
| 271 if isfield(method,'minyMaxy') && ~isempty(method.minyMaxy) | 258 if isfield(method,'minyMaxy') && ~isempty(method.minyMaxy) |
| 272 ylim(method.minyMaxy) | 259 ylim(method.minyMaxy) |
| 273 else | 260 else |
| 274 if max(yValues)>min(yValues) | 261 if max(yValues)>min(yValues) |
| 275 ylim([min(yValues) max(yValues)]) | 262 ylim([min(yValues) max(yValues)]) |
| 276 end | 263 end |
| 277 end | 264 end |
| 278 if min(yValues)>1 % put channel array on a log scale | 265 |
| 266 % y-axis design yTickLabels | |
| 267 if min(yValues)>1 | |
| 279 tickValues=[min(yValues) max(yValues)]; | 268 tickValues=[min(yValues) max(yValues)]; |
| 269 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 set(gca,'ytick',tickValues) | 280 set(gca,'ytick',tickValues) |
| 281 set(gca,'ytickLabel', strvcat(num2str(tickValues'))) | 281 set(gca,'ytickLabel', strvcat(tickLabels)) |
| 282 set(gca,'FontSize', method.defaultFontSize) | 282 set(gca,'FontSize', method.defaultFontSize) |
| 283 end | 283 end |
| 284 | 284 |
| 285 end | 285 end |
| 286 | 286 |
| 287 else % is logical | 287 else % is logical |
| 288 | |
| 289 % logical implies spike array. Use raster plot | 288 % logical implies spike array. Use raster plot |
| 290 [y,x]=find(toPlot); %locate all spikes: y is fiber number ie row | 289 [y,x]=find(toPlot); %locate all spikes: y is fiber number ie row |
| 291 x=x*dt+method.timeStart; % x is time | 290 x=x*dt+method.timeStart; % x is time |
| 292 plot(x,y, 'o', 'MarkerSize', rasterDotSize, 'color', 'k') | 291 plot(x,y, 'o', 'MarkerSize', rasterDotSize, 'color', 'k') |
| 293 if numYvalues>1 | 292 if numYvalues>1 |
| 312 halfWayUp=round(r/2); | 311 halfWayUp=round(r/2); |
| 313 hold on | 312 hold on |
| 314 plot([0 c*method.displaydt],[halfWayUp halfWayUp], 'b') | 313 plot([0 c*method.displaydt],[halfWayUp halfWayUp], 'b') |
| 315 hold off | 314 hold off |
| 316 end | 315 end |
| 316 | |
| 317 end | 317 end |
| 318 | 318 |
| 319 set(gca, 'xcolor', defaultAxesColor) | 319 set(gca, 'xcolor', defaultAxesColor) |
| 320 set(gca, 'ycolor', defaultAxesColor) | 320 set(gca, 'ycolor', defaultAxesColor) |
| 321 | 321 |
| 328 if ~isfield(method,'axes') || isempty(method.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 | 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) | 330 set(gca,'xtick',[],'FontSize', method.defaultFontSize) |
| 331 if method.subPlotNo==method.numPlots | 331 if method.subPlotNo==method.numPlots |
| 332 if isfield(method,'xLabel') && ~isempty(method.xLabel) | 332 if isfield(method,'xLabel') && ~isempty(method.xLabel) |
| 333 % set(gca,'ActivePositionProperty','outerposition') | 333 % set(gca,'ActivePositionProperty','outerposition') |
| 334 % xlabel(method.xLabel) | 334 % xlabel(method.xLabel) |
| 335 xlabel(method.xLabel, 'FontSize', method.defaultFontSize, 'color', defaultTextColor) | 335 xlabel(method.xLabel, 'FontSize', method.defaultFontSize, 'color', defaultTextColor) |
| 336 end | 336 end |
| 337 set(gca,'xtickmode','auto') % add timescale to the lowest graph | 337 set(gca,'xtickmode','auto') % add timescale to the lowest graph |
| 338 end | 338 end |
