Hi all,

A warm welcome back. This week we are going to look at small multiples. They can be a little fiddly at times due to various reasons, mainly because of null fields.

We will look to explain some of these nuances as well as plot our all important football shot map charts. We will further our work by making our small multiples use more than one layer, allowing greater flexibility in build.

Where to start? 

Well we will be using the 2021/22 season premier league data, that you can find a copy under the Github repo, or run your own version of the data from main.py that uses the understatapi package to collate the data. I have previously blogged about this data collection here.

What transformations do we need?

Well our small multiples doesn’t like null values, so we can’t go down our traditional route of following Andy K’s video tutorial. (Yes I revisit this blog every time I need to copy and paste his calculations!) This means that our grid function needs essentially hardcoding the values this time round. You can read up more on the impact of nulls on small multiples in this blog by Gwilym.

So i’ve made a solution in Alteryx that can be applied to small multiples to always allow for updating datasets. You can find it in the repo.

What does the flow do?

We take the original dataset and firstly identify whether the shot was taken by a home or attacking player. (of course we could have done this in tableau, but while we are here – why not. I also look to scale the X and Y co-ordinates up slightly for convenience.

We then take a unique list of all the teams. (Of course, 20 records, given the number of teams in the Premier League) Next we allocating them a RecordID, 0 through 19.

We introduce two calculations, the equivalent to the column and row headers seen in both Gwelyn’s blog that hardcodes the values and Andy’s blog that uses index and sizing calculations. My calculations use a floor calc, and a modular calculation.

You can see how this builds out the different column and row dividers we will need.

Finally, we glue it back to our original dataset on the team field, and export it to player_shot_data_small_multiples.csv. Again this file can be found in the repository if you want to compare the final output vs the original input.

Now we have that small amount of transformation out the way we can go ahead and build our visualisation.


Lets start our calculations with the standard X & Y scatter in make points. Reason being we can plot multiple layers this way, as well as add our background image.

MP. Pitch


Double click to bring it into the view.

All our shots from the season! Looks messy without a pitch though doesn’t it.

Lets split our data by team.

Drag Column onto Columns, and Row onto Rows. Make them both discrete dimensions.

Make the marks a circle while adding X & Y onto the marks card also as dimensions.

Looks like blue paint splatter but we can soon fix this. Lets get the pitch in. A copy of the basic pitch can be found in the GitRepo.

Go to maps and turn off the back ground map.

Then go to maps, background map. You can use the X & y Field co-ordinate mapping from my print screen if you have used my data flow, if not these will need to be configured based on the scale of your X and Y data.

Tips to getting this correct. 1) Make sure you are using latitude and longitude in your x and y field. 2) Play around with the options whether you want to lock the aspect ratio and show the entire image. Because I only wanted a zoomed in version of the pitch I don’t have these ticked myself. 3) On your dashboard, turn your map options off to stop the pitch zooming in.

We can edit the axis of the latitude (i.e y-axis) to give some breathing space to the viz and rescale the pitch to amount of pitch we want to show. Same goes for the longitude (i.e x axis)

Lets do some cosmetic changes, including tooltips, axis reshaping and colour.

You will notice in the above print-screen I’ve made some space in my chart now for some Headers and where i’ll add the number of goals. (result = Goal, on filter)

We create a placeholder with Y axis 1.3 in this case, and in the middle of the box with an X axis of 0.4. By dragging the team name onto the view and the fixed calculation of number of goals per team we can add in this final additional context to finalise the visual. Just remember to turn back on your map to drag the extra layer back on!

All goes well, you should have your final visual. Truth be told we could still make this a lot prettier with a few more formatting concepts, but I think it’s an adequate enough starting basis for people to run with the idea.

Some final things to consider

It’s worth checking your data is correct with a cross reference. I ended up using footystats. I find this important to see if I really have an accurate number of goals on labels. It instantly made me realise that I have excluded the own goals from the dataset. (I’m fine with that for now, but it would take extra work to amend whether you want this showing on the team it was for, or the team that conceded the own goals shot map) Hence why some discrepancies exist when comparing to the league table of Goals For.

Another way to check is to actually use the understat dataset, For example I can take a player like Emile Smith-Rowe, This made me realise I had to actually mirror my x axis points.

As seen below.

Hopefully that has been useful as to how to build small multiple soccer shot maps.

You can also see how I experimented previously with hardcoded calculations in this hex shot map visual, and this NBA visual.