Names Default To Here( 1 ); /* Animate Sampling Distribution created by Sam Gardner, https://www.linkedin.com/in/samgardner/, https://community.jmp.com/t5/user/viewprofilepage/user-id/4467 This Script animates drawing random samples from a normal population distribution and demonstrates how the sampling distribution of the mean also has a normal distribution, with the sampling distribution being updated histogram after each sample draw */ mean = 5; //population mean sd = 1; //population standard deviation n = 5; //sample size n_iterations = 50; // number of samples animation_delay = 0.05; // delay time between animation steps func_VNormalShape = Function( // create a polygon that looks like a vertically oriented normal distribution {_xloc, _yloc, _xscale = 1, _yscale = 1}, {_VNormShapeX, _VNormShapeY}, // create a vector of y values to use for plotting the shape _VNormShapeY = ((_yloc - 3 * _yscale) :: (_yloc + 3 * _yscale) :: (_yscale / 10))`; // create the filled polygon boundary points _VNormShapeX = V Concat( J( 61, 1, _xloc ), _xloc + Sqrt( 2 * Pi() ) * _yscale * _xscale * Normal Density( Sort Descending( _VNormShapeY ), _yloc, _yscale ) ); _VNormShapeY = V Concat( _VNormShapeY, Sort Descending( _VNormShapeY ) ); // substitute into the Polygon(function) the two vectorw with the boundary point X and Y values // and evaluate the function Eval( Substitute( Expr( Polygon( Expr( shape_x ), Expr( shape_y ) ) ), Expr( shape_x ), _VNormShapeX, Expr( shape_y ), _VNormShapeY ) ); ); expr_DrawHistogram = Expr(); //meansvec=J(1,20,Random Normal( mean, sd ) ); _nw = New Window( "Sampling Distribution of the Mean", _ob = Outline Box( "Sampling Animation", _hlb = H List Box( _gb = Graph Box( X Scale( -.1, 6 ), Y Scale( 1, 9 ), Xname( "" ), Yname( "" ), Fill Color( "green" ); func_VNormalShape( 0, mean, 1.5, sd ); Line( {3, 2}, {3, 8} ); Fill Color( "blue" ); expr_DrawHistogram; // Marker( J( n, 1, 2 ), sample ); // For( ii = 1, ii <= n, ii++, // Line( Eval List( {2, sample[ii]} ), Eval List( {5, samplemean} ) ) // ); // Marker(Evallist({5,samplemean})); ) ) ) ); _nw[AxisBox( 2 )] << Show Major Grid( 0 ); _nw[AxisBox( 1 )] << Show Major Grid( 0 ); _nw[Axis Box( 1 )] << {Scale( "Linear" ), Format( "Fixed Dec", 12, 0 ), Min( 1 ), Max( 9 ), Interval( "Numeric" ), Inc( 1 ), Minor Ticks( 0 ), Label Row Nesting( 1 ), Add Ref Line( 5, "Dotted", "Green", "population mean", 1 ), Label Row( {Automatic Font Size( 0 ), Automatic Tick Marks( 0 ), Inside Ticks( 0 ), Label Orientation( "Horizontal" ), Major Grid Line Color( -14145495 ), Minor Grid Line Color( -15790320 ), Show Major Grid( 0 ), Show Major Labels( 1 ), Show Major Ticks( 1 ), Show Minor Grid( 0 ), Show Minor Labels( 0 ), Show Minor Ticks( 1 ), Tick Offset( 0 )} )}; // delete the x-axis from the display _nw[AxisBox( 2 )] << Delete; meansvec = []; For( kk = 1, kk <= n_iterations, kk++, sample = J( n, 1, Random Normal( mean, sd ) ); samplemean = Mean( sample ); meansvec = meansvec || samplemean; // add markers for the random sample Wait( animation_delay ); _gb[Framebox( 1 )] << Add Graphics Script( Marker( J( n, 1, 0 ), sample ) ); Wait( animation_delay ); // draw lines from the sample points to the overall sample mean For( ii = 1, ii <= n, ii++, frompoint = Substitute( Expr( {0, yyy} ), Expr( yyy ), sample[ii] ); Eval( Substitute( Expr( _gb[Framebox( 1 )] << Add Graphics Script( Line( yyy, Eval List( {2, samplemean} ) ) ) ), Expr( yyy ), frompoint ) ); Wait( animation_delay ); ); Wait( animation_delay ); //draw a marker for the sample mean _gb[Framebox( 1 )] << Add Graphics Script( Marker Size( 7 ); Marker( 4, Eval List( {2, samplemean} ) ); ); Wait( animation_delay ); //remove the lines from the data points to the sample mean For( ii = 1, ii <= n, ii++, _gb[Framebox( 1 )] << Remove Graphics Script( 2 ) ); Wait( animation_delay ); // draw a horizontal arrow line from the sample mean marker to the baseline for the histogram _gb[Framebox( 1 )] << Add Graphics Script( Arrow( Eval List( {2, samplemean} ), Eval List( {3, samplemean} ) ) ); Wait( animation_delay ); // now need to update the expr_DrawHistogram Expression and reshow the display expr_DrawHistogram = Expr( // add a note to the graph to indicate how many samples have been drawn Text( {1, 8.2}, "n samples = " || Char( kk - 1 ) ); // steps to make histogram // 1. get range of values n_means = N Cols( meansvec ); // if we are just starting, need let the range be > 0 If( n_means <= 1, range = 1, range = Max( meansvec ) - Min( meansvec ) ); minval = Min( meansvec ); // 2. determine number of bins // a. if number of values < 8 use 3 bins // b. o.w. use n_bins = floor(log2(nvalues)+1) n_bins = Max( Floor( Log( n_means, 2 ) + 1 ), 3 ); // 3. determine bin width = range/n_bins bin_width = range / n_bins; // 4. for each bin count # of values in the bin and convert to percent bin_freqs = J( n_bins, 1, . ); For( hh = 1, hh <= n_bins - 1, hh++, bin_freqs[hh] = (Sum( ((meansvec >= minval + (hh - 1) * bin_width) & (meansvec < minval + hh * bin_width)) )) / n_means ); // this last step needs a different comparison condition, to allow for capturing the maximum value bin_freqs[hh] = Sum( ((meansvec >= minval + (hh - 1) * bin_width)) ) / n_means; // 5. draw frequency chart of the percent data in each bin // scaling factor for bar chart histfreqscale = 1.5 / Max( bin_freqs ); // this creates the bars for each bin For( hh = 1, hh <= n_bins, hh++, Eval( Substitute( Expr( Rect( 3, minval + bin_width * zzz, 3 + bin_freqs[zzz] * histfreqscale, minval + bin_width * (zzz - 1), 1 ); Rect( 3, minval + bin_width * zzz, 3 + bin_freqs[zzz] * histfreqscale, minval + bin_width * (zzz - 1), 0 ); ), Expr( zzz ), hh ) ) ); ); // redraw the graph so that the histogram is updated _gb[Framebox( 1 )] << Reshow; Wait( animation_delay ); // delete, in order, the arrow, mean marker, and data points, prior to repeating _gb[Framebox( 1 )] << Remove Graphics Script( 3 ); _gb[Framebox( 1 )] << Remove Graphics Script( 2 ); _gb[Framebox( 1 )] << Remove Graphics Script( 1 ); );