Hi all,

At the end of last year I revised one of my Tennis visualisations for a third time that included a chord diagram. The accompanying blog seems to be gaining a fair amount of traction in terms of views.

I was also pretty glad to see one of my favourite designers in the community, Lindsay Betzendahl use the chart as inspiration for her Iron Viz feeder for her Wordle games entry. Do Check it out, it was certainly one of my favourites from this years entries.

So here we are, doing more on chords.

For those that follow my blogs, I create all my chord charts in the same structure as follows:

  • Rank your points
  • Find the angle needed to separate them
  • Spread them equally using the rank and angle
  • Make them circular using trigonometry

That logic goes for any circle really.

Today we will take some of that logic I’ve previously written about but create a chart that has:

  • The start and end points as flexible points
  • An ability to increase and decrease the spacing
  • Re-introduce middling points for the chords (Bezier curves)

As always, the dataset can be found on the Github page at the top of the page. The visualisation can be found on the following link on Tableau Public.

I think by this stage I don’t need to do all the disclaimer malarkey of telling you where and when is appropriate to use a chart like this, so lets just crack on. This will be a run-through as oppose to template for that very reason.

The Data

We have a list of the LPGA Number 1’s of each year split by Player and Country.

Each of these in our final chart will need their own mark, so I’ve given them a rank ascending from the most recent year down to the earliest record. This will form the out spread of our chord.

We will want our starting co-ordinates to come from the country, then fan out to the players. Therefore they all need their own rank value. In this case, I simply find the distinct in a new sheet and number them and rejoin that data in.

The final tab on the excel is the value T. This is 100 points (don’t change this) We are just going to use them to plot the chord in between our start and end points.

Here’s what the join should look like in Tableau. Glue in your inner tab on the inner rank names, i.e country. and then create a custom join of 1=1 to blow the dataset up in terms of 100 new records for each individual row in our original dataset.

Let’s create the original circle

00. Rank

[Outer Rank]

01. Angle

360/{fixed: COUNTD([Outer Rank])}

02. Rank Angle

[00. Rank]*[01. Angle]

03. End X

cos(RADIANS([02. Rank Angle]))

04. End Y

sin(RADIANS([02. Rank Angle]))

Told you I make all circles the same way. Okay lets plot X against Y.

So at the moment we have a circle, but really we will want to squash these points together and move them around.

Let’s go back and amend the Angle calculation. First we will need to make a parameter, this will be a float between 1 and 4 with increments of 0.1.

Amend your angle calculation now to

01. Angle

360/{fixed: COUNTD([Outer Rank])}
/ [01. Outer Spacing]

Have a play around with the parameter value to see how it impacts the circle, here is the two extremes. 1, which is our original circle. 2 Which is a half circle

To an extreme of 4,

Technical term, see how they get squished together.

Okay, But now we may want to actually rotate these values. So lets add in some new calculations that allows us to rotate these points about our origin 0,0.

First lets create a parameter

02. Outer Rotate

You’ll see that we make the parameter between values 0 and 360, so we can spin our points to any position on the circle.

Next create our two new calculations

03. End X Rotated

([03. End X]*cos(radians([02. Outer Rotate]))) – ([04. End Y]*sin(radians(([02. Outer Rotate]))))+0


03. End Y Rotated

([03. End X]*sin(radians([02. Outer Rotate])))+ ([04. End Y]*cos(radians([02. Outer Rotate])))

If you’d like to learn more about what these calculations do, you can read more from this blog here. Or even better read my blog on Understanding Polygons 1.

All goes well you can now plot your end points and rotate them.

Here are a few variations

Cool, now we have some end points finally.

Time to repeat the process for our start points.

10. Rank

[Inner Rank]

Create a new parameter 11. Inner Spacing, to be the same set up as the outer spacing.

11. Angle

360/{fixed: COUNTD([Inner Rank])}
/ [11. Inner Spacing]

12. Rank Angle

[10. Rank]*[11. Angle]

13. Start X

cos(RADIANS([12. Rank Angle]))

14. Start Y

sin(RADIANS([12. Rank Angle]))

All goes well you should be able to plot your start X and Y against one another to create a circle

Of course we can amend our Inner Spacing parameter to squeeze our points together. Finally we want to rotate these around our origin 0,0.

Lets duplicate our Outer Rotate parameter details but name it Inner Rotate

Lets apply our final rotation calculations to our start points.

13. Start X Rotated

([13. Start X]*cos(radians([12. Inner Rotate]))) – ([14. Start Y]*sin(radians(([12. Inner Rotate]))))+0

13. Start Y Rotated

([13. Start X]*sin(radians([12. Inner Rotate])))+ ([14. Start Y]*cos(radians([12. Inner Rotate])))

All goes well,

Now you should have your start points radially plotted, as well as your end points. These are both dynamic so we will be able to amend these moving forwards using our inner and outer spacing and rotate parameters.

The final part we need is the chords!

Lets create two new calculations for some mid points.

21. Mid X


21. Mid Y


as well as a calculation for making sure our additional 100 points are to scale.

22. TT


Finally we can build the chords,

31. Bezier X

((1-[22. TT])^2*[13. Start X Rotated]+2*(1-[22. TT])*[22. TT]*[21. Mid X]+[22. TT]^2*[03. End X Rotated])

32. Bezier Y

((1-[22. TT])^2*[13. Start Y Rotated]+ 2*(1-[22. TT])*[22. TT]*[21. Mid Y]+[22. TT]^2*[03. End Y Rotated])

We can plot these as our final components

By playing around with our spacing parameters, Rotation parameters as well as our midpoints we can now customise our chord to our desired effect.

To add a few more details, we can use map layers, to bring in the start and end dots, with different tooltip information.

Check out my quick visualisation showcasing the LPGA Player Of The Year data.

I made a few minor adjustments to close out the shape of the visual.

  • I re-arranged the ranking of my countries as I wanted the chords to bend in specific ways, left and right.
  • I did consider moving my mid points but ended up reverting them back to zero.

To recap, we cover off how to make circles, we then understand how to squeeze these points together and move them radially around our origin of 0,0. Finally we build a bezier curve between the start and end points.

Some pretty deep calculations putting this one together, let me know how you get on with it.