-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathshadedErrorBar.m
177 lines (139 loc) · 4.8 KB
/
shadedErrorBar.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
function H=shadedErrorBar(x,y,errBar,lineProps,transparent)
% function H=shadedErrorBar(x,y,errBar,lineProps,transparent)
%
% Purpose
% Makes a 2-d line plot with a pretty shaded error bar made
% using patch. Error bar color is chosen automatically.
%
% Inputs
% x - vector of x values [optional, can be left empty]
% y - vector of y values or a matrix of n observations by m cases
% where m has length(x);
% errBar - if a vector we draw symmetric errorbars. If it has a
% size of [2,length(x)] then we draw asymmetric error bars
% with row 1 being the upper bar and row 2 being the lower
% bar. ** alternatively ** errBar can be a cellArray of
% two function handles. The first defines which statistic
% the line should be and the second defines the error
% bar.
% lineProps - [optional,'-k' by default] defines the properties of
% the data line. e.g.:
% 'or-', or {'-or','markerfacecolor',[1,0.2,0.2]}
% transparent - [optional, 0 by default] if ==1 the shaded error
% bar is made transparent, which forces the renderer
% to be openGl. However, if this is saved as .eps the
% resulting file will contain a raster not a vector
% image.
%
% Outputs
% H - a structure of handles to the generated plot objects.
%
%
% Examples
% y=randn(30,80); x=1:size(y,2);
% shadedErrorBar(x,mean(y,1),std(y),'g');
% shadedErrorBar(x,y,{@median,@std},{'r-o','markerfacecolor','r'});
% shadedErrorBar([],y,{@median,@std},{'r-o','markerfacecolor','r'});
%
% Overlay two transparent lines
% y=randn(30,80)*10; x=(1:size(y,2))-40;
% shadedErrorBar(x,y,{@mean,@std},'-r',1);
% hold on
% y=ones(30,1)*x; y=y+0.06*y.^2+randn(size(y))*10;
% shadedErrorBar(x,y,{@mean,@std},'-b',1);
% hold off
%
%
% Rob Campbell - November 2009
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Error checking
error(nargchk(3,5,nargin))
%Process y using function handles if needed to make the error bar
%dynamically
if iscell(errBar) && ~isvector(y)
fun1=errBar{1};
fun2=errBar{2};
errBar=fun2(y);
y=fun1(y);
elseif ~iscell(errBar) && isvector(y)
y=y(:)';
else
error('2nd and 3rd input arguments are not compatible')
end
if isempty(x)
x=1:length(y);
else
x=x(:)';
end
if length(x) ~= length(y)
error('inputs x and y are not of equal lengths')
end
%If only one error bar is specified then we will mirror it, turning it into
%both upper and lower bars.
if length(errBar)==length(errBar(:))
errBar=repmat(errBar(:)',2,1);
else
f=find(size(errBar)==2);
if isempty(f), error('errBar has the wrong size'), end
if f==2, errBar=errBar'; end
end
if length(x) ~= length(errBar)
error('inputs x and y must have the same length as errBar')
end
%Set default options
defaultProps={'-k'};
if nargin<4 || isempty(lineProps)
lineProps=defaultProps;
end
if ~iscell(lineProps)
lineProps={lineProps};
end
if nargin<5 || ~isnumeric(transparent)
transparent=0;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Plot the main line. We plot this first in order to extract the RGB values
% for the line colour. I am not aware of a function that does this.
H.mainLine=plot(x,y,lineProps{:});
% Work out the color of the shaded region and associated lines
% Using alpha requires the render to be openGL and so you can't
% save a vector image. On the other hand, you need alpha if you're
% overlaying lines. We therefore provide the option of choosing alpha
% or a de-saturated solid colour for the patch surface.
col=get(H.mainLine,'color');
edgeColor=col+(1-col)*0.55;
patchSaturation=0.15; %How de-saturated or transparent to make the patch
if transparent
faceAlpha=patchSaturation;
patchColor=col;
set(gcf,'renderer','openGL')
else
faceAlpha=1;
patchColor=col+(1-col)*(1-patchSaturation);
set(gcf,'renderer','painters')
end
%Calculate the y values at which we will place the error bars
uE=y+errBar(1,:);
lE=y-errBar(2,:);
%Add the error-bar plot elements
holdStatus=ishold;
if ~holdStatus, hold on, end
%Make the cordinats for the patch
yP=[lE,fliplr(uE)];
xP=[x,fliplr(x)];
%remove any nans otherwise patch won't work
xP(isnan(yP))=[];
yP(isnan(yP))=[];
H.patch=patch(xP,yP,1,'facecolor',patchColor,...
'edgecolor','none',...
'facealpha',faceAlpha);
%Make nice edges around the patch.
H.edge(1)=plot(x,lE,'-','color',edgeColor);
H.edge(2)=plot(x,uE,'-','color',edgeColor);
%The main line is now covered by the patch object and was plotted first to
%extract the RGB value of the main plot line. I am not aware of an easy way
%to change the order of plot elements on the graph so we'll just remove it
%and put it back (yuk!)
delete(H.mainLine)
H.mainLine=plot(x,y,lineProps{:});
if ~holdStatus, hold off, end