Mercurial > hg > map
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utilities/UTIL_plotMatrix.m Fri May 27 13:19:21 2011 +0100 @@ -0,0 +1,350 @@ +function UTIL_plotMatrix(toPlot, method) +% UTIL_plotMatrix general purpose plotting utility for plotting the results +% of the MAP auditory model. +% All plots are placed in subplots of a figure (default figure 1). +% Input arguments: +% 'toPlot' is matrix (either numeric or logical) +% 'method' is a structure containing plot instructions +% +% surface plots have log z-axis when all values are >1 +% +% when calling this function, always increment the subPlotNo in method +% method.subPlotNo=method.subPlotNo+1; +% method.subPlotNo=method.subPlotNo; +% +% mandatory parameters: +% method.displaydt xValues spacing between data points +% method.numPlots total number of subPlots in the figure +% method.subPlotNo number of this plot +% method.yValues mandatory only for 3D plots +% +% optional +% method.figureNo normally figure(1) +% method.zValuesRange [min max] value pair to define yaxis limits +% method.zValuesRange [min max] CLIMS for 3-D plot +% method.yLabel (string) y-axis label +% method.xLabel (string) x-axis label +% method.title (string) subplot title +% method.bar =1, to force bar histogram (single channel only) +% method.view 3D plot 'view' settings e.g. [-6 40] +% method.axes (handle) used for writing to GUIs (specifies panel) +% method.maxPixels maximum number of pixels (used to speed plotting) +% method.blackOnWhite =1; % NB inverts display for 2D plots +% method.forceLog positive values are put on log z-scale +% method.rasterDotSize min value is 1 +% method.defaultFontSize +% method.timeStart default=dt +% method.defaultTextColor default ='w' +% method.defaultAxesColor default = 'w' +% method.nCols default=1 +% method.nRows default=method.numPlots +% +% useful paste for calling program +% method.numPlots=method.numPlots; +% method.subPlotNo=method.subPlotNo+1; +% method.subPlotNo=method.subPlotNo; +% dt=dt; +% method.yValues=method.nonlinCF; % for 3D plots only +% +% method.figureNo=1; +% method.yLabel='useThisLabel'; +% method.xLabel='use this label'; +% method.title='myTitle'; +% +% UTIL_plotMatrix(toPlot, method) + +dt=method.displaydt; +if ~isfield(method,'figureNo') || isempty(method.figureNo) + method.figureNo=99; +end +% if ~isfield(method,'zValuesRange') || isempty(method.zValuesRange) +% method.zValuesRange=[-inf inf]; +% end + +% set some defaults +if ~isfield( method,'plotDivider') || isempty(method.plotDivider) + method.plotDivider=0; +end +if ~isfield( method,'blackOnWhite') || isempty(method.blackOnWhite) + method.blackOnWhite=0; +end +if ~isfield(method,'timeStart')|| isempty(method.timeStart) + method.timeStart=dt; +end +if ~isfield(method,'objectDuration') || isempty(method.objectDuration) + [nRows nCols]=size(toPlot); method.objectDuration=dt*nCols; +end +if ~isfield(method,'defaultFontSize') || isempty(method.defaultFontSize) + method.defaultFontSize=12; +end +if ~isfield(method,'defaultTextColor') || isempty(method.defaultTextColor) + method.defaultTextColor='k'; + defaultTextColor=method.defaultTextColor; +else + defaultTextColor='k'; +end +if ~isfield( method,'defaultAxesColor') || isempty(method.defaultAxesColor) + method.defaultAxesColor=defaultTextColor; +end +defaultAxesColor=method.defaultAxesColor; + +% arrangement of plots in rows and columns +if ~isfield(method,'nCols') || isempty(method.nRows) + method.nCols=1; +end +if ~isfield(method,'nRows') || isempty(method.nRows) + method.nRows= method.numPlots; +end + +if ~isfield(method,'rasterDotSize') || isempty(method.rasterDotSize) + rasterDotSize=1; +else + rasterDotSize=method.rasterDotSize; +end + +% user can specify either an independent axis +% or a subplot of the current figure +% if both are specified, 'axes' takes priority +figure(method.figureNo) +if isfield(method,'axes') && ~isempty(method.axes) + % select an axis in some location other than 'figure' + h=axes(method.axes); +else + % now using a regular figure + if method.subPlotNo>method.numPlots; + error('UTIL_plotMatrix: not enough subplots allocated in figure 1. Check method.numPlots') + end + % choose subplot + subplot(method.nRows,method.nCols,method.subPlotNo), % cla + + if isfield(method,'segmentNumber') && ~isempty(method.segmentNumber)... + && method.segmentNumber>1 + % in multi-segment mode do not clear the image + % from the previous segment + hold on + else + % otherwise a fresh image will be plotted + hold off + cla + end +end + +[numYvalues numXvalues]=size(toPlot); +xValues=method.timeStart:dt:method.timeStart+dt*(numXvalues-1); + +if isfield(method,'yValues') && ~isempty(method.yValues) + % yValues is normally a vector specifying channel BF + yValues=method.yValues; +else + yValues=1:numYvalues; +end + +% Now start the plot. +% 3D plotting for 4 or more channels +% otherwise special cases for fewer channels + +if ~islogical(toPlot) + % continuous variables + switch numYvalues + case 1 % single vector (black) + if isfield(method,'bar') && ~isempty(method.bar) + % histogram + bar(xValues, toPlot,'k') + method.bar=[]; % avoid carry over between modules + else + % waveform + plot(xValues, toPlot,'k') + end + xlim([0 method.objectDuration]) + if isfield(method,'zValuesRange') ... + && ~isempty(method.zValuesRange) + ylim(method.zValuesRange) + method.zValuesRange=[]; % avoid carry over between modules + end + if isfield(method,'yLabel') && ~isempty(method.yLabel) + ylabel(method.yLabel, 'color', defaultTextColor) + method.yLabel=[]; % avoid carry over between modules + end + + case 2 % 2 x N vector (black and red) + plot(xValues, toPlot(1,:),'k'), % hold on + plot(xValues, toPlot(2,:),'r'), % hold off + xlim([0 method.objectDuration]) + if isfield(method,'zValuesRange') ... + && ~isempty(method.zValuesRange) + ylim(method.zValuesRange) + method.zValuesRange=[]; % avoid carry over between modules + end + if isfield(method,'yLabel')&& ~isempty(method.yLabel) + ylabel(method.yLabel, 'color', defaultTextColor) + method.yLabel=[]; % avoid carry over between modules + end + + case 3 % 3 x N vector (black red and green) + % this is used for 1 channel DRNL output + plot(xValues, toPlot(1,:),'k'), hold on + plot(xValues, toPlot(2,:),'r'), hold on + plot(xValues, toPlot(3,:),'g'), hold off + xlim([0 method.objectDuration]) + if isfield(method,'zValuesRange') ... + && ~isempty(method.zValuesRange) + ylim(method.zValuesRange) + end + if isfield(method,'yLabel') && ~isempty(method.yLabel) + ylabel(method.yLabel, 'color', defaultTextColor) + end + + otherwise % >3 channels: surface plot + % add white line to separate HSR and LSR + if method.plotDivider && size(toPlot,1) > 2 + [r c]=size(toPlot); +% if isempty(method.zValuesRange), method.zValuesRange=0; end +% mm=method.zValuesRange(2); + emptyLine=max(max(toPlot))*ones(2,c); + halfway=round(r/2); + toPlot=[toPlot(1:halfway,:); emptyLine; toPlot(halfway+1:end,:)]; + end + + % invert data for black on white matrix plotting + if method.blackOnWhite + toPlot=-toPlot; + end + + % matrix (analogue) plot + if isfield(method,'forceLog') && ~isempty(method.forceLog) + % positive values are put on log z-scale + toPlot=toPlot+min(min(toPlot))+1; + toPlot=log(toPlot); + if isfield(method,'title') + method.title=[method.title ' (log scale)']; + else + method.title= '(log scale)'; + end + end + + % zValuesRange + if isfield(method,'zValuesRange') ... + && ~isempty(method.zValuesRange) + % zValuesRange gives the max and min values +% a=method.zValuesRange(1); +% b=method.zValuesRange(2); +% toPlot=(toPlot-a)/(b-a); +% clims=[0 1]; + clims=(method.zValuesRange); + imagesc(xValues, yValues, toPlot, clims), axis xy; %NB assumes equally spaced y-values + else + % automatically scaled + imagesc(xValues, yValues, toPlot), axis xy; %NB assumes equally spaced y-values + + % if ~isfield(method,'zValuesRange') + % method.zValuesRange=[-inf inf]; + % end + % + % if method.blackOnWhite + % % NB plotted values have negative sign for black on white + % caxis([-method.zValuesRange(2) -method.zValuesRange(1)]) + % else + % caxis(method.zValuesRange) + % end + + if ~isfield(method,'zValuesRange')... + || isempty(method.zValuesRange) + method.zValuesRange=[-inf inf]; + end + + if method.blackOnWhite + % NB plotted values have negative sign for black on white + caxis([-method.zValuesRange(2) -method.zValuesRange(1)]) + else + caxis(method.zValuesRange) + end + end + + % xaxis + % NB segmentation may shorten signal duration + [r c]=size(toPlot); + imageDuration=c*method.displaydt; + xlim([0 imageDuration]) +% xlim([0 method.objectDuration]) + + % yaxis + if isfield(method,'minyMaxy') && ~isempty(method.minyMaxy) + ylim(method.minyMaxy) + else + if max(yValues)>min(yValues) + ylim([min(yValues) max(yValues)]) + end + end + if min(yValues)>1 % put channel array on a log scale + tickValues=[min(yValues) max(yValues)]; + set(gca,'ytick',tickValues) + set(gca,'ytickLabel', strvcat(num2str(tickValues'))) + set(gca,'FontSize', method.defaultFontSize) + end + + end + +else % is logical + + % logical implies spike array. Use raster plot + [y,x]=find(toPlot); %locate all spikes: y is fiber number ie row + x=x*dt+method.timeStart; % x is time + plot(x,y, 'o', 'MarkerSize', rasterDotSize, 'color', 'k') + if numYvalues>1 + set(gca,'yScale','linear') + set(gca,'ytick', [1 numYvalues],'FontSize', method.defaultFontSize) + % show lowest and highest BF value only + set(gca,'ytickLabel', [min(yValues) max(yValues) ],'FontSize', method.defaultFontSize) + if method.plotDivider + % or use labels to identify fiber type + set(gca,'ytickLabel', {'LSR', 'HSR'},'FontSize', method.defaultFontSize) + end + ylim([0 numYvalues+1]) + end + xlim([0 method.objectDuration]) + if isfield(method,'yLabel') && ~isempty(method.yLabel) + ylabel(method.yLabel,'FontSize', method.defaultFontSize, 'color', defaultTextColor) + end + + % add line to separate HSR and LSR + if method.plotDivider + [r c]=size(toPlot); + halfWayUp=round(r/2); + hold on + plot([0 c*method.displaydt],[halfWayUp halfWayUp], 'b') + hold off + end +end + +set(gca, 'xcolor', defaultAxesColor) +set(gca, 'ycolor', defaultAxesColor) + +% add title +if isfield(method,'title') && ~isempty(method.title) + title(method.title, 'FontSize', method.defaultFontSize, 'color', defaultTextColor) +end + +% label axes +if ~isfield(method,'axes') || isempty(method.axes) + % annotate the x-axis only if it is the last plot on a figure created by this utility + set(gca,'xtick',[],'FontSize', method.defaultFontSize) + if method.subPlotNo==method.numPlots + if isfield(method,'xLabel') && ~isempty(method.xLabel) +% set(gca,'ActivePositionProperty','outerposition') + % xlabel(method.xLabel) + xlabel(method.xLabel, 'FontSize', method.defaultFontSize, 'color', defaultTextColor) + end + set(gca,'xtickmode','auto') % add timescale to the lowest graph + end +end + +% add user labels to the y-axis if requested +if isfield(method,'yLabel') && ~isempty(method.yLabel) + ylabel(method.yLabel, 'color', defaultTextColor) +end + +% define color +if method.blackOnWhite, colormap bone, else colormap jet +end + +% drawnow