function bvnormal(option, first) % BVNORMAL Interactive bivariate normal distribution %Peter Dunn %15 September 1998 if nargin==0, option=0; figure('Name','Interactive Bivariate Normal Distribution', ... 'Resize','off'); %SET UP THE CANVAS border = 0.02; dimen1 = 0.20; %parameters window uicontrol('Style','Frame', 'Units','normalized',... 'Position',[border border 1-2*border 0.2-border]); %options: uicontrol('Style','Frame', 'Units','normalized',... 'Position',[0.76 0.2+border 0.24-border 1-0.2-2*border]); %Parameter `buttons' pbborder = 0.02; pbwidth = ( 1 - (2 * border) - 6*pbborder ) / 5; uicontrol('Style','text','String','mu x','Units','normalized',... 'Position',[0.02+pbborder 0.14 pbwidth 0.05]); uicontrol('Style','Slider', 'Max',5, 'Min',-5, ... 'Callback','bvnormal(8);','value',0.0,... 'tag','hmx', 'Units','normalized', ... 'Position',[0.02+pbborder 0.04 pbwidth 0.05]); uicontrol('Style','Edit','String','0.0','Units','normalized',... 'Position',[0.02+pbborder 0.09 pbwidth 0.05],... 'tag','hmxedit','Callback','bvnormal(9);'); uicontrol('Style','text','String','mu y','Units','normalized',... 'Position',[0.02+2*pbborder+pbwidth 0.14 pbwidth 0.05]); uicontrol('Style','Slider', 'Max',5, 'Min',-5, ... 'Callback','bvnormal(8);','value',0.0,... 'tag','hmy', 'Units','normalized', ... 'Position',[0.02+2*pbborder + pbwidth 0.04 pbwidth 0.05]); uicontrol('Style','Edit','String','0.0','Units','normalized',... 'Position',[0.02+2*pbborder + pbwidth 0.09 pbwidth 0.05],... 'tag','hmyedit','Callback','bvnormal(9);'); uicontrol('Style','text','String','sigma x','Units','normalized',... 'Position',[0.02+3*pbborder + 2*pbwidth 0.14 pbwidth 0.05]); uicontrol('Style','Slider', 'Max',5, 'Min',0.1,... 'Callback','bvnormal(8);',... 'Value',1.0,'tag','hsx', 'Units','normalized',... 'Position',[0.02+3*pbborder + 2*pbwidth 0.04 pbwidth 0.05]); uicontrol('Style','Edit','String','1.0','Units','normalized',... 'Position',[0.02+3*pbborder + 2*pbwidth 0.09 pbwidth 0.05],... 'tag','hsxedit','Callback','bvnormal(9);'); uicontrol('Style','text','String','sigma y','Units','normalized',... 'Position',[0.02+4*pbborder + 3*pbwidth 0.14 pbwidth 0.05]); uicontrol('Style','Slider', 'Max',5, 'Min',0.1, ... 'Callback','bvnormal(8);',... 'Value',1.0,'tag','hsy', 'Units','normalized', ... 'Position',[0.02+4*pbborder + 3*pbwidth 0.04 pbwidth 0.05]); uicontrol('Style','Edit','String','1.0','Units','normalized',... 'Position',[0.02+4*pbborder + 3*pbwidth 0.09 pbwidth 0.05],... 'tag','hsyedit','Callback','bvnormal(9);'); uicontrol('Style','text','String','rho','Units','normalized',... 'Position',[0.02+5*pbborder + 4*pbwidth 0.14 pbwidth 0.05]); uicontrol('Style','Slider', 'Max',0.99, 'Min',-0.99, ... 'Callback','bvnormal(8);','value',0,... 'tag','hrho', 'Units','normalized', ... 'Position',[0.02+5*pbborder + 4*pbwidth 0.04 pbwidth 0.05]); uicontrol('Style','Edit','String','0.0','Units','normalized',... 'Position',[0.02+5*pbborder + 4*pbwidth 0.09 pbwidth 0.05],... 'tag','hrhoedit','Callback','bvnormal(9);'); %options `buttons' oborder = 0.78; owidth = 0.18; oheight = 0.07; uicontrol('Style','Text','String','Type','Units','normalized',... 'Position', [ oborder 0.96-0.08 owidth oheight] ); uicontrol('Style','Popup','String','Mesh|Surf|B&W','Units','normalized',... 'Position',[ oborder 0.96-2*0.08+0.03 owidth oheight],... 'tag','htypeplot','value',1,... 'Callback','bvnormal(10);'); uicontrol('Style','Text','String','View','Units','normalized',... 'Position', [ oborder 0.96-3*0.08 owidth oheight] ); uicontrol('Style','Popup','String','Default|Overhead|Conditnl X|Conditnl Y', ... 'tag','hview',... 'Callback','bvnormal(1);','Units','normalized',... 'Position',[ oborder 0.96-4*0.08+0.03 owidth oheight]); uicontrol('Style','Text','String','Elevation','Units','normalized',... 'Position',[oborder 0.96-5*0.08 owidth oheight]); uicontrol('Style','Slider','Max',180,'Min',-180,'Units','normalized',... 'Position',[ oborder 0.96-6*0.08+0.03 owidth 0.05],... 'value',30.0,... 'tag','helevation','Callback','bvnormal(2);'); uicontrol('Style','Text','String','Azimuth','Units','normalized',... 'Position',[oborder 0.96-7*0.08 owidth oheight]); uicontrol('Style','Slider','Max',180,'Min',-180,'Units','normalized',... 'Position',[ oborder 0.96 - 8*0.08+0.03 owidth 0.05],... 'value',-37.5,... 'tag','hazimuth','Callback','bvnormal(3);'); uicontrol('Style','Pushbutton','String','Close','Units','normalized',... 'Position',[ oborder 0.25 owidth oheight], ... 'Callback','close(gcf);'); %PLOT THE FUNCTION axes('Position',[0.08 0.30 0.65 0.65 ]) bvnormal(10, 1); %Now, after rotate3d had been done, we have to set the %elevation and azimuth slide controls to their proper values, %so we alter the WindowButtonUpFcn to include this change: cwbuf = get(gcf,'WindowButtonUpFcn'); set(gcf,'WindowButtonUpFcn',[cwbuf,'; bvnormal(4);']); set(gcf,'HandleVisibility','Callback'); end; if option == 1, %Changes the view value = get( findobj('tag','hview'), 'Value'); if (value==1), %default view(-37.5, 30); set( findobj('tag','hazimuth'),'value',-37.5); set( findobj('tag','helevation'),'value',30.0); elseif (value==2), %overhead view(0, 90); set( findobj('tag','hazimuth'),'value',0.0); set( findobj('tag','helevation'),'value',90.0); elseif (value==3), %conditional x view(0, 0); set( findobj('tag','hazimuth'),'value',0.0); set( findobj('tag','helevation'),'value',0.0); elseif (value==4), %conditional y view(90,0); set( findobj('tag','hazimuth'),'value',90.0); set( findobj('tag','helevation'),'value',90.0); end; elseif (option==2), %Changes the elevation value = get( findobj('tag','helevation'), 'value'); [az, el] = view; view(az, value); elseif (option==3), %Changes the azimuth value = get( findobj('tag','hazimuth'), 'value'); if value>180, value = 360-value; set( findobj('tag','hazimuth'), 'value', value ); elseif value<-180 value = 360+value; set( findobj('tag','hazimuth'), 'value', value ); end; [az, el] = view; view(value, el); elseif (option==4), %sets the azimuth and elevation after rotate3d [az, el] = view; if az>180, az = 360-az; set( findobj('tag','hazimuth'), 'value', az ); elseif az<-180 az = 360+az; set( findobj('tag','hazimuth'), 'value', az ); end; set( findobj('tag','hazimuth'),'value',az); set( findobj('tag','helevation'),'value',el); elseif (option==8), %Parameters slid set( findobj('tag','hmxedit'), ... 'string', num2str(get(findobj('tag','hmx'),'value')) ); set( findobj('tag','hmyedit'), ... 'string', num2str(get(findobj('tag','hmy'),'value')) ); set( findobj('tag','hsxedit'), ... 'string', num2str(get(findobj('tag','hsx'),'value')) ); set( findobj('tag','hsyedit'), ... 'string', num2str(get(findobj('tag','hsy'),'value')) ); set( findobj('tag','hrhoedit'), ... 'string', num2str(get(findobj('tag','hrho'),'value')) ); bvnormal(10); elseif (option==9), %Parameters editted entval = str2num( get(findobj('tag','hmxedit'),'string') ); if (entval < -5 ) set( findobj('tag','hmxedit'),'string', '-5.0'); entval = -5.0; elseif (entval > 5) set( findobj('tag','hmxedit'),'string', '5.0'); entval = 5.0; end set( findobj('tag','hmx'), 'value', entval ); entval = str2num( get(findobj('tag','hmyedit'),'string') ); if (entval < -5 ) set( findobj('tag','hmyedit'),'string', '-5.0'); entval = -5.0; elseif (entval > 5) set( findobj('tag','hmyedit'),'string', '5.0'); entval = 5.0; end set( findobj('tag','hmy'), 'value', entval ); entval = str2num( get(findobj('tag','hsxedit'),'string') ); if (entval < 0.1 ) set( findobj('tag','hsxedit'),'string', '0.1'); entval = 0.1; elseif (entval > 5) set( findobj('tag','hsxedit'),'string', '5.0'); entval = 5.0; end set( findobj('tag','hsx'), 'value', entval ); entval = str2num( get(findobj('tag','hsyedit'),'string') ); if (entval < 0.1 ) set( findobj('tag','hsyedit'),'string', '0.1'); entval = 0.1; elseif (entval > 5) set( findobj('tag','hsyedit'),'string', '5.0'); entval = 5.0; end set( findobj('tag','hsy'), 'value', entval ); entval = str2num( get(findobj('tag','hrhoedit'),'string') ); if (entval < -0.99 ) set( findobj('tag','hrhoedit'),'string', '-0.99'); entval = -0.99; elseif (entval > 0.99) set( findobj('tag','hrhoedit'),'string', '0.99'); entval = 0.99; end set( findobj('tag','hrho'), 'value', entval ); bvnormal(10); elseif (option==10), %Changes the parameters %Return to view before the change...but on %first call, there is no view yet. So we juggle it... %Thus, the second input, first, is just a flag to indicate this. if nargin==2, el = get( findobj('tag','helevation'), 'value'); az = get( findobj('tag','hazimuth'), 'value'); else [az, el] = view; end; meanx = get(findobj('tag','hmx'), 'Value'); meany = get(findobj('tag','hmy'), 'Value'); stdx = get(findobj('tag','hsx'), 'Value'); stdy = get(findobj('tag','hsy'), 'Value'); rho = get(findobj('tag','hrho'), 'Value'); [zx, zy] = meshgrid( linspace(-3.5, 3.5, 40), linspace(-3.5, 3.5, 40) ); x = meanx + stdx*zx; y = meany + stdy*zy; Q = ( zx.^2 - 2*rho*zx.*zy + zy.^2 ) ./ ( 1 - rho^2 ); z = exp( -0.5*Q ) ./ ( 2*pi*stdx*stdy*sqrt(1-rho^2) ); how = get( findobj( 'tag','htypeplot' ), 'value'); if (how==1), %mesh hplot = mesh(x, y, z); colormap default; elseif (how==2), %surface hplot = surf(x, y, z); colormap default; elseif (how==3), %black and white hplot = surf(x, y, z); colormap gray; brighten(0.5); end view(az, el); rotate3d on; xlabel('x-axis'); ylabel('y-axis'); drawnow; end