plot_shadedErrorBar.m 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. function varargout = plot_shadedErrorBar(x,y,errBar,varargin)
  2. % generate continuous error bar area around a line plot
  3. %
  4. % function H=shadedErrorBar(x,y,errBar, ...)
  5. %
  6. % Purpose
  7. % Makes a 2-d line plot with a pretty shaded error bar made
  8. % using patch. Error bar color is chosen automatically.
  9. %
  10. %
  11. % Inputs (required)
  12. % x - vector of x values [optional, can be left empty]
  13. % y - vector of y values or a matrix of n observations by m cases
  14. % where m has length(x);
  15. % errBar - if a vector we draw symmetric errorbars. If it has a size
  16. % of [2,length(x)] then we draw asymmetric error bars with
  17. % row 1 being the upper bar and row 2 being the lower bar
  18. % (with respect to y -- see demo). ** alternatively **
  19. % errBar can be a cellArray of two function handles. The
  20. % first defines statistic the line should be and the second
  21. % defines the error bar.
  22. %
  23. % Inputs (optional, param/value pairs)
  24. % 'lineProps' - ['-k' by default] defines the properties of
  25. % the data line. e.g.:
  26. % 'or-', or {'-or','markerfacecolor',[1,0.2,0.2]}
  27. % 'transparent' - [true by default] if true, the shaded error
  28. % bar is made transparent. However, for a transparent
  29. % vector image you will need to save as PDF, not EPS,
  30. % and set the figure renderer to "painters". An EPS
  31. % will only be transparent if you set the renderer
  32. % to OpenGL, however this makes a raster image.
  33. % 'patchSaturation'- [0.2 by default] The saturation of the patch color.
  34. %
  35. %
  36. %
  37. % Outputs
  38. % H - a structure of handles to the generated plot objects.
  39. %
  40. %
  41. % Examples:
  42. % y=randn(30,80);
  43. % x=1:size(y,2);
  44. %
  45. % 1)
  46. % shadedErrorBar(x,mean(y,1),std(y),'lineprops','g');
  47. %
  48. % 2)
  49. % shadedErrorBar(x,y,{@median,@std},'lineprops',{'r-o','markerfacecolor','r'});
  50. %
  51. % 3)
  52. % shadedErrorBar([],y,{@median,@(x) std(x)*1.96},'lineprops',{'r-o','markerfacecolor','k'});
  53. %
  54. % 4)
  55. % Overlay two transparent lines:
  56. % clf
  57. % y=randn(30,80)*10;
  58. % x=(1:size(y,2))-40;
  59. % shadedErrorBar(x,y,{@mean,@std},'lineprops','-r','transparent',1);
  60. % hold on
  61. % y=ones(30,1)*x; y=y+0.06*y.^2+randn(size(y))*10;
  62. % shadedErrorBar(x,y,{@mean,@std},'lineprops','-b','transparent',1);
  63. % hold off
  64. %
  65. %
  66. % Rob Campbell - November 2009
  67. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  68. % Parse input arguments
  69. narginchk(3,inf)
  70. params = inputParser;
  71. params.CaseSensitive = false;
  72. params.addParameter('lineProps', '-b', @(x) ischar(x) | iscell(x));
  73. params.addParameter('transparent', true, @(x) islogical(x) || x==0 || x==1);
  74. params.addParameter('patchSaturation', 0.2, @(x) isnumeric(x) && x>=0 && x<=1);
  75. params.parse(varargin{:});
  76. %Extract values from the inputParser
  77. lineProps = params.Results.lineProps;
  78. transparent = params.Results.transparent;
  79. patchSaturation = params.Results.patchSaturation;
  80. if ~iscell(lineProps), lineProps={lineProps}; end
  81. %Process y using function handles if needed to make the error bar dynamically
  82. if iscell(errBar)
  83. fun1=errBar{1};
  84. fun2=errBar{2};
  85. errBar=fun2(y);
  86. y=fun1(y);
  87. else
  88. y=y(:).';
  89. end
  90. if isempty(x)
  91. x=1:length(y);
  92. else
  93. x=x(:).';
  94. end
  95. %Make upper and lower error bars if only one was specified
  96. if length(errBar)==length(errBar(:))
  97. errBar=repmat(errBar(:)',2,1);
  98. else
  99. s=size(errBar);
  100. f=find(s==2);
  101. if isempty(f), error('errBar has the wrong size'), end
  102. if f==2, errBar=errBar'; end
  103. end
  104. if length(x) ~= length(errBar)
  105. error('length(x) must equal length(errBar)')
  106. end
  107. %Log the hold status so we don't change
  108. initialHoldStatus=ishold;
  109. if ~initialHoldStatus, hold on, end
  110. H = makePlot(x,y,errBar,lineProps,transparent,patchSaturation);
  111. if ~initialHoldStatus, hold off, end
  112. if nargout==1
  113. varargout{1}=H;
  114. end
  115. function H = makePlot(x,y,errBar,lineProps,transparent,patchSaturation)
  116. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  117. % Plot to get the parameters of the line
  118. H.mainLine=plot(x,y,lineProps{:});
  119. % Work out the color of the shaded region and associated lines.
  120. % Here we have the option of choosing alpha or a de-saturated
  121. % solid colour for the patch surface.
  122. mainLineColor=get(H.mainLine,'color');
  123. edgeColor=mainLineColor+(1-mainLineColor)*0.55;
  124. if transparent
  125. faceAlpha=patchSaturation;
  126. patchColor=mainLineColor;
  127. else
  128. faceAlpha=1;
  129. patchColor=mainLineColor+(1-mainLineColor)*(1-patchSaturation);
  130. end
  131. %Calculate the error bars
  132. uE=y+errBar(1,:);
  133. lE=y-errBar(2,:);
  134. %Add the patch error bar
  135. %Make the patch
  136. yP=[lE,fliplr(uE)];
  137. xP=[x,fliplr(x)];
  138. %remove nans otherwise patch won't work
  139. xP(isnan(yP))=[];
  140. yP(isnan(yP))=[];
  141. if(isdatetime(x))
  142. H.patch=patch(datenum(xP),yP,1);
  143. else
  144. H.patch=patch(xP,yP,1);
  145. end
  146. set(H.patch,'facecolor',patchColor, ...
  147. 'edgecolor','none', ...
  148. 'facealpha',faceAlpha)
  149. %Make pretty edges around the patch.
  150. H.edge(1)=plot(x,lE,'-','color',edgeColor);
  151. H.edge(2)=plot(x,uE,'-','color',edgeColor);
  152. uistack(H.mainLine,'top') % Bring the main line to the top