
Dieses Skript animiert das Ziehen von Zufallsstichproben aus einer normalen Populationsverteilung und zeigt, wie die Stichprobenverteilung des Mittelwerts auch eine Normalverteilung aufweist, wobei das Histogramm der Stichprobenverteilung nach jeder Stichprobenziehung aktualisiert wird.
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 );
);