To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

The primary repository for this project is hosted at git://github.com/rmeddis/MAP.git .
This repository is a read-only copy which is updated automatically every hour.

Statistics Download as Zip
| Branch: | Revision:

root / utilities / UTIL_plotMatrix.m @ 0:f233164f4c86

History | View | Annotate | Download (13 KB)

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