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
|