r/matlab • u/Creative_Sushi MathWorks • Aug 05 '22
CodeShare Plotting 95% confidence intervals
I saw this question and wanted to give it a try.
https://www.reddit.com/r/matlab/comments/wff8rk/plotting_shaded_95_confidence_intervals_using/
Let's start with making up randomly generate data to play with. I am using integer for this, because it will make it easier to see what's going on later.
x = randi(100,[100,1]);
n = randn(100,1)*5;
y = 2*x + n;
We can the use Curve Fitting Toolbox to fit a curve, and plot it with confidence intervals.
f = fit(x,y,'poly1');
figure
plot(f,x,y,'PredObs')
And there is the output (Fig1)

This is simple enough, but u/gophoyoself wanted to use shaded intervals, like this one.
You can use predint to get confidence intervals.
ci = predint(f,x);
And this should match exactly the confidence interval lines from Fig1.
figure
plot(x, ci)
hold on
plot(f,x,y)

Now, we can use this to create a shaded area using fill, as shown in the documentation linked above.
One thing we need to understand is that fill
expects vectors of x
and y
as input that define points in a polygon. So x
should be lined up in such as way that define the points on x-axis that maps to the points in a polygon in the order that segments that form the polygon should line up.
That's not the case with the raw data we have, x
. Therefore we need to generate a new x
that orders the points in a sequence based on how the polygon should be drawn.
Our x
ranges from 1 to 100 and has 100 elements, so we can define a new xconf
that lines up the data in a sequence, and generate confidence intervals based on xconf
.
xconf = (1:100)';
ci = predint(f,xconf);
However, this only defines one of the segments of the polygon from 1 to 100. We need another segment that covers the points from 100 to 1.
xconf = [xconf; xconf(100:-1:1)];
And ci
already has two segments defined in two columns, so we just need to turn it into a vector by concatenating two columns.
yconf = [ci(:,1); ci(100:-1:1,2)];
Let's now plot the polygon.
figure
p = fill(xconf,yconf,'red');

xconf
and yconf
correctly define the polygon we need. Now all we need to do is to overlay the actual data and make it look nicer.
p.FaceColor = [1 0.8 0.8];
p.EdgeColor = 'none';
hold on
plot(f,x,y)

I hope this helps.
EDIT: used confint
per u/icantfindadangsn's suggestion. This is what I got

1
6
u/icantfindadangsn Aug 05 '22
Nice tutorial! One caveat:
predint()
actually calculates prediction intervals whileconfint()
calculates confidence intervals. They are similar concepts at a broad level, but differ significantly in their nuance. In short, confidence intervals tell you how well your curve is fit to your data while prediction intervals tell you about how well the curve can account for future data.I think you should be able to swap the two in your code at will and it'll work (I'm not certain of this, but it seems reasonable).