Plot multiple normal distributions on a single figure, using normspec()

18 views (last 30 days)
Hello,
I want to plot two normal distributions on the same figure using the normspec () command. The problem is that Matlab always creates two separate figures, even if I use the "hold on" command. Is there a way to get around this problem?
I'd appreciate any help!
Best, Martin

Accepted Answer

Star Strider
Star Strider on 13 Jul 2014
I did this a couple months ago with this code:
alpha = 0.05; % significance level
mu = 82.9; % mean
sigma = 8.698; % std
x = linspace(mu-5*sigma, mu+5*sigma, 500);
cutoff1 = norminv(alpha/2, mu, sigma); % Lower 95% CI is p = 0.025
cutoff2 = norminv(1-alpha/2, mu, sigma); % Upper 95% CI is p = 0.975
y = normpdf(x, mu, sigma);
xci = [linspace(mu-5*sigma, cutoff1); linspace(cutoff2, mu+5*sigma)];
yci = normpdf(xci, mu, sigma);
figure(1)
plot(x, y, '-b', 'LineWidth', 1.5)
patch(x, y, [0.5 0.5 0.5])
patch([xci(1,:) cutoff1], [yci(1,:) 0], [1 1 1])
patch([cutoff2 xci(2,:)], [0 yci(2,:)], [1 1 1])
Experiment with it until you get the result you want. As written, it produces:

More Answers (2)

dpb
dpb on 13 Jul 2014
Not with the function as written--it has the following hardcoded in its preamble code prior to plotting--
%get the axes ready
nspecfig = figure;
nspecaxes = axes;
set(nspecaxes, 'Parent', nspecfig);
set(nspecaxes,'Nextplot','add');
So, as you noted, it's going to create a new figure no matter what.
Your options are basically --
a) make a local copy of the function and modify it to allow it to take an axes handle as an optional input and if given, skip the creation of the new figure and axes and add the additional to the existing one, or
b) essentially accomplish the same thing by using the pieces of that code that do the plotting it does on the existing axes for the second set on the existing axis.
  1 Comment
thomaz lascala
thomaz lascala on 16 Mar 2016
Hello dpb,
Can you show me how to modify the local function skipping the creation of two figures?
I basically want to do a subplot of normspec.
Thanks

Sign in to comment.


Matheus Daniel
Matheus Daniel on 17 Mar 2016
Edited: Matheus Daniel on 17 Mar 2016
I modified the local function normspec and created a new function to generate the figure you want. please see the code below:
function [p,h] = normspecMOD(specs,mu,sigma,region,col)
%NORMSPEC Plots normal densit between specification limits.
% NORMSPEC(SPECS) plots the standard normal density, shading the
% portion inside the spec limits. SPECS is a two element vector
% containing the lower and upper specification limits.
% Set SPECS(1)=-Inf if there is no lower limit, and SPECS(2)=Inf
% if there is no upper limit.
%
% NORMSPEC(SPECS,MU,SIGMA) shades the portion inside the spec limits of
% a normal density with parameters MU and SIGMA. The defaults are MU=0 and
% SIGMA=1.
%
% NORMSPEC(SPECS,MU,SIGMA,REGION) shades either the portion 'inside' or
% 'outside' of the spec limits. The default is REGION='inside'.
%
% [P] = NORMSPEC(...) returns the probability, P, of the shaded area.
%
% [P,H] = NORMSPEC(...) returns a handle H to the line objects.
%
% Copyright 1993-2011 The MathWorks, Inc.
%fill in default args
if nargin<2
mu=0;
end
if nargin<3
sigma=1;
end
if nargin<4
region='inside';
end
%test for invalid args
if numel(specs) ~= 2 || ~isnumeric(specs),
error(message('stats:normspec:BadSpecsSize'));
end
if max(size(mu)) > 1 || max(size(sigma)) > 1 ,
error(message('stats:normspec:ScalarRequired'));
end
if ~strcmp(region,'inside') && ~strcmp(region,'outside')
error(message('stats:normspec:BadRegion'));
end
%swap the specs if they are reversed
lb = specs(1);
ub = specs(2);
if lb > ub
lb = specs(2);
ub = specs(1);
end
lbinf = isinf(lb);
ubinf = isinf(ub);
%continue checking for invalid args
if lbinf && ubinf
error(message('stats:normspec:BadSpecsInfinite'));
end
%compute normal curve
prob = (0.0002:0.0004:0.9998)';
x = norminv(prob,mu,sigma);
y = normpdf(x,mu,sigma);
%compute p
if strcmp(region,'outside')
if lbinf,
p = normcdf(-ub,-mu,sigma); % P(t > ub)
elseif ubinf,
p = normcdf(lb,mu,sigma); % P(t < lb)
else
p = sum(normcdf([lb -ub],[mu -mu],sigma)); % P(t < lb) + Pr(t > ub)
end
else
if lbinf,
p = normcdf(ub,mu,sigma); % P(t < ub)
elseif ubinf,
p = normcdf(-lb,-mu,sigma); % P(t > lb)
else
p = diff(normcdf([lb ub],mu,sigma)); % P(lb < t < ub)
end
end
hh = plot(x,y,'black-');
xlims = 4*[specs(1) specs(2)];
%compute the endpoints of the spec limit lines and plot limit lines
%lower limit line goes up, and upper limit line goes down
pll = [xlims(1);xlims(1)];
ypll = [0;eps];
if lbinf,
ll = pll;
yll = ypll;
else
ll = [lb; lb];
yll = [0; normpdf(lb,mu,sigma)];
end
pul = [xlims(2);xlims(2)];
ypul = [eps;0];
if ubinf,
ul = pul;
yul = ypul;
else
ul = [ub; ub];
yul = [normpdf(ub,mu,sigma); 0];
end
%create title, draw spec lines, and shade area
switch region
case 'inside'
if ubinf
str = sprintf('%s',getString(message('stats:normspec:ProbGTlb',num2str(p))));
k = find(x > lb);
hh1 = plot(ll,yll,'black-');
elseif lbinf
str = sprintf('%s',getString(message('stats:normspec:ProbLTub',num2str(p))));
k = find(x < ub);
hh1 = plot(ul,yul,'black-');
else
str = sprintf('%s',getString(message('stats:normspec:ProbBetweenBounds',num2str(p))));
k = find(x > lb & x < ub);
hh1 = plot(ll,yll,'black-',ul,yul,'black-');
end
xfill = [ll; x(k); ul];
yfill = [yll; y(k); yul];
fill(xfill,yfill,col);
case 'outside'
if ubinf
str = sprintf('%s',getString(message('stats:normspec:ProbLTlb',num2str(p))));
k1 = find(x < lb);
k2=[];
hh1 = plot(ll,yll,'black-');
elseif lbinf
str = sprintf('%s',getString(message('stats:normspec:ProbGTub',num2str(p))));
k1=[];
k2 = find(x > ub);
hh1 = plot(ul,yul,'black-');
else
str = sprintf('%s',getString(message('stats:normspec:ProbOutsideBounds',num2str(p))));
k1 = find(x < lb );
k2=find(x > ub);
hh1 = plot(ll,yll,'black-',ul,yul,'black-');
end
xfill = [pll; x(k1); ll ; ul; x(k2); pul ];
yfill = [ypll; y(k1); flipud(yll) ; flipud(yul); y(k2); ypul ];
fill(xfill,yfill,col);
otherwise
error(message('stats:normspec:BadRegion'));
end
%return line handles, if requested
if nargout > 1
h = [hh; hh1];
end
I inserted the option to change the colors of the areas, see below the routine I use to run with the modified function:
col=hsv(4); % color variation search for "colormap"
j=1;
m=0; % mean
std=0.1; % standard deviation
for i=0:0.1:0.3
h=erf(i); % tolerance interval
normspecMOD([-h,h],m,std,'outside',col(j,1:end)); hold all;
j=j+1;
end
title({'Gaussian Noise Curve',['Mean = ',num2str(m),' / Standard Deviation = ',num2str(std)]});
xlabel('Disturbance Signal');
ylabel('Gauss Distribution');
grid on;
I hope this could be helpful to you :) See below an example of the graph generated.
%

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!