From a list of numbers to a picture
A simulation usually ends with a long list of results: the total of two dice for each of 10,000 rolls, the number of tries until a rare drop, the final position of a random walk. A list that long tells you nothing by eye. A histogram turns it into a picture.
To build one, you divide the range of possible values into intervals called bins, count how many results fall into each, and draw a bar for each bin with height proportional to the count. The result shows where outcomes cluster, how widely they spread, and whether the pattern is symmetric or lopsided.
Counts or proportions
The vertical axis can show raw counts or relative frequencies, where each count is divided by the total number of results. Relative frequencies are usually better when you want to compare with theory or with another run, because the heights then read directly as estimated probabilities and do not depend on how many trials you ran.
For example, if 1,671 of 10,000 two-dice rolls total 7, the bar for 7 has relative height 0.1671. The exact probability is 6/36, about 0.1667, so the bar is close to the theoretical value.
Choosing bins
For outcomes that are whole numbers with few possible values, such as dice totals, use one bin per value. The bars are centred on the values and do not need any grouping.
For outcomes with many possible values, such as the number of tries until a drop, you need to group them. Bin width is a judgement call, and it changes the picture:
- Too wide: the bars blur together and hide real features.
- Too narrow: each bar holds few results, so random noise dominates and the shape looks jagged.
- A reasonable starting point: try a handful of widths and see which makes the underlying shape clear without much jitter. More trials let you use narrower bins.
If the shape changes dramatically when you adjust the width a little, treat the fine details with suspicion.
A short plotting example
Using Python with the matplotlib and numpy libraries, here is a histogram of 10,000 simulated totals of two dice:
import random
import matplotlib.pyplot as plt
import numpy as np
totals = [random.randint(1, 6) + random.randint(1, 6) for _ in range(10_000)]
bins = np.arange(1.5, 13.5, 1) # edges at 1.5, 2.5, ..., 12.5
plt.hist(totals, bins=bins, density=True, rwidth=0.9)
plt.xticks(range(2, 13))
plt.xlabel("Total of two dice")
plt.ylabel("Relative frequency")
plt.show()
The bin edges sit halfway between whole numbers, so each bar is centred on one total. Setting density=True scales the bars so their areas add up to 1; with bins of width 1 the heights then equal relative frequencies.
Reading the shape
Different processes produce recognisable shapes.
Triangle. The total of two dice rises steadily from 2 up to a peak at 7, then falls symmetrically to 12. The peak has six ways to occur and the ends have one each.
Flat. One fair die gives a nearly flat histogram, with every face about equally likely. Small differences between bars are random noise, and with a few thousand rolls you should expect some.
Bell shape. When you add up many independent small contributions, such as the totals of several dice or the final position of a random walk, the histogram tends to approach a bell-shaped curve centred on the average. This is the normal distribution appearing in practice.
Skewed with a long tail. The number of attempts until a rare drop is bunched near the low end with a long tail stretching right. In that shape the mean is pulled above the median, so the average can mislead as a summary of a typical outcome.
Two peaks. A histogram with two humps often means two different processes are mixed together, which is a hint to separate them.
Using the histogram to check a hand calculation
Overlay the exact probabilities on the histogram, or print them in a column beside the bar heights. If the bars follow the exact values within a small, random-looking scatter, your calculation and your code agree. If one bar is consistently off, or the shape is wrong, look for a mistake in either the model or the formula.
Remember that each bar has its own noise. With 10,000 rolls, the bar for 7 is expected to be near 0.1667 with a standard error of roughly 0.0037, since the square root of (0.1667 x 0.8333 / 10,000) is about 0.0037. So bar heights between about 0.159 and 0.174 are within two standard errors, and a bar that sits slightly above or below its target is not evidence of a problem.
Pitfalls
- Misleading axes. Starting the vertical axis above zero exaggerates small differences between bars.
- Different bin widths compared by eye. Counts depend on bin width, so use relative frequencies or density when comparing.
- Reading patterns into noise. Random data can show apparent bumps and gaps, particularly with few trials. Repeating the simulation tells you whether a feature is stable.
- Treating the picture as a forecast. A histogram describes simulated results under a model. It does not say the next outcome in a real game will follow any pattern, since independent events have no memory.
The same visual habit is useful when thinking about games with a house edge: the histogram of long-run results shifts in the player’s disadvantage, and variation around it is just variation. Gambling can be harmful, and local support services can help anyone who needs it.