Fully customisable Coxcomb Chart with Targets

Example of what you can create using this tutorial

Link to the viz: https://t.co/r9uDJSfstu

Fully customisable Coxcomb Chart with Targets

It has been a been a while since I last wrote a blog post but the subject of this post has come from a solution I built recently for a professional sports team client (sadly I cannot name).  Their request was to build a Coxcomb chart to allow them to compare their own players to the league average of players in a similar position, or targets that they can set.  Now normally we would say a bar chart would be a better visual for comparisons or bullet charts for targets, but here the metrics used are not necessarily linked and the client liked the interesting visual a Coxcomb gives and one they felt would spark more interest from their senior management.

Naturally I looked towards the Tableau community for inspiration, tutorials or templates.  Yet all that I could find didn’t quite fit the bill of being able to set targets in a Coxcomb chart and also they didn’t feel right for passing this work across to the client for them to manage.  I felt the tutorials and solutions were going to be too tricky to understand or maintain – with lots of complicated calculations required and custom image backgrounds.

So I set to work to come up with my own solution that first removed the need for custom image backgrounds and the immediate thought of using Map Layers.  I thought; if you could use the data to draw the background then any solution would be adaptable and much more flexible.    The other thing to note about Map Layers is they cannot work if you have any Table Calculations – which for this scenario is actually a good thing, Table Calcs in Tableau can be confusing to set up, especially with bespoke visuals.   The client I was working for was not the more adept in Tableau and so any simplification I could create would be an advantage.

So I set about to developing the following solution.  

 

Before I go into the build of this solution, I will say that the linked workbook (below) has all the calculations annotated within, so if you don’t want to read on and just pick up the workbook, well, I won’t hold it against you!!!

Link to the template:

Template - Tableau Public

 

The other point is I won’t duplicate the wording here in the blog and the calculation images with contain the explanations as to why the calcs are like they are.

 

So with that all said, lets start….

 

Data

As always we need to just go through the data structure before we can dive into the Tableau build.   For this build I will be using two data sources (both Excel files).  The main data source contains all the player information, in this case I have collected data from ESPN about the current Six Nations Championship (Rugby Union).  The data is very vertical, with a row for each different metric per player, per round of the Championship.  The data originally was very wide in its format and I pivoted it using Tableau Prep. 

This is a snippet of the main data source:


The second data source is actually just a single column of numbers running from 0 to 99 (i.e. 100 rows).  This is our ‘data model’ that we will use to densify (sometime referred to as ‘scaffolding’) our data.  We will join the two data sources (explained in a moment) to inflate our main data source, so that effectively each row of our main data source is duplicated 100 times (once for each row of our data model).

“WHY!?” I hear you cry!

Well, we need to densify our data in order to instruct Tableau to draw curves.  We’ll need around 100 points to draw a ‘smooth’ curved line.  Note: Tableau actually draws straight lines between each point, but having a high number of points to a curve we draw means that its hard to see each straight line and therefore the curve ‘looks’ like it is actually smooth – when it isn’t.  To plot each point on a curve we will need our main data to determine where we plot.  So this is why we need to duplicate each row of our main data 100 times.

Here is a picture of the structure of the ‘data model’ I am joining to the main data source:


So how do I join the data?

Actually I’ll be doing this using Tableau in the Logical Layer using relationships.  See image below:

A side note here:  I do not have to use Tableau Desktop to do this.  I could have used Tableau Prep and joined the Main Data with the Data Model before bringing into Tableau, but I didn’t want this densification of the data to be hidden from anyone downloading my workbook and keep it there for transparency of the process.  The other point is, this densification will also work at the Physical Layer in Tableau Desktop Data Source pane, with a true Left Join.  Any of the three methods would work.

 

With the relationship join, I created a Relationship Calculation and simply typed the number Zero in the calculation.  This would repeated on both sides of the join and forms the common dimension that the two tables will join.  Essentially this is creating a column in each that has Zero on every row.  Tableau will densify, by saying for every Zero row in the Main Data source join all rows that have a matching dimension (Zero) in the Data Model source.  This is how the densification works.

 

Screenshots of the relationship join and relationship calculation.




Now we have our data and we have densified it we can begin our build of the Coxcomb.

 

The Build

So here we go, as stated above the explanations of each calculations are written in the screenshots and are in the workbook, so I won’t repeat myself here and make this blog any longer than it needs to be.

So to start we will need to set up some calculations which will form the basis of the build, as follows:


Metric_ID:




Metric_Name:


a_Player_Values_SUM:  

We are summing here because I have decided for the tutorial that the Coxcomb will show the total values of each metric for each player for the whole of the Six Nations Championship.  In my final viz, I have created the option to alter this calculation to show the Maximum value scored by a player in any round of the Championship or even their Average score per metric across the games they played.  But here we will stick to totals and therefore SUM




b_Position_Values_MAX:


c_Normalised_Plot_Values:

 

d_Position_Values_AVG: 

 

e_Normalised_Plot_Targets:

We now come to the calculations that will form the actual build of the Coxcomb and will refer to the previous calculations we have just seen.


1_Point_Type:



2_Curve_Points:



A Coxcomb chart is a radial chart and therefore we will need to build out some classic trigonometry calculations. 

Remember our end goal here is to use Map Layers.  Map Layers traditionally plot using Longitude and Latitude values, but it is possible to ‘hack’ it (explained later) so that Map Layers use an X & Y coordinate base.  We will be using trigonometry to calculate those X & Y coordinates. 

We will also be seemingly duplicating calculations here.  These duplicates will form the basis for each individual layer in our Map Layers.  We will be building these layers (to start with and more later):

a_Plot – the main coxcomb plot

b_Axis – the background ‘image’ of the axis / range of the coxcomb.

c_Targets – plotting the target positions for each metric.

 

The Trig.

3a_Radius_Plot:


3b_Radius_Axis:



3d_Radius_Targets:  
Wait!  What happened to “3c”? - that will come later!




NOW JUST PAY ATTENTION HERE!
We need to make two parameters to help us control our coxcomb.

1. # of Segments (Metrics), Integer, value = 12 (note 12 is the number of segments I want, change this value to the number YOU want in your own viz.

2. Angle Adjustment (Degrees), Integer, value = 90, Range 0 to 360 steps of 1.  I set my value to 90 to move some metrics that were poor player performance indicators to the top right of my coxcomb.

4_Angle:

 

5a_X_Plot:


5b_X_Axis:


5d_X_Targets:


6a_Y_Plot:


6b_Y_Axis:


6d_Y_Targets:


7a_MakePoint_Plot:


7b_MakePoint_Axis:


7d_MakePoint_Targets:


Now for a couple of calculations to help control the colour of the Coxcomb so we can easily see which players are scoring more or less than the Championship Average.  The other calculation to ensure the targets will again show up well either against the background colour or the colour of the coxcomb segments.

 

Metrics (group) - for Colouring:

I actually in my data set have some metrics that are positive (good things for a player to score in) and others that are negative (bads scores).  I wanted to reflect that in the colouring of the coxcomb segments, so I created a simple Grouping of the metrics, giving the groups these headers:



Colour_Plot:



Colour_Target:


Well done if you’ve made it this far now let put all this to good use and start dragging fields onto the worksheet.


Before we do that, lets just reflect on the fields we have just created and try to give a little context to where each sits in our build going forward.


Stage 1: Creating the basic Coxcomb.

To begin with we will create the very basic, stripped back Coxcomb chart, before moving on to create more calculations to really allow us to customise and add a little flourish to the chart.  

This is what we the basic Coxcomb will look like when we have complete the stage 1 build:




Step 1.
Start a new empty worksheet and then drag your "7a_MakePoint_Plot" calculation onto the Detail shelf.  This will generate Longitude and Latitude pills on Columns and Rows.

This will actually tell Tableau to create a map and you may even see some map features (landscape, coastline, roads etc) appear on your screen.  Do not panic, this is to be expected.

Step 2.
Next drag "7b_MakePoint_Axis" calculation to the area of the worksheet as shown below.  This will create a 2nd Marks Card, which will form the basis for creating the axis background.



Step 3.
THIS IS THE HACK I mentioned at the beginning of the blog.
Swap the Longitude and Latitude pills with each other.  Easiest way is to select the 'Swap Rows and Columns' button from the toolbar, as shown below.



Step 4.
Next drag "7d_MakePoint_Targets" onto the worksheet as in Step 2 above, to create a third Marks Card (this is the beauty of Map Layers, there is no limit on the number of marks cards).


Step 5.
Before we overload our worksheet with every possible row of data we need to apply some filters.  These are the filters I applied:
  • Metric_ID:  I selected 12 metrics I was interested in (this will be the number of Segments)
  • Pos Desc1: i.e. what position am I interested in.  I selected just a single position here, Scrum Half
  • Player:  Again, to reduce it down I only want to look at a single player, J Gibson-Park.
Metric_ID and Pos Desc1 were both added to Context (right-click each pill and select Add to Context).  So that these filter the data down before our normalisation of values and targets are calculated.



Step 6.  Plot_Player_Scores (aka. 7a_MakePoint_Plot)
  • Change the mark type to Polygon
  • Drag on all the pills as shown in the image below.
  • Take note that Points is set to Path and this is a Dimension.


Step 7.  Axis_Background (aka. 7b_MakePoint_Axis)
  • Change the mark type to Polygon
  • Drag on all the pills as shown in the image below.
  • Take note that Points is set to Path and this is a Dimension.


Step 8.  Targets_Championship_Av (aka. 7d_MakePoint_Targets)
  • Change the mark type to Line
  • Drag on all the pills as shown in the image below.
  • Take note that Points is set to Path and this is a Dimension.


Step 9. 
Now we just need to reorder the marks cards so that the Axis Marks card sits at the bottom and the Target on the top.




Step 10. 
You should now have something like this - looks hideous right! ha



Step 11. 
We are actually done on the basic build, except for some formatting and this is a great example why formatting can make the world of difference to a visualisation.

Try applying these settings:

7b_MakePoint_Axis:
  • Colour fill, #f4f4f4 (lightest grey)
  • Border, #d9d9d6 (light grey)
7a_MakePoint_Plot:
  • Colour, "Other < League_Av.", #989dae
  • Colour, "Other > League_Av.", #666c82
  • Colour, "Positive Contributions < League Av.", #a3dbe1
  • Colour, "Positive Contributions > League Av.", #54bdc9
  • Border, #FFFFFF (white)
7d_MakePoint_Targets:
  • Colour, "False", #323744
  • Colour, "True.", #FFFFFF
  • Size, 25% thickness (i.e. drag the slider about a quarter of the way from the left)

Step 12. 
You will then end up with something that looks like this! - much better!



That's it for the Basic Build of the Coxcomb - no messy Table Calculations and no background images to draw, save, line up, resize, draw again until you get it right.  

The beauty of this is the background is drawn in the worksheet using the data.  So if you take out segments / metrics, your background adjusts with it.

Take a breather.

So if you are still with me to this point and you are game for more.  The next section will take you through to adding a little more pizazz to the viz!  To create this:




PAY ATTENTION HERE!
We first need to create a few parameters to help us

1. Metric Label Adjustment (Radius), Float, value = 1.12.  This is just a value I found that works to place the metric labels outside of the the axis, but not too close it overlaps or so far away it looks disconnected. 

2. Show plot value if greater than (Radius), Float, value = 0.3, Range 0 to 2.  This will form the basis of our control on plot labels to only appear if the plot itself for that metric is big enough.  This stops all labels being shown and overlapping or obscuring the view of the plot.


Now we are ready to create some more calculations, as follows.

3c_Radius_Metric Label:




5c_X_Metric_Label:




5e_X_Plot_Values:




6c_Y_Metric_Label:



6c_Y_Plot_Values:



7c_MakePoint_Metric_Labels:



7e_MakePoint_Plot_Values:



7f_MakePoint_Club_Icon:




7g_MakePoint_Player_Name:




Plot_Value_Label:




OK, that's a few more calculations created, let's reflect again.  This time concentrate on the 4 columns with the blue headers - these are what we will add to the visualisation next.


Stage 2: Creating the intermediate level Coxcomb.

This next stage is going to take our Coxcomb chart from good to great.  We need to add labels to aid the understanding of our chart, but the best part is with Map Layers we can control where those labels appear.

Step 13
Drag onto the worksheet the following MakePoint calculations (as per the image below).
  • 7c_MakePoint_Metric_Labels
  • 7e_MakePoint_Plot_Values
  • 7f_MakePoint_Club_Icon
  • 7g_MakePoint_Player_Name




Step 14. Metric_Labels (aka. 7c_MakePoint_Metric_Labels)
  • Change the mark type to Circle
  • Drag on all the pills as shown in the image below.
  • Take note that Metric_Name and b_Position_Values_Max are set to Label

 


Step 15. Plot_Labels (aka. 7e_MakePoint_Plot_Values)
  • Change the mark type to Circle
  • Drag on all the pills as shown in the image below.
  • Take note that Plot_Value_Label is set to Label


Step 16. Icon_Team (aka. 7f_MakePoint_Club_Icon)
  • Change the mark type to Shape
  • Drag on all the pills as shown in the image below.
  • Take note that Team is set to Shape


Step 17. Player_Name (aka. 7g_MakePoint_Player_Name)
  • Change the mark type to Square
  • Drag on all the pills as shown in the image below.
  • Take note that Player and Pos Desc1 are set to Label


This should now give you something like this (see below) - again it needs some formatting to get it looking polished.



Firstly though, we need to sort out the two axis (Columns and Rows).   Our coxcomb chart as it stands is actually being warped by the fact our axis are not the same length.  I can demonstrate this if I exaggerate the effect by increasing the length of the x-axis below:

 


To solve this simply make these changes:

  • X-Axis:  Fixed Start = -1.325 , Fixed End = 1.325 (total length of 2.65)
  • Y-Axis: Fixed Start = -1.15 , Fixed End = 1.5 (total length of 2.65)

This will mean our radial plots will now be completely circular.


Nearly done!

Lets finish off this tutorial with some formatting changes....


Metric_Labels (aka. 7c_MakePoint_Metric_Labels)

  • Colour, Opacity = 0%, Border = None
  • Size = 0% (i.e. move slider to the far left)
  • Labels, Font = Tableau Light, I made the Metric_Name 8pt and b_Position_Values_MAX 7pt
  • Alignment = Centre

Plot_Labels (aka. 7e_MakePoint_Plot_Values)

    • Colour, Opacity = 0%, Border = None
    • Size = 0% (i.e. move slider to the far left)
    • Labels, Font = Tableau Medium, 8pt, #FFFFFF
    • Alignment = Centre

    Icon_Team (aka. 7f_MakePoint_Club_Icon)

    • Shape = apply appropriate shape for your team/club, I used the National logos for each team
    • Size = YOU judge it by eye

    Player_Name (aka. 7g_MakePoint_Player_Name)

    • Colour, Opacity = 0%, Border = None
    • Size = 0% (i.e. move slider to the far left)
    • Player, Tableau Semibold, 28pt, Right Aligned
    • Pos Desc1, Tableau Book, 9pt, Right Aligned


    You will then end up with this set up:

     


     And that is it for the tutorial!


    There is of course so much more you can do with this and I encourage you to look at my visualisation on the 2022 Six Nations, that I have only just published.  Here I went even further with the map layers to show each round individually next to the main plot.  I also created a Trellis Chart, so I could show ALL players from the same playing position and then make comparisons.  Lastly I made the coxcomb even more adaptable from an analysis perspective, allowing the user to chose to compare scores at a Total Score level, Maximum scores across all rounds, Average scores across all rounds, and then make the target lines adaptable to compare to only that player's own position or all players from all positions.

    2022 Six Nations Player Performance


    Thank you for reading,

    Sam






    Comments

    1. Hi Samuel,

      First of all, good job on writing such a lengthy and detailed post to the tableau template. Well done! I've been looking for a proper coxcomb chart step-by-step tutorial since I have a project I've been working on. I have made a chart in Python that uses 3 dimensions (table columns). It is some sort of pie chart where I'm representing a column using radius, pie slice size to represent another column, as well as color to represent another column.

      So far, in Tableau I've managed to create a pie chart where I'm making use of angle and colour to represent two dimensions but I couldn't change the radius in the piechart. I've tried dual-axis but that wasn't enough because I couldn't adjust each slice's radius.

      Now, in Tableau I've been having a rough time finding a way to adjust the radius. My research eventually led me to finding out about this custom type chart, so I managed to create a basic coxcomb where I'm using a dimension that is represented by the length of each however I can't seem to plot the other two dimensions.

      I'd like to know if it's possible in coxcomb chart to adjust the width of a bar? Also, Is it possible to plot the color based on a certain measure, a continuous value?

      ReplyDelete
    2. Fantastic viz and tutorial, much helpful. Thanks for your sharing

      ReplyDelete

    Post a Comment