-
Notifications
You must be signed in to change notification settings - Fork 0
/
sp_normplot.m
173 lines (142 loc) · 4.57 KB
/
sp_normplot.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
function h = normplot(x)
%NORMPLOT Displays a normal probability plot.
% H = NORMPLOT(X) makes a normal probability plot of the data in X. For
% matrix, X, NORMPLOT displays a plot for each column. H is a handle to the
% plotted lines.
%
% The purpose of a normal probability plot is to graphically assess whether
% the data in X could come from a normal distribution. If the data are
% normal the plot will be linear. Other distribution types will introduce
% curvature in the plot. NORMPLOT uses midpoint probability plotting
% positions. Use PROBPLOT when the data included censored observations.
%
% Use the data cursor to read precise values, observation numbers, and
% the value of the observations projected on to the reference line.
%
% See also PROBPLOT, WBLPLOT.
% Copyright 1993-2008 The MathWorks, Inc.
% $Revision: 1.2 $ $Date: 2011-03-24 16:15:15 $
if size(x,1)==1
x = x';
end
[n, m] = size(x);
[sx,originds] = sort(x);
minx = min(sx(:));
maxx = max(sx(:));
if isnan(minx) % Data all NaNs, setting arbitrary limits.
minx = 0;
maxx = 1;
end
range = maxx-minx;
if range>0
minxaxis = minx-0.025*range;
maxxaxis = maxx+0.025*range;
else
minxaxis = minx - 1;
maxxaxis = maxx + 1;
end
% Use the same Y vector if all columns have the same count.
if (~any(isnan(x(:))))
eprob = ((1:n)' - 0.5)./n;
else
nvec = sum(~isnan(x));
eprob = repmat((1:n)', 1, m);
eprob = (eprob-.5) ./ repmat(nvec, n, 1);
eprob(isnan(sx)) = NaN;
end
y = norminv(eprob,0,1);
minyaxis = norminv(0.25 ./n,0,1);
maxyaxis = norminv((n-0.25) ./n,0,1);
p = [0.001 0.003 0.01 0.02 0.05 0.10 0.25 0.5...
0.75 0.90 0.95 0.98 0.99 0.997 0.999];
label = {'0.001','0.003', '0.01','0.02','0.05','0.10','0.25','0.50', ...
'0.75','0.90','0.95','0.98','0.99','0.997', '0.999'};
tick = norminv(p,0,1);
q1x = prctile(x,25);
q3x = prctile(x,75);
q1y = prctile(y,25);
q3y = prctile(y,75);
qx = [q1x; q3x];
qy = [q1y; q3y];
dx = q3x - q1x;
dy = q3y - q1y;
slope = dy./dx;
centerx = (q1x + q3x)/2;
centery = (q1y + q3y)/2;
maxx = max(x);
minx = min(x);
maxy = centery + slope.*(maxx - centerx);
miny = centery - slope.*(centerx - minx);
yinter = centery - slope.*(centerx);
mx = [minx; maxx];
my = [miny; maxy];
abs_min = min(minx, miny);
abs_max = max(maxx, maxy);
% Plot data and corresponding reference lines in the same color,
% following the default color order. Plot reference line first,
% followed by the data, so that data will be on top of reference line.
newplot();
hdat = line(sx,y,'LineStyle','none','Marker','+');
hrefends = line(mx,my,'LineStyle','-.','Marker','none');
hrefmid = line(qx,qy,'LineStyle','-','Marker','none');
heq = line([-5; 5], [-5; 5],'LineStyle','-','Marker','none','Color','k');
if m==1
set(hdat,'MarkerEdgeColor','b');
set([hrefends,hrefmid],'Color','r');
end
if nargout>0
h = [hdat;hrefmid;hrefends];
end
new_label = {};
for i=1:length(tick)
new_label{i} = sprintf('%.1f',tick(i));
end
set(gca,'YTick',tick,'YTickLabel',new_label);
set(gca,'YLim',[minyaxis maxyaxis],'XLim',[minxaxis maxxaxis]);
xlabel('Data');
ylabel('Normal Distribution Values');
title('Normal Probability Plot');
grid on;
for i=1:m
% Set custom data cursor on data.
hB = hggetbehavior(hdat(i),'datacursor');
set(hB,'UpdateFcn',{@normplotDatatipCallback,slope(i),yinter(i)});
% Disable datacursor on reference lines.
hB = hggetbehavior(hrefends(i),'datacursor');
set(hB,'Enable',false);
hB = hggetbehavior(hrefmid(i),'datacursor');
set(hB,'Enable',false);
if m>1
setappdata(hdat(i),'group',i);
end
setappdata(hdat(i),'originds',originds(:,i));
end
% ----------------------------
function datatipTxt = normplotDatatipCallback(obj,evt,slope,yinter)
target = get(evt,'Target');
ind = get(evt,'DataIndex');
pos = get(evt,'Position');
x = pos(1);
y = pos(2);
% Compute position to display.
yper = normcdf(y,0,1);
yperexp = normcdf(polyval([slope,yinter],x));
xexp = polyval([1/slope,-yinter/slope],y);
% Get the original row number of the selected point.
originds = getappdata(target,'originds');
origind = originds(ind);
% Get the group number, which is set if more than one.
group = getappdata(target,'group');
% Generate text to display.
datatipTxt = {
['Data: ',num2str(x)],...
['Probability: ',num2str(yper)],...
''
};
datatipTxt{end+1} = ['Observation: ',num2str(origind)];
if ~isempty(group)
datatipTxt{end+1} = ['Group: ',num2str(group)];
end
datatipTxt{end+1} = '';
datatipTxt{end+1} = ['Refline Data: ',num2str(xexp)];
datatipTxt{end+1} = ['Refline Probability: ',num2str(yperexp)];