Drawing Curves on a Map: Radial Concept

This blog outlines steps as to how to make a radial map. The original data is attached within the blog.

Hello! Back again with a visualisation that can only be described as ‘marmite’ best practice. This time, looking at curved lines on a map. Through endless scrolling on Pinterest, mixed with a clear love for radial vizzes, I was trying to piece together a few ideas before remembering the perfect guest blog by Wendy Shijia on the Flerlage Twins site.

This blog will cover a run-through of how I created a recent “A night in Paris” visualisation. It is by far my least “favourited” visualisation on Tableau Public… seems marmite is less liked than I first thought! Nonetheless, If you’d like to follow along, take a copy of my dataset from here. This is an adapted dataset of the original from AirBnB. You can also find the original dashboard on my profile, here.

As a pre-requisite, do visit Ken’s fantastic blog on the concepts of data densification here. It’s so easy to follow and will help understand some of the calculations seen below. Before making this visualisation I ended up deconstructing Ken’s work to gain a better understanding how the data densified points spacing, and sigmoid curve worked. You can find these two downloadable workbooks on my profile under Data Densification (Development) and Data Densification (Development V2).

The two workbooks are meant to be progressive so that you initially understand data densification between two points. Then apply these techniques radially. Finally the blog below adjusts a lot of the calculations to be applied to a map scenario with adjustments made to Longitude and Latitudes!

Wendy’s original blog builds a foundation for the first few steps required in terms of data prep. I’d recommend seeing if you can navigate your way through this tutorial first. It also offers a fantastic explanation of how the Mercator map works in terms of projection of Latitude and Longitudes. Thank you to both Ken and Wendy for their super useful insights.

Getting Started: Data Prep

Sheet: ParisData

1. What is important in this dataset is to have our Start X and Start Y (Longitude and Latitude) co-ordinates for where their initial position (Airbnb rooms) will start on the map.

2. We will want to also consider what our end points will be. For my user case I split the rooms offered by availability. E.g. each room will then draw a curved line to one of three places. It doesn’t matter how many categories you have, as we will adjust for this in the workbook calculations. You may notice we do not have an End X and Y location, because we will be creating these!

3. The last important thing is that we will want our lines between the start and end points to be curved. This requires an inner join between the Paris Data Sheet and Join Sheet, using the join column. We will be creating 100 points between the start and end point, along a curve. This is why we have the Join Sheet with values of T running from 1 to 100.

Once we have the data prepped we can start to create the calculations needed

Workbook Calculations:

1a. AVG Centre X

{ FIXED : AVG([Start X])}

Explanation: This is the average of all the X points. We will want to offset our final points when it comes to the circular calculations by this amount to find the end points.

1b. AVG Centre Y

{ FIXED : AVG([Start Y])}

Explanation: Same theory as above but for Y. We want to offset our co-ordinates to be adjusted around our map points.

Category End

CASE [Available Category]
when ‘A’ then 1 when ‘B’ then 2 when ‘C’ then 3 END

Explanation: We want the rank to be numbers, with 1 being the first, going radially round. This is a bit messy on my part but hopefully makes sense that the order you want the categories to go round clockwise will be dependent on the case statement you build here with the rank numbers.

1c. Rank

[Category End]

Explanation: This is the different end flow category. We will need these as ranks to split going radial

1d. Angle

360/3

Explanation: We want to divide a full circle evenly into our three categories. Here we will need to adjust if you have less or more categories. Play around with this value once you’ve created your viz to see how it impacts end parts of your visualisation. This in effect is the spacing between your end categories around the edge of the circle.

1e. Rank Angle

([1c. Rank] * [1d. Angle])

Explanation: We multiply the rank by the angle to find the positioning around the edge of the circle. Again play around with this calculation at the end to see how it adjusts the end points. I decided to edit this calculation to make all my end points stay on the right side of the viz.

2a. End X

(sin(radians([1e. Rank Angle]))* 0.031)
+ [1a. AVG Centre X]

Explanation: The radians and sin part of the equation makes our end circular points. The *0.031 is discretionary based on how far out you want the radius to be. E.g. this will depend on the size of your map. Personally, I would recommend plotting on a map where you want to have the edge of the circle reach, and then minus the average Centre X from this to find the value. E.g. the length of the radius around the centre point! Check out the below:

2b. End Y

(COS(radians([1e. Rank Angle]))*0.0205) + [1b. AVG Centre Y]

Explanation: The radians and cos part of the equation makes our end circular points. The *0.0205 is discretionary i had to adjust these slightly after the final build to fit the design of my workbook but the logic remains the same as above. Check out the below print screen that highlights the radius concept.

3a. Max Points

{FIXED: MAX([T])}

Explanation: This is the number of points we create between the start (room locations) and the end (outer circle point) to make curved lines. In our dataset we have 100 T values, so this calculation will be 100.

3b. X Gap

{ FIXED [Id1]: AVG(([2a. End X]-[Start X])/([3a. Max Points]-1))}

Explanation: All of our start points (room locations) will have a different distance between it and the edge of the circle. Therefore we want to find the distance for each Id between them. We want this value split evenly for each of the 100 points we will create between them. This will help for the chord that sits between the start and end point.

3c. Y Gap

{ FIXED [Id1]: AVG(([2b. End Y]-[Start Y])/([3a. Max Points]-1))}

Explanation: Same as above but for Y. Again, this helps plot the spacing for each of the 100 points of our chord between the start (room locations) and the outer edge of the circle.

To slightly digress, The workbook next contains. 4a. Densification X and 4b. Densification Y

These calculations theoretically aren’t needed but are good to check if you have managed to get the points to work. If you plot these points you will see how data densification works along a straight line. You could now imagine how a circle would wrap around these outer points? Realistically we want these points to have a curve between them. That’s why we use the following two calculations instead.

5a. Sigmoid Calc 1

([T]-1)*(12/([3a. Max Points]-1))-6

5b. Sigmoid Calc 2

1/(1 + EXP(-[5a. Sigmoid Calc 1]))

Explanation: Part of the sigmoid curve theory, please re-visit Ken’s tutorial if this doesn’t make complete sense.

6a. Curve X

IF [T] = 1 then
[Start X]

ELSEIF
[T] > 1 and [T] < 100
then
(
[Start X] + ([2a. End X] – [Start X]) * [5b. Sigmoid Calc 2]
)

ELSEIF [T] = 100
then [2a. End X]
END

Explanation: This calculation will plot the start point for where T = 1, the Chord for where it is between 2 and 99 and then the end point where T = 100.  How the curve works is that it takes the start position, the difference of each X co-ordinate multiplied by our curved adjustment!

6b. Curve Y

IF [T] = 1 then
[Start Y]

ELSEIF
[T] > 1 and [T] < 100
then
(

[Start Y] + ([T]-1) * ([2b. End Y] – [Start Y]) / ([3a. Max Points]-1)
)

ELSEIF [T] = 100
then [2b. End Y]
END

Explanation: Create a similar calculation for Y! This calculation will plot the start point for where T = 1, the Chord for where it is between 2 and 99 and then the end point where T = 100. 

Separator

IF [T] = 1 then
“Start Point”

ELSEIF [T] > 1 and T < 100 then “Chord”

ELSEIF T = 100 then “End Point”

END

Explanation: Finally, create a separator to be able to show your start, chord and end points separately.

The Build Phase. 

Change 6a. Curve X to a geographic role of Longitude.

Change 6b. Curve Y to a geographic role of Latitude.

Drag 6a. Curve X to Columns. Make sure it is a continuous dimension.

Drag 6b. Curve Y to Rows. Make sure it is a continuous dimension.

Drag ID to detail. Change the marks type to a Line.

Drag T onto Path.

Drag Available Category to colour

Drag Separator onto detail.

Finally i created a size calculation to resize the start and end points rather than create a dual axis for the chord and start/ends.

This really is the end point of the build – Hopefully you managed to follow along. It definitely was a challenging one. You might be wondering… wow this doesn’t look like a circle. It is a little underwhelming right?

The rest of the dashboard is a matter of cosmetics and housekeeping that really draw the piece together. I’ll briefly explain my thought process below for the layering and creating a circle to encapsulate each of the end category points. It would probably be most useful to download the workbook and have a look through the various layers.

Tips:

  1. This is the same map, one has all the map layers turned off and has washout set to 100%. The other is what it would look with as a normal map. This was super useful for layering. You can find this control panel in MAP – Map Layers. Remember to right click and remove the background in the formatting area too.

2. I’d recommend making the map with the layers showing and get it on the dashboard how you want it. Turn off the map options in MAP – Map Options, this will stop the pan & zoom controls. Also make sure this is set at the dashboard level. I was reminded about this by Fred and Adrian, so thanks to them!

3. Get your design hat on – It was a lot of back and forth with Photoshop to create the layers the way i wanted them. I’m not too much of a whiz at Adobe, but managed my way to making these. I’m sure something similar might be possible in Figma, or Powerpoint. What i found quite useful was laying out the final map on the dashboard, exporting the image and then creating a circle for the dashboard from that. That way i could ensure my map points lined up.

The workbook is made up of three sheets and two layers of design still images. The order of these are important. First I have my background image and background map (filled), then the text layer with a transparent background (not white!). Following this I overlay my final map, that has the lines coloured but the background mapping washed out. This is because i want the tooltips to be able to be hovered over.

Finishing Touches and Comments:

I ended up playing round with a buffer, as my initial dataset was within a 0.3 Mile radius of the

In retrospect, If design isn’t your strong point and you want another method of creating a circle around your end points, you could theoretically use a buffer!

Buffer (New for radius)

IF [T] = 1

then
(
BUFFER(MAKEPOINT( [1b. AVG Centre Y], [1a. AVG Centre X]),1.42,”Miles”)
)
ELSE null
END

Explanation: You will want to play around with the number here to get it to the correct radius, but it is drawing a radius perfectly around the centre points used earlier. Create this in a separate sheet.

This is what the visualisation looks like using a buffer as a boundary:

Finally a few shout outs. Firstly to Judit Bekker, Judit helped me understand the different map layer background and washout techniques. I messaged her at a point where i was going to give up and admit defeat on the idea, so I’m very pleased she pulled through! Judit recently shared with the community a design tip that will be useful in terms of layering which can be found here, for a video walk-through. Similarly shout out to JR Copreros, I am in love with his VOTD “City and Colour: Income Inequality in Toronto” I’d love to emulate more of this style moving forward. It was a huge inspiration for the dashboard design.

Update 18/02/2021: (@nathanadams_viz) Nathan messaged me after reading my tutorial and noticed that to get the same effect of my viz you didn’t need as many layers as i put in it. He made the equivilant of the above by making a circle fully transparent and then the block colour 50% transparent, allowing for the map to show through ever so slightly. Because the map has washout features too it means that you actually only need two layers instead of the three or four within my visualisation. Thanks Nathan for the tip!

Bit more of a challenging visualisation! Let me know if you have any questions, and feel free to reach out to me on Linkedin or Twitter.

Logging off.

CJ

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

WordPress.com.

Up ↑