comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:f233164f4c86
1 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 % Input arguments:
6 % 'toPlot' is matrix (either numeric or logical)
7 % 'method' is a structure containing plot instructions
8 %
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:
16 % method.displaydt xValues spacing between data points
17 % method.numPlots total number of subPlots in the figure
18 % method.subPlotNo number of this plot
19 % method.yValues mandatory only for 3D plots
20 %
21 % optional
22 % method.figureNo normally figure(1)
23 % method.zValuesRange [min max] value pair to define yaxis limits
24 % method.zValuesRange [min max] CLIMS for 3-D plot
25 % method.yLabel (string) y-axis label
26 % method.xLabel (string) x-axis label
27 % method.title (string) subplot title
28 % method.bar =1, to force bar histogram (single channel only)
29 % method.view 3D plot 'view' settings e.g. [-6 40]
30 % method.axes (handle) used for writing to GUIs (specifies panel)
31 % method.maxPixels maximum number of pixels (used to speed plotting)
32 % method.blackOnWhite =1; % NB inverts display for 2D plots
33 % method.forceLog positive values are put on log z-scale
34 % method.rasterDotSize min value is 1
35 % method.defaultFontSize
36 % method.timeStart default=dt
37 % method.defaultTextColor default ='w'
38 % method.defaultAxesColor default = 'w'
39 % method.nCols default=1
40 % method.nRows default=method.numPlots
41 %
42 % useful paste for calling program
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)
55
56 dt=method.displaydt;
57 if ~isfield(method,'figureNo') || isempty(method.figureNo)
58 method.figureNo=99;
59 end
60 % if ~isfield(method,'zValuesRange') || isempty(method.zValuesRange)
61 % method.zValuesRange=[-inf inf];
62 % end
63
64 % 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)
69 method.blackOnWhite=0;
70 end
71 if ~isfield(method,'timeStart')|| isempty(method.timeStart)
72 method.timeStart=dt;
73 end
74 if ~isfield(method,'objectDuration') || isempty(method.objectDuration)
75 [nRows nCols]=size(toPlot); method.objectDuration=dt*nCols;
76 end
77 if ~isfield(method,'defaultFontSize') || isempty(method.defaultFontSize)
78 method.defaultFontSize=12;
79 end
80 if ~isfield(method,'defaultTextColor') || isempty(method.defaultTextColor)
81 method.defaultTextColor='k';
82 defaultTextColor=method.defaultTextColor;
83 else
84 defaultTextColor='k';
85 end
86 if ~isfield( method,'defaultAxesColor') || isempty(method.defaultAxesColor)
87 method.defaultAxesColor=defaultTextColor;
88 end
89 defaultAxesColor=method.defaultAxesColor;
90
91 % arrangement of plots in rows and columns
92 if ~isfield(method,'nCols') || isempty(method.nRows)
93 method.nCols=1;
94 end
95 if ~isfield(method,'nRows') || isempty(method.nRows)
96 method.nRows= method.numPlots;
97 end
98
99 if ~isfield(method,'rasterDotSize') || isempty(method.rasterDotSize)
100 rasterDotSize=1;
101 else
102 rasterDotSize=method.rasterDotSize;
103 end
104
105 % user can specify either an independent axis
106 % or a subplot of the current figure
107 % if both are specified, 'axes' takes priority
108 figure(method.figureNo)
109 if isfield(method,'axes') && ~isempty(method.axes)
110 % select an axis in some location other than 'figure'
111 h=axes(method.axes);
112 else
113 % now using a regular figure
114 if method.subPlotNo>method.numPlots;
115 error('UTIL_plotMatrix: not enough subplots allocated in figure 1. Check method.numPlots')
116 end
117 % choose subplot
118 subplot(method.nRows,method.nCols,method.subPlotNo), % cla
119
120 if isfield(method,'segmentNumber') && ~isempty(method.segmentNumber)...
121 && method.segmentNumber>1
122 % in multi-segment mode do not clear the image
123 % from the previous segment
124 hold on
125 else
126 % otherwise a fresh image will be plotted
127 hold off
128 cla
129 end
130 end
131
132 [numYvalues numXvalues]=size(toPlot);
133 xValues=method.timeStart:dt:method.timeStart+dt*(numXvalues-1);
134
135 if isfield(method,'yValues') && ~isempty(method.yValues)
136 % yValues is normally a vector specifying channel BF
137 yValues=method.yValues;
138 else
139 yValues=1:numYvalues;
140 end
141
142 % Now start the plot.
143 % 3D plotting for 4 or more channels
144 % otherwise special cases for fewer channels
145
146 if ~islogical(toPlot)
147 % continuous variables
148 switch numYvalues
149 case 1 % single vector (black)
150 if isfield(method,'bar') && ~isempty(method.bar)
151 % histogram
152 bar(xValues, toPlot,'k')
153 method.bar=[]; % avoid carry over between modules
154 else
155 % waveform
156 plot(xValues, toPlot,'k')
157 end
158 xlim([0 method.objectDuration])
159 if isfield(method,'zValuesRange') ...
160 && ~isempty(method.zValuesRange)
161 ylim(method.zValuesRange)
162 method.zValuesRange=[]; % avoid carry over between modules
163 end
164 if isfield(method,'yLabel') && ~isempty(method.yLabel)
165 ylabel(method.yLabel, 'color', defaultTextColor)
166 method.yLabel=[]; % avoid carry over between modules
167 end
168
169 case 2 % 2 x N vector (black and red)
170 plot(xValues, toPlot(1,:),'k'), % hold on
171 plot(xValues, toPlot(2,:),'r'), % hold off
172 xlim([0 method.objectDuration])
173 if isfield(method,'zValuesRange') ...
174 && ~isempty(method.zValuesRange)
175 ylim(method.zValuesRange)
176 method.zValuesRange=[]; % avoid carry over between modules
177 end
178 if isfield(method,'yLabel')&& ~isempty(method.yLabel)
179 ylabel(method.yLabel, 'color', defaultTextColor)
180 method.yLabel=[]; % avoid carry over between modules
181 end
182
183 case 3 % 3 x N vector (black red and green)
184 % this is used for 1 channel DRNL output
185 plot(xValues, toPlot(1,:),'k'), hold on
186 plot(xValues, toPlot(2,:),'r'), hold on
187 plot(xValues, toPlot(3,:),'g'), hold off
188 xlim([0 method.objectDuration])
189 if isfield(method,'zValuesRange') ...
190 && ~isempty(method.zValuesRange)
191 ylim(method.zValuesRange)
192 end
193 if isfield(method,'yLabel') && ~isempty(method.yLabel)
194 ylabel(method.yLabel, 'color', defaultTextColor)
195 end
196
197 otherwise % >3 channels: surface plot
198 % add white line to separate HSR and LSR
199 if method.plotDivider && size(toPlot,1) > 2
200 [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);
204 halfway=round(r/2);
205 toPlot=[toPlot(1:halfway,:); emptyLine; toPlot(halfway+1:end,:)];
206 end
207
208 % invert data for black on white matrix plotting
209 if method.blackOnWhite
210 toPlot=-toPlot;
211 end
212
213 % matrix (analogue) plot
214 if isfield(method,'forceLog') && ~isempty(method.forceLog)
215 % positive values are put on log z-scale
216 toPlot=toPlot+min(min(toPlot))+1;
217 toPlot=log(toPlot);
218 if isfield(method,'title')
219 method.title=[method.title ' (log scale)'];
220 else
221 method.title= '(log scale)';
222 end
223 end
224
225 % zValuesRange
226 if isfield(method,'zValuesRange') ...
227 && ~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);
234 imagesc(xValues, yValues, toPlot, clims), axis xy; %NB assumes equally spaced y-values
235 else
236 % automatically scaled
237 imagesc(xValues, yValues, toPlot), axis xy; %NB assumes equally spaced y-values
238
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')...
251 || isempty(method.zValuesRange)
252 method.zValuesRange=[-inf inf];
253 end
254
255 if method.blackOnWhite
256 % NB plotted values have negative sign for black on white
257 caxis([-method.zValuesRange(2) -method.zValuesRange(1)])
258 else
259 caxis(method.zValuesRange)
260 end
261 end
262
263 % xaxis
264 % NB segmentation may shorten signal duration
265 [r c]=size(toPlot);
266 imageDuration=c*method.displaydt;
267 xlim([0 imageDuration])
268 % xlim([0 method.objectDuration])
269
270 % yaxis
271 if isfield(method,'minyMaxy') && ~isempty(method.minyMaxy)
272 ylim(method.minyMaxy)
273 else
274 if max(yValues)>min(yValues)
275 ylim([min(yValues) max(yValues)])
276 end
277 end
278 if min(yValues)>1 % put channel array on a log scale
279 tickValues=[min(yValues) max(yValues)];
280 set(gca,'ytick',tickValues)
281 set(gca,'ytickLabel', strvcat(num2str(tickValues')))
282 set(gca,'FontSize', method.defaultFontSize)
283 end
284
285 end
286
287 else % is logical
288
289 % logical implies spike array. Use raster plot
290 [y,x]=find(toPlot); %locate all spikes: y is fiber number ie row
291 x=x*dt+method.timeStart; % x is time
292 plot(x,y, 'o', 'MarkerSize', rasterDotSize, 'color', 'k')
293 if numYvalues>1
294 set(gca,'yScale','linear')
295 set(gca,'ytick', [1 numYvalues],'FontSize', method.defaultFontSize)
296 % show lowest and highest BF value only
297 set(gca,'ytickLabel', [min(yValues) max(yValues) ],'FontSize', method.defaultFontSize)
298 if method.plotDivider
299 % or use labels to identify fiber type
300 set(gca,'ytickLabel', {'LSR', 'HSR'},'FontSize', method.defaultFontSize)
301 end
302 ylim([0 numYvalues+1])
303 end
304 xlim([0 method.objectDuration])
305 if isfield(method,'yLabel') && ~isempty(method.yLabel)
306 ylabel(method.yLabel,'FontSize', method.defaultFontSize, 'color', defaultTextColor)
307 end
308
309 % add line to separate HSR and LSR
310 if method.plotDivider
311 [r c]=size(toPlot);
312 halfWayUp=round(r/2);
313 hold on
314 plot([0 c*method.displaydt],[halfWayUp halfWayUp], 'b')
315 hold off
316 end
317 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 % set(gca,'ActivePositionProperty','outerposition')
334 % 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