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 |