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