I wanted to write about variance in golf here, but when I was reviewing my theoretical, idealized dispersion patterns, I realized it was effectively pointless to start discussing variance in golf without generating realistic dispersion patterns. These golf shot dispersion patterns represent the inherent variance in the game, so we need the model to reflect them before looking at birdies and blow-ups.
Note: this is going to be very technical. There will be a lot of footnotes. For technical folks following along, I’ve opened the source for this dispersion pattern generator. I’ll try to break this up by adding the resulting dispersion patterns, and overlaying them onto the road hole at St Andrews.

To build a shot dispersion model I’ll need data. The ultimate irony here is that plenty of datasets exist, it’s just that 1) I don’t have access to them, and 2) the owners of any datasets I could get access to would almost certainly not allow me to publish much with relevant parts of that data.1 Thus, I’m forced to scour the internet for any datasets that have already been published.
Note: if you work at a golf data analytics company willing to share data, please reach out. Access to large datasets would dramatically help in building an accurate dispersion model. I would like to make the model public even if the underlying data remains private. I will publicly shout out and thank any company willing to assist every time I discuss the model in the future.
Thankfully, there is quite a bit of data out there that I am able to access. I really appreciate the following work:
Mark Broadie: Every Shot Counts.2
Mark Broadie and Soonmin Ko: “A simulation model to analyze the impact of distance and direction on golf scores.”3
Arccos: Arccos Annual Driving Distance Report 2026 Edition.4
Shot Scope: Annual Golf Performance Report 2026 Edition.5
Shot Scope: “Approach shots: average proximity to the hole.”6
Lou Stagner’s newsletter: “Fairway Bunkers.”7
Hireko Golf: “Average Distance for Each Golf Club: The Complete Chart by Skill Level.”8
Finally, I found a dataset that claimed to be a Shotlink database with what appeared to be legitimate data from tournaments between 2015 and 2017. Because I couldn’t know for sure whether or not it was actual data, I only used it to fill in some gaps.9
I started by building a theoretical dispersion pattern. The intuition on what it should look like comes from the model described in “A simulation model to analyze the impact of distance and direction on golf scores” by Brodie and Ko.10 Importantly, they use a polar coordinate system rather than a grid. This ends up being incredibly important and automatically scales the distribution as distance increases. The other important feature that Brodie and Ko’s model incorporates is a “good shot” and “bad shot” aspect for calculating how far the shot ends up going.

I chose a different approach to how “good shots” and “bad shots” are used in the overall dispersion because I wanted to include player handedness. Including player handedness allows us to skew the shot distribution long-left and short-right, which is one of the more important parts of the golf swing that can be lost in generalized data.

The “good shot” distribution is currently a normal, bivariate distribution along the polar coordinates. This, in hindsight, may be a mistake. A Student’s t-distribution might end up being more accurate to the existing data, and I will likely adjust the model in the future if that fits better.
The “bad shot” distribution is completely different. The lateral error remains normally distributed where the shot misses left or right, but the distance of the shot is distributed effectively randomly. We should end up with a discrete uniform distribution.

Note here that each of these distributions use methods that specifically prevent data from randomly clumping together. I do this so that the samples remain smooth across the probability distribution, avoiding the potential for random artifacts.11
It actually took a few attempts to find a good probability of a “bad shot.”1213 I finally settled on using Brodie’s “Awful shot scorecard” data from Every Shot Counts. Here, I was able to calculate a reasonable probability of “bad shots” simply by taking “strokes lost per round to awful shots,” and dividing it by the total shots taken by each type of player. This ended up being a fairly elegant solution that came very close to matching the few pieces of shot data I could find.
To determine the length of a “bad shot,” I eventually looked at the Shot Scope drive distance averages and the “well struck” drive distance averages.14 After trying a few different ways to interpret this data, I found that what works is to assume “well struck” driving distances were just the shots that averaged one standard deviation beyond the mean for all drives. This assumption yielded the most realistic results when compared to the one driving dispersion pattern I found. Knowing what a “well struck” drive looks like means we can calculate what a “poorly struck” drive looks like and how far we should expect it to go. With this realistic distance delta between good and bad shots, we can set a ceiling for how far our poorly hit shots should travel.

The only thing I added arbitrarily, without any supporting data, is a tilt in the dispersion patterns. I was simply unable to find a dataset with dispersion patterns of golfers based on handedness.
Right-handed players tend to miss long-left and short-right because of swing dynamics. I’ve been fitted for clubs, and have seen my dispersion patterns across clubs. I just tried to eyeball this adjustment. It should not significantly change the data, but if anyone has any idea how to base this adjustment in reality, let me know.
Next, pure distributions tend to scale beyond realism. Shots should be limited by the physical limits of the players hitting the ball. There really isn’t some tiny probability that a 15 handicap blades a 6 iron 400 yards. It’s never going to happen. To account for this I apply a “squish” to the distribution, where shots long are squished down within a limited theoretical max distance. I also skew shorter shots even shorter to reflect the way fades tend to balloon in the air. It’s a minor adjustment, but it is meant to represent how air resistance should affect shots, and should affect longer shots more than shorter shots.
Finally, I apply an adjustment so that shots do not finish behind where they started. Instead of changing the entire dispersion pattern, I just add another “squish” where shots that end up too short or behind the starting point are proportionally squeezed into the five-yard area in front of the starting spot. This should represent chunked shots pretty well.

What we have now is a kind of arbitrary “shape” to the data; it looks a bit like a teardrop. However, this shape is effectively theoretical, and we need to fit that shape to a size that reflects how people actually play at different handicaps. We actually have quite a bit of data that helps us do this in Mark Brodie’s book, Every Shot Counts. There he lists fairway and rough “median leave” data that allow us to know exactly how many yards the median shot in our dispersion pattern should be from the hole from different distances.
This is probably the most important step in the entire process. We adjust our distribution to reflect the data by adjusting its scale repeatedly until it reflects reality. We do this by simply expanding or contracting the variance of the distribution, over and over, until we’ve found the scale of the variance that most closely matches the data. Once we have the appropriate scalars for each distance in the dataset, it’s fairly straightforward to fill in gaps between the other distances and other handicaps. This works great for shots from the fairway and rough, but things are more difficult from bunkers.
We can use the same median leave calculation for short sand shots in Brodie’s data, but that data only exists for distances inside 40 yards. We can extend this a bit with Shot Scope’s data, but that data is vague at best. Unfortunately, I haven’t found any real distribution data for bunker shots over 100 yards.

To try to address this as accurately as possible, I incorporate Lou Stagner’s dataset to calculate the “distance penalty” for long shots from sand. To find a distribution, I have to turn to the Shotlink data and hope it’s accurate. I use that to calculate the distribution changes for pros between fairway and sand, and then assume those ratios scale to higher handicaps. It’s synthetic data, yes, but I don’t really have any other way to guess at the shape of these distributions.

When we think of a player hitting a golf shot, each club has a different distribution pattern and ideal distance. Unfortunately, the model basically does the opposite. The distributions are based on the distances we’re hitting, but we can then choose a club that should best match that shot.
Ultimately, we get our club distance data from Hireko Golf (which in turn cites its data from Shot Scope, TrackMan, and Arccos. I’m not happy about all these abstractions, but this is what I’m working with). I thought about adding an error to the output of a club for hitting it shorter than one optimally should – e.g., applying an increasing distance error for hitting a 6 iron the length of a 9 iron to simulate a low runner – but doing this opens up so many potential problems that it’s just not practical right now. So right now the “club used” remains effectively arbitrary.
We’ve set up our distribution using ideas based in theory. We’ve tied that theory to the data using scalars. The result is that any shot at any distance hit by any handicap on any surface can be modeled. And it can be modeled to a “reasonable approximation” of reality.
It’s certainly not going to be perfect. And it really can’t be. We’re modeling data averages, when the actual differences in shot type between individuals is pretty large.15 Ultimately, that actual data from humans does exist, most people just don’t have access to it. However, for illustration of general concepts, it should be reasonable to fall back on this kind of general model.
Creating a shot pattern now takes four inputs: distance, lie type (fairway, rough, sand), player handicap, and player handedness (to flip the dispersion tilt for lefties). We also add in the number of shots we want simulated. We sample shots more evenly than we would expect from data to reduce noise, because our goal is creating architectural heatmaps.16
I also built a visualizer that shows where shots are most likely to finish and with general probabilities. This makes it easier to see the main dispersion area around the target and the larger miss patterns outside it.17 The main purpose of the visualizer is to see if our results are completely out of touch with reality. And at first, they were.
Throughout the development process, I’ve been comparing my model’s output to Broadie and Ko’s work. They have three published dispersion patterns, and I compared these outputs at each stage of development to look for obvious mistakes. It took quite a bit of tinkering to get outputs that seemed reasonable.

As we can see above, the final results should reasonably approximate the existing data. It’s not perfect, but I’m working with very little here, and these researchers had direct access to datasets that should make the process more straightforward.
If anyone is interested in working on this with me, reach out. Again, better and more plentiful data should obviously lead to a superior generalized model. I think I’ve done a fairly reasonable job here, but when real player data already exists, any model like mine will be inferior. Thus, I see no reason not to share the code with others to help improve it. If you want to help make it better, you can find the code here on github, just maybe be nice about the fact that a significant amount of the code was LLM assisted. I’ve released it under an MIT license so anyone can use it.
It will take a bit of time to actually connect this dispersion generator to the architectural mapping model, but when that has happened, we should see much, much more realistic architectural visualizations. I still need to build a putting model, and that will come, but now I should be able to talk about variance in golf design much more realistically.
Please share this post with someone. It really helps me find readers. Thanks!