ANALYSIS TOOL BOX

Simulations

SimulateNormallyDistributedOutcome

Run Monte Carlo simulations for normally distributed outcomes.

monte-carlonormal-distributionsimulationuncertainty

Introduction

Most physical, social, and financial measurements — height, test scores, sensor error, portfolio returns — cluster symmetrically around a mean with the probability of extreme values tapering off in both directions, which is exactly what the Normal distribution models. SimulateNormallyDistributedOutcome runs a Monte Carlo simulation drawing from that distribution, letting you specify the spread either directly as a standard deviation or, when you only have an expert's plausible range, by estimating it automatically from a min/max using the range rule of thumb.

Teaching Note

Normal distribution simulations are essential for:

  • Finance: Modeling the historical distribution of portfolio or index returns over time.
  • Healthcare: Simulating physiological measurements like blood pressure, height, or weight in a population.
  • Quality Engineering: Modeling industrial variability and tolerances in manufacturing component dimensions.
  • Intelligence Analysis: Modeling the circular error probability (CEP) or geolocation error for sensors.
  • Logistics & Supply Chain: Estimating the distribution of transit times for highly standardized delivery routes.
  • Environmental Science: Simulating annual fluctuations in average temperatures or rainfall patterns.
  • Human Resources: Modeling standardized test results or performance appraisal scores across a large workforce.
  • Engineering: Simulating the distribution of mechanical stress loads on a structural component during operation.

Parameters

ParameterTypeDefaultDescription
expected_outcomefloat0The mean or average value of the distribution (Loc). Defaults to 0.
standard_deviation_of_outcomefloatNoneThe standard deviation representing the spread of the data (Scale). If None, it must be estimated from min_max_of_outcome. Defaults to None.
min_max_of_outcomelistNoneA list of length 2 [min, max] used to estimate the standard deviation (range/3.29). Ignored if standard_deviation_of_outcome is provided. Defaults to None.
number_of_trialsint10000The number of stochastic simulations (Monte Carlo trials) to run. Defaults to 10000.
return_formatstr'dataframe'The format of the returned data: 'dataframe' (pd.DataFrame) or 'array' (np.ndarray). Defaults to 'dataframe'.
simulated_variable_namestr'Simulated Outcome'The label for the simulated variable in the output and plot. Defaults to 'Simulated Outcome'.
random_seedint412The seed for the random number generator to ensure replicability. Defaults to 412.
plot_simulation_resultsboolTrueWhether to display a histogram of the simulation outcomes. Defaults to True.
fill_colorstr'#999999'The hex color code for the histogram bars. Defaults to '#999999'.
fill_transparencyfloat0.6The transparency level (0-1) for the histogram plot. Defaults to 0.6.
figure_sizetuple(8, 6)The size of the plot figure in inches (width, height). Defaults to (8, 6).
show_meanboolTrueWhether to display the mean value as a vertical dashed line. Defaults to True.
show_medianboolTrueWhether to display the median value as a vertical dotted line. Defaults to True.
title_for_plotstr'Simulation Results'The main title for the distribution plot. Defaults to 'Simulation Results'.
subtitle_for_plotstr'Showing the distribution of the outcome'The descriptive subtitle for the plot.
caption_for_plotstrNoneOptional caption text displayed at the bottom of the plot. Defaults to None.
data_source_for_plotstrNoneOptional data source identification text. Defaults to None.
show_y_axisboolFalseWhether to display the frequency/density scale on the y-axis. Defaults to False.
title_y_indentfloat1.1Vertical position for the title text. Defaults to 1.1.
subtitle_y_indentfloat1.05Vertical position for the subtitle text. Defaults to 1.05.
caption_y_indentfloat-0.15Vertical position for the caption text. Defaults to -0.15.

Returns

The simulated outcomes across all Monte Carlo runs — a pandas DataFrame or a NumPy array, depending on return_format.

Example

python
from analysistoolbox.simulations import SimulateNormallyDistributedOutcome

# Estimate annual revenue with uncertainty
revenue_draws = SimulateNormallyDistributedOutcome(
    expected_outcome=5_000_000,
    standard_deviation_of_outcome=750_000,
    number_of_trials=10_000,
    simulated_variable_name='Annual Revenue ($)',
)

# Probability of exceeding $6M
prob_above_6m = (revenue_draws['Annual Revenue ($)'] > 6_000_000).mean()
print(f"P(Revenue > $6M): {prob_above_6m:.1%}")