Categories
How-To's Tableau Techniques Totally Useless Charts

Totally Useless Charts & How to Build Them – Lotus Flowers

Welcome to our new series, Totally Useless Charts & How to Build Them. In each installment of this series we’ll look at one very custom chart, something with almost no real use cases, and we’ll walk through, step by step, how to build it. The purpose of this series isn’t necessarily to teach you how to build these specific useless charts, it’s more about talking through the techniques, the approach, and the thought process behind each chart. Our hope is that seeing how we went about building these will help you with your own custom charts. But if you do somehow find a great use case for one of these charts, by all means, please download the workbook and use it as your own.

In this first installment we’re going to learn how to build Lotus Flowers in Tableau. It’s not a requirement, but it may be a good idea to review Part 1 and Part 2 of the Fun With Curves Series before proceeding. To follow along, you can download the workbook here, and the data here.

Lotus Flower

First, let’s take a look at what we’re trying to build. Below is a lotus flower with 10 petals, which means we have a total of 11 polygons; 1 circle and 10 petals. The circle is fairly easy to build using the techniques in Part 1 mentioned above. The petals are a little more complicated. But first thing’s first…we need some data.

Building Your Data Source

Let’s start with our data. For this example we’re going to build 12 lotus flowers and we’re going to use the value from our data source to size the flowers appropriately. We’ll start with the tab titled ‘Source Data’.

Next, we’re going to do some densification to get the number of polygons needed for each of the flowers. Below I have 1 record for the Circle and 24 records for the petals. We’re going to build this in a way that will let you choose how many petals you want to display (up to 24). This data can be found in the ‘Polygons’ tab in the sample data.

Now we’re going to join these two sources together using a join calculation (value of 1 on each side). The result will be 25 records for each of our 12 ‘Base’ records.

Next, we need to do a little more densification, but this time it’s a little trickier. For our circle, we want at least 50 points for a relatively smooth curve. For our petals, we actually need to draw 2 lines for each petal, one for the left side of the petal (Min) and one for the right side of the petal (Max), and then join those together. Pretty confusing right? We’ll talk about this in a lot more detail. This table is a little too large to include a screenshot, but take a look at the ‘Densification’ tab in the sample data.

For our circles, we have 50 records. We have two numerical fields, [Points] and [Order], that both run from 1 to 50 and a [Type] field to identify that these points are for our circles. For our petals, we have 100 records. We still have the same two numerical fields, but the values are a little different. We have an [Order] field that runs from 1 to 100, and a [Points] field that runs from 1 to 50 and then back down from 50 to 1. We also have a [Side] field with values of Min or Max. The Min records will be used to draw the left side of our petals. The Max records will be used to draw the right side of our petals. And then we have a [Type] field to identify that these records are for our petals. Now we just need to join this table to our data source on the [Type] Field.

Building Your Circles

If you have read through Part 1 of the Fun With Curves series, then you may remember that in order to draw a circle in Tableau, we only need 2 inputs; the distance of each point from the center of the circle (the radius), and the position of each point around the circles (represented as a percentage).

Let’s start with the first input, the radius. We are going to size our circles based on the Value field in the Source Data. We want the area of our circles to represent the value in the data. So we have the area of each circle, we just need to use those values to calculate the radius of each circle. We can do this with the simple calculation below.

Radius = SQRT([Value]/PI())

Next, we need to calculate the position of each point around the circle. I’m not going to go into too much detail on this, but you can read more about it in the post mentioned above. To calculate this, we need the maximum number of points for our Circles (50), and we need the [Points] field (values 1 thru 50). For the max point calculation I am going to use an LOD because the max number of points for our circles, may not always align with the max number of points in our data source (but in this case it does).

Max_Point = {FIXED [PolygonType] : MAX([Points])}

Circle_Position = ([Points]-1)/([Max_Point]-1)

Next, we just need to plug the [Radius] and the [Circle_Position] values into our X and Y formulas for plotting points around a circle.

Circle_X = [Radius]* SIN(2*PI() * [Circle_Position])

Circle_Y = [Radius]* COS(2*PI() * [Circle_Position])

Now, let’s draw our circles

  • Right click on [Circle_X] and drag it to columns. When prompted, choose [Circle_X] without any aggregation
  • Right click on [Circle_Y] and drag it to rows. When prompted, choose [Circle_Y] without any aggregation
  • Right click on [Base_ID], change it to a Dimension, and drag it to Detail
  • Right click on [Order], change it to a Dimension, and drag it to Path
  • Drag [Type] to Filter Shelf and filter to ‘Circle’
  • Change the Mark Type to Polygon

Now you should have something that looks like this.

Although it looks like one big circle, we actually have all 12 circles in this view. They’re just stacked on top of each other. So next we need to space these out a little bit. There are a lot of different techniques to do this, but here’s one I like to use to create Trellis Charts. This technique works great when you have a sequential ID field, which we do (Base_ID).

First, we’re going to create a numeric parameter that will allow us to choose the number of columns we want to create. We’ll call the parameter [Column Count] and set the value to 3. Next, we’re goin to use the [Base_ID] field to break our circles into columns and rows, starting with row.

Row = CEILING([Base ID]/[Column Count])

Column = [Base ID]-(([Row]-1)*[Column Count])

Now right click on both of these fields, change them to Dimensions, and then drag them to the appropriate shelf (Row to Rows, Column to Columns). The result should look something like this.

Building Your Petals

Alright, so this part is a little more complicated. I’m going to start by reviewing the basics of how you build these shapes, but I’m going to skim over the calculations since those will change significantly once we try to build these petals around our circle. No need to follow along with the workbook during this section.

So here are the basics. Let’s start by drawing a Bezier Curve with 4 control points. Our line is going to start at 0,0 and end at 5,10. Wow, this is easy, we already have the coordinates for 2 of the points!

Let’s take a look at our inputs. Our line will have a height of 10 and a width of 5. I’ve also built 2 parameters that we’ll use to calculate the 2nd and 3rd set of points. You can experiment with different values here, but these seem to work pretty well. We need a total of 8 values (4 sets of X and Y).

  • Point 1 will be the start of the line. In this case, it’s 0,0
  • Point 2 will appear on the same X axis as Point 1, but will be somewhere between the start and end of the line on the Y axis. I like to place it two thirds of the way, or .67 (the value in the P2 Parameter Input above). So the coordinates for Point 2 will be 0 and 6.7 (P2 Parameter x Height of the line)
  • Point 3 will appear on the same X axis as Point 4, and will appear somewhere between the start and end of the line on the Y axis (similar to P2). I like to place it halfway, or .5 (the value in the P3 Parameter Input above). So the coordinates for Point 3 will be 5 and 5 (P3 Parameter x Height of the line).
  • Point 4 will be the end of the line. In this case, it’s 5,10

If you were to plot these 4 points, you would have a jagged line like you see in the image above. But look what happens when we plug those values into our Bezier calculations

X = (1-[T])^3*[P1_X] + 3*(1-[T])^2*[T]*[P2_X] + 3*(1-[T])*[T]^2*[P3_X] + [T]^3*[P4_X]

Y = (1-[T])^3*[P1_Y] + 3*(1-[T])^2*[T]*[P2_Y] + 3*(1-[T])*[T]^2*[P3_Y] + [T]^3*[P4_Y]

Alright, we are halfway there! Kind of. So now we have a line that will create 1/2 of one of our petals. But in order to turn this into a petal shaped polygon, we need another line that’s a mirror image of this one.

This is where the Min and Max records come in. We need to calculate our 4 sets of coordinates for both sides. Luckily, most of the values are actually the same. P3 and P4 are going to be identical for both lines. And the Y values for P1 and P2 are the same. The only differences are the X values for P1 and P2. And to calculate those we just add the width of the whole petal (width x2) to our starting point. And if we were to plug these coordinates into the same calculations, we have this.

Now this is where the [Order] field comes into play. To make this one single polygon instead of two separate lines, we can use the [Order] field on Path and change the Mark Type to polygon

On the Left (Min) side, we have points 1 thru 50, running from the bottom left up to the top middle. On the right (Max) side, we have points 1 thru 50 running from the bottom right up to the top middle. But then we have the [Order] field (on label in the image above). This field runs from the bottom left to the top middle to the bottom right, in one continuous flow, from value 1 to 100. This is what makes it a single continuous polygon.

Ok, so that’s how we would build 1 single petal shaped polygon, perfectly positioned facing directly upward. But that’s not what we’re trying to do. We’re trying to build a dynamic number of petals, evenly spread around a circle and facing outward in the appropriate directions. So let’s do that.

Building Your Petals (for real this time)

We’re going to use a similar approach to what was described above, but everything needs to be plotted around a circle. So any calculations we use to determine our 4 points are going to have to run through those X and Y calculations for plotting points around a circle. That means, for all of our points, P1 thru P4 for both sides, we need to calculate two things; the distance from the center of the circle, and the position around the circle. But before we calculate those specific points there are a few other calculations that we’ll need. We also need a parameter, called [Petal Count] that will allow us to select how many petals we want. This should be a numeric parameter, and let’s set the value to 10 (I recommend using a range, allowing values from 4 to 24)

T = ([Points]-1)/([Max_Point]-1) – this is the same as the [Position] calc used earlier. It’s used to evenly space points between 0% and 100%

Petal_Count_Filter = [Polygon ID]<=[Petal Count] – this will be used as a filter to limit the number of petals displayed to what is selected in the [Petal Count ] parameter

Petal_Width = 1/[Petal Count] – this calculates the total position around the circle that will be occupied by each petal. For example, if there were 10 petals, each one would occupy 1/10 of the space around the circle, or .10

Petal_Side_Position = IF [Side]=’MIN’ THEN ([Polygon ID]-1)*[Petal_Width] ELSE [Polygon ID]*[Petal_Width]
END
– this calculates the position of the start of each Min line and Max line. If there were 10 petals, the Min side of the 2nd petal would be at position .1 or (2-1)*.1, and the Max side of the petal would be at position .2, or 2*.1. The Min value will share the same position as the Max value of the previous petal. The max value will share the same position as the Min value of the next petal

Petal_Middle_Position = ([Polygon ID]/[Petal Count]) – ([Petal_Width]/2) – this calculates the position of the center of each petal. If there were 10 petals, the center of petal 3 would be at .25, or (3/10) – (.1/2). This is also halfway between the position of the Min line and the Max line.

Alright, now we can calculate all of our coordinates. Let’s start with P1. For the first input, we want this point to start right at the edge of our circle. So the distance from the center is going to be equal to the radius of the inner circle. So the first input is just [Radius]. For the second input, we’ll use the the [Petal_Side_Position] we calculated above.

P1_X = [Radius]* SIN(2*PI() * [Petal_Side_Position])

P1_Y = [Radius]* COS(2*PI() * [Petal_Side_Position])

If we were to plot these points for 12 petals, we would end up with 24 points, but it would appear that we only 12 because each is overlapping with another point. But this gives us the outside edges of each of our petals

Now onto P2. This one is a little more complicated. We’re going to use P1 as a starting point for this calculation, instead of the center of the inner circle. Now we need to calculate the distance from P1 where we want our next point to appear. First, we need to determine the length of the entire petal. I like to use a parameter for this so I can dynamically adjust the look of the flowers. So let’s create a parameter called [Petal_Length_Ratio]. This is going to be a number relative to the radius, so a ratio of 1 would set the length of the petal equal to the radius of the circle. A value of .8 would set the length of the petal equal to 80% of the radius, and so on. I usually go with a value somewhere between .5 and 1. We’ll use this along with the radius, so that the petals of each flower are sized appropriately based on the size of their inner circle. Next, we need to position this point somewhere between the start of the line and the end of the line. As I mentioned earlier, I like to place it two thirds of the way (P2_Parameter from the previous section). So the first input, the distance from P1, is going to be the radius x the length ratio x the P2 parameter. For the second input, we’re going to use the [Petal_Middle_Position] because we want this side of the line to follow the same path as the line with P3 and P4. If we were to use the [Petal_Side_Position] field, we would end up with really wide, strange looking petals. This will probably make more sense a little further along. For now, let’s plug those values into our X and Y calcs.

P2_X = [P1_X] + (([Radius] * [Petal_Length_Ratio] * [P2_Parameter]))* SIN(2*PI() * [Petal_Middle_Position])

P2_Y = [P1_Y] + (([Radius] * [Petal_Length_Ratio] * [P2_Parameter]))* COS(2*PI() * [Petal_Middle_Position])

P3 is a little more straight forward. For the first input, we’re going to calculate the distance from the center of the inner circle. And then we’ll use a similar approach to what we did for P2. The first input will be the radius + (the radius x the length ratio x the P3 parameter). As I mentioned in the earlier section, I like to set this parameter to .5. And once again, we’re going to use the [Petal_Middle_Position] field for the second input.

P3_X = ([Radius]+([Radius] *[Petal_Length_Ratio] * [P3_Parameter]))* SIN(2*PI() * [Petal_Middle_Position])

P3_Y = ([Radius]+([Radius] *[Petal_Length_Ratio] * [P3_Parameter]))* COS(2*PI() * [Petal_Middle_Position])

P4 is almost identical to P3, except we don’t need the length ratio. We want this point to appear at the end of the line. So we can just remove that from the calc.

P4_X = ([Radius]+([Radius] * [Petal_Length_Ratio])) SIN(2*PI() * [Petal_Middle_Position])

P4_Y = ([Radius]+([Radius] * [Petal_Length_Ratio])) COS(2*PI() * [Petal_Middle_Position])

We’re almost there! If we were to plot these points for the first petal in our lotus flower, it would look like this. It looks very similar to what we reviewed in the previous section, but with one very important difference…everything is at an angle…which is what we wanted.

All that’s left to do is to plug all of these points in our Bezier calcs and then build our polygons!

Petal_X = (1-[T])^3*[P1_X] + 3*(1-[T])^2*[T]*[P2_X] + 3*(1-[T])*[T]^2*[P3_X] + [T]^3*[P4_X]

Petal_Y = (1-[T])^3*[P1_Y] + 3*(1-[T])^2*[T]*[P2_Y] + 3*(1-[T])*[T]^2*[P3_Y] + [T]^3*[P4_Y]

Now the polygons. Let’s build this as a Trellis chart, just like we did with the Circles. So drag [Row] on to Rows and [Column] onto Columns. And then;

  • Right click on [Petal_X] and drag to Columns. When prompted, select [Petal_X] without aggregation
  • Right click on [Petal_Y] and drag to Rows. When prompted, select [Petal_Y] without aggregation
  • Drag [Type] to Filter Shelf and filter to ‘Petal’
  • Drag [Petal_Count_Filter] to Filter Shelf and filter to TRUE. Right click and ‘Add to Context’
  • Drag [Polygon_ID] to Detail
  • Drag [Order] to Path
  • Change Mark Type to Polygon

We’re so close! Your sheet should look like this

The only thing left to do is to combine the Circle polygons with the Petal Polygons. We have separate data for them, all we need to do is get them on the same sheet. So we’ll create two more simple calcs to bring it all together.

Final_X = IF [Type]=’Circle’ THEN [Circle_X] ELSE [Petal_X] END

Final_Y = IF [Type]=’Circle’ THEN [Circle_Y] ELSE [Petal_Y] END

Now just replace [Petal_X] and [Petal_Y] with [Final_X] and [Final_Y] and drag [Type] from the filter shelf on to Color and you should have your lotus flowers!

The Final Touches

The hard part is done, now to make it look pretty. Play around with some of the parameters until you get the look that you like. Adjust the [Petal Count], the [Column_Count], the [Petal_Length_Ratio], and even the [P2_Parameter] and [P3_Parameter] if you wanna get crazy.

Next, throw some color on there. You could make the color meaningful to encode some data, or you could do what I just did and color it randomly. I used the calc below and then just assigned one of the color palettes I have saved.

Color = [Type] + STR([Base ID])

And that’s it! If you made it this far, please reach out and let me know what you thought, and what you came up with. Thank you so much for reading, and keep an eye on the blog for more ‘Totally Useless Charts & How to Build Them’

Categories
How-To's

Fun With Curves in Tableau Part 2: Bezier Curves

This is part two of a three-part series on creating curved elements in Tableau. Although this post covers new and different techniques, I would recommend checking out part one of the series here as some of the concepts overlap. This post will focus on one type of curved line that is used frequently in Tableau Public visualizations; Bezier Curves. To follow along, you can download the sample data and workbook here.

Bezier Curves

There are many types of Bezier curves varying in complexity from very simple to ridiculously complicated. One commonality with these types of curves is that they rely on ‘control points’. This post is going to focus on quadratic Bezier curves, which have 3 control points. An easy way to think about these points is that there is a starting point, a mid point, and an end point, creating a triangle. The starting point and end point are simply the start and end of the line. The other point, the mid point, will determine the shape of the triangle, and in turn, what that curve is going to look like. Now let’s see how the position of that mid point (creating different types of triangles) will affect the curve.

Each of the triangles above have the same starting point (1,0) and the same end point (10,0), but have significantly different curves because of the varying mid point. For most applications in Tableau we’re going to be dealing with examples like Example 1 and Example 4 in the image above, where the mid point is halfway between the other points, creating an isosceles triangle. To make things even easier for this example, we’re going to deal with just Example 1, which is an equilateral triangle, meaning all 3 sides are the same length.

Building Your Data Source

To build our data source we are going to follow the same process that we did in Part 1 of this series. We are going to create additional points by joining our sample data to a densification table using join calculations (value of 1 on each side of the join). In this case, our sample data is called Bezier_SampleData and our densification data is called BezierModel. You can download the sample data here. In our sample data we have 10 records that we’ll use to draw 10 unique curves. For simplicity sake, all of these curves will start and end at 0 on the Y axis.

Building Your Calculations

To draw our curves there are a few things we’ll need to calculate. Our sample data has 2 of the 3 points we need (starting point and end point), so we’ll need to calculate the X and Y values for the 3rd point (mid point). Let’s start there.

We discussed above that we are going to use equilateral triangles to draw our curves. In that case, the X value for the mid-point will be halfway between [X_Start] and [X_End] and the Y value will be the height of the triangle plus the starting point. Here is an example

To find the X value that falls in the middle of [X_Start] and [X_End], just add them together and divide by 2

X_Mid

([X_Start]+[X_End)/2

To find the Y Value add the Y starting point to the height of the triangle. To find the height of the triangle, use the formula (h=a*3/2) where a is the length of one of the sides of your equilateral triangle. To find that length subtract [X_Start] from [X_End]

Y_Mid

[Y_Start] + (([X End]-[X Start])*SQRT(3)/2)

Now, we have 3 points for each record in our data set. We have our starting point ([X_Start],[Y_Start]), our end point ([X_End],[Y_End]), and our mid point ([X_Mid],[Y_Mid]). If we were to stop here and plot those points, it would look something like this, 10 equilateral triangles of different sizes, all on the Y axis (because we had used 0 for all of the [Y_Start] and [Y_End] values)

Now let’s convert those points into Bezier curves. The first calculation we’ll need is [T]. T is going to be a percentage value that is equally spaced between 0 and 1 for the number of points in our densification table. Think of this as similar to the [Position] calc in Part 1 of this series, but slightly different because we need our first point to start at 0.

T

([Points]-1)/{MAX([Points])-1}

No matter how many points you add to your densification table, this calculation will spread them evenly between 0 and 1. This field is used to evenly space our points along our curved line. When complete, your T values should look like this. The value for point 1 should be 0%, the value for the last point should 100% and all of the points in the middle should be equally spaced between those

Now all that is left is to calculate the X and Y coordinates for each point along our curved lines. The calculations for X and Y are exactly the same, but in the [Bezier_X] calc you are using the 3 X values, and in the [Bezier_Y] calc you are using the 3 Y values

Bezier_X

((1-[T])^2*[X_Start] + 2*(1-[T])*[T]*[X_Mid]+[T]^2*[X_End])

Bezier_Y

((1-[T])^2*[Y_Start] + 2*(1-[T])*[T]*[Y_Mid]+[T]^2*[Y_End])

Now let’s build the curves in Tableau

Build Your Curves

Follow the steps below to build your curves

  • Right click on the [Bezier_X] field, drag it to columns, and when prompted, choose the top option ‘Bezier_X’ without aggregation
  • Right click on the [Bezier_Y] field, drag it to rows, and when prompted, choose the top option ‘Bezier_Y’ without aggregation
  • Change the Mark Type to ‘Line’
  • Right click on the [Points] field, drag it to Path, and when prompted, choose the top option ‘Points’ without aggregation
    • This tells Tableau what order to ‘connect the dots’ in.
  • Drag [Line Name] to color

When you finish, your worksheet should look something like this

Or you can change the Mark Type to ‘Polygon’ and reduce the Opacity and it will look like this

Now this is a relatively simple example. You can get really creative with how you calculate those 3 points, especially the ‘mid’ point. Let’s do one more example, combining the work we’ve done in this exercise with what we had done in Part 1 of the series. The result should look pretty familiar.

First, let’s take our X values and plot them in a circle, instead of on a straight line. From Part 1 of this series, we know that in order to plot points around a circle, we need 2 inputs for each point; the Radius (the distance from the center of the circle), and the Position (the position around the circle expressed as a percentage). Since we want all of our points to be equally distant from the center, we can use a single value for the radius of all points. Let’s create a parameter called [Radius] and set the value to 10. For Position, we’ll need to calculate the position for each start and end point. For the position calculations we’ll need to first find the maximum number of points around our circle, or in this case, the max value of the [X_Start] and [X_End] fields together. Looking at our data, we can see the maximum value of the [X_Start] field is 12 and the maximum value of the [X_End] field is 15. So our Max Point will be 15

Max_Point

{MAX(MAX([X_Start],[X_End]))}

Next, we’ll use that value to calculate the position around the circle for each start and end point

Position_Start

[X_Start]/[Max_Point]

Position_End

[X_End]/[Max_Point]

Now, we can calculate the X and Y coordinates for the starting point and end point of every line, using the same calculations we used in Part 1 of the series. Let’s begin with the starting points

Circle_X_Start

[Radius]* SIN(2*PI() * [Position_Start])

Circle_Y_Start

[Radius]* COS(2*PI() * [Position_Start])

And now we’ll calculate the X and Y coordinates for the end points using the same formulas but swapping out the [Position_Start] field, with the [Position_End] field.

Circle_X_End

[Radius]* SIN(2*PI() * [Position_End])

Circle_Y_End

[Radius]* COS(2*PI() * [Position_End])

Now for each of our lines, we have two sets of coordinates. We have the coordinates for the start of our line ([Circle_X_Start],[Circle_Y_Start]) and the coordinates for the end of our line ([Circle_X_End],[Circle_Y_End]). All we need now is that 3rd set of coordinates, the mid-point. The good news is, when plotting these around a circle, we have a very convenient mid-point…the middle of the circle. In this case, because our circle is starting at (0,0), we can use those values as our 3rd set of points. Let’s take our 3 sets of coordinates and plug them into the Bezier calculations we used earlier

Circle_Bezier_X

((1-[T])^2*[Circle_X_Start] + 2*(1-[T])*[T]*0+[T]^2*[Circle_X_End])

Circle_Bezier_Y

((1-[T])^2*[Circle_Y_Start] + 2*(1-[T])*[T]*0+[T]^2*[Circle_Y_End])

Now in our view if we replace the [Bezier_X] and [Bezier_Y] fields with the [Circle_Bezier_X] and [Circle_Bezier_Y] fields, we get something like this…the foundation of a chord chart

This chart uses the same exact calculations for the curved lines, we just used some additional logic to calculate the coordinates for the start and end points. In our first example, for Line 2, we drew a curved line between 3 and 15 on the X axis. The coordinates for our start and end point were (3,0) and (15,0) respectively. Then we calculated the coordinates for our mid point, which ended up being (9,10.4)

In this last example, we also drew a curved line between 3 and 15, but instead of those points being on the same Y axis, they were positioned around a circle. We used what we learned in Part 1 of this series to translate those X values (3 and 15) into coordinates around a circle. So the coordinates for our start and end positions ended up being (9.5,3.1) and (0,10) respectively. And instead of calculating our mid-point, we used the center of the circle (0,0).

These are just a few basic examples of what you can do with Bezier curves, but there are so many possibilities. Here are a few examples of where I’ve used Bezier Curves in my Tableau Public Profile.

Thank you so much for reading, and keep an eye out for the third and final part of this Series, focusing on Sigmoid curves.

Categories
How-To's

Fun With Curves in Tableau Part 1: Circles

In recent years there have been multiple scientific studies1 designed to confirm what many of us in the Data Visualization Community have already suspected; when it comes to art, people are drawn to curves. Think about some of your favorite pieces of Data Art. I am willing to bet that the majority of them contain some type of curved element. Not only are curves more aesthetically pleasing than straight lines and sharp corners, but they have that ‘WOW’ factor, because as we all know, curved lines do not exist in Tableau. They take effort, and when it comes to drawing curves, most people don’t know where to start. But you don’t need to be an expert in Tableau to create beautiful radial charts, or to add some impressive curves to your dashboards. You just need to know the math, you need to know how to structure your data, and you need to know how to bring those elements together in Tableau. That’s the goal of this series. To hopefully demystify some of this work and make it more approachable, and to provide some examples. This series will focus on three types of curved elements; Circles, Bezier Curves, and Sigmoid Curves.

Drawing Circles in Tableau

Tableau does have a ‘Circle’ mark type that can be used, but being able to draw your own circles opens up a world of possibilities. The calculations that are used for drawing a circle, are the same calculations that can be used to create any type of radial chart you can imagine. For this post, I am going to keep the math as simple as possible, but if you’re interested in diving deeper I would recommend checking out this post by Ken Flerlage.

Once you have your data structured there are really only 2 inputs needed to create your radial; the distance of each point from the center of the circle (radius), and the position of each point around the circle. We’ll discuss these inputs a lot more in this post, but let’s start with our data structure. To follow along with this post, you can download the sample data and workbook here.

Building Your Data Source

To create any type of curved element in Tableau, you’ll need to start by densifying your data. To create your densification table, create a table in Excel with 1 column, in the first cell name that column ‘Points’, and then add rows with numbers 1 through however many points you wish to create. There are a few things to consider when choosing that number. Choosing a number that is too high may affect performance as that many rows will be added to your data source for each record in your ‘Core’ data set (a data source with 1000 rows will turn into 100,000 if you choose 100 points). Choosing a number that is too low will result in visible straight lines and corners instead of a smooth curve. Here is an example to help visualize how the number of points can affect the shape

I will usually choose somewhere between 50 and 100 points, closer to 50 when the circles will be small, and closer to 100 when the circles will be large. For this post, we’ll go with 50 points, so your densification table should look something like this.

And here is some sample data we’ll use as our ‘Core’ data source. We have 10 records that we’ll use to create 10 distinct circles, and we’ll use the ‘Value’ column to size the circles appropriately. I use this technique frequently, instead of the ‘Circle’ mark type in Tableau, to ensure that the size (area) of each circle accurately represents the underlying value. When designing my ‘Core’ data source, I like to use a sequential ‘ID’ field, starting from 1. This can help make some of the calculations easier, but if it’s not an option, you can typically replace that ‘ID’ field with the INDEX function in Tableau.

Now that we have our ‘Core’ data set, and our densification table, let’s bring these together in Tableau. To densify our data we’ll need to join these two tables in the physical layer in Tableau.

  • First, connect to your ‘Core’ data. In this example, that table is called ‘CircleData’
  • Drag your ‘CircleData’ table onto the Data Source pane
  • Double-click on the ‘CircleData’ Logical Table to view the Physical Tables
  • Drag your ‘Densification’ data onto the Data Source pane. In this example, this table is called ‘CircleDensification’
  • Join the tables with a Join Calculations
    • On the left side of the join, click on the drop-down and select ‘Create Join Calculation’
    • In the calculation box enter the number 1
    • Repeat the steps above on the right side of the join
  • When complete, your data source should look like this

Building Your Calculations

Now that we have our data source, the next step will be to build our calculations. As I mentioned earlier, there are 2 inputs that we’ll need to draw our circles; the distance of each point from the center of the circle, and the position of each point around the circle. Let’s start with the distance calculation.

In this example, we want the area of the circle to represent the value in our data. The distance from the center of a circle to the outside of the circle is known as the radius, and we can calculate that with the formula below. This will serve as our first input.

r = √A/π or in plain English Radius = Square Root of Area/Pi

In our data we have the Area (Value) so we can calculate the radius for each of circles using the calculation below in Tableau. Create a new calculated field called ‘Radius‘ and copy the formula below

Radius

SQRT([Value]/PI())

For the next input, we’ll need to calculate the position of each point around the circle. For each circle, we have 50 points (the number of rows in our densification table) and we’ll want to evenly distribute those points around the circle. The resulting number will be a percentage and will represent how far around the circle that point appears. For example, imagine you were looking at a clock. 3 o’clock would be 25%, 6 o’clock would be 50%, 9 o’clock would be 75% and 12 o’clock would be 100%

We can calculate that percentage for each point by taking the value of the Points field divided by the Max Value of that field (which would represent the number of points or number of rows in our densification table). So the Position calculation would be as follows in Tableau

Position

[Points]/{MAX([Points])}

Note* if you plan on using the ‘Line’ mark type to draw your circles instead of the ‘Polygon’ mark type, you should modify this calculation by subtracting 1 from the divisor, [Points]/{MAX([Points])-1}. This is because polygons will automatically connect your first and last point. For lines, we need to force that connection.

Now your data should look something like this. For each record in your ‘Core’ data set, you have 50 points, with position values equally spread between 0-100%

Now we have our 2 inputs and all that is left to do is to translate these inputs into X and Y coordinates, which can be done with two simple calculations

X

[Radius]* SIN(2*PI() * [Position])

Y

[Radius]* COS(2*PI() * [Position])

Build your Circles

Follow the steps below to build your circles

  • Right click on the [X] field, drag it to columns, and when prompted, choose the top option ‘X’ without aggregation
  • Right click on the [Y] field, drag it to rows, and when prompted, choose the top option ‘Y’ without aggregation
  • Change the Mark Type to ‘Polygon’
  • Right click on the [Points] field, drag it to Path, and when prompted, choose the top option ‘Points’ without aggregation
    • This tells Tableau what order to ‘connect the dots’ in.
  • Drag [Circle Name] to color

When you finish, your worksheet should look something like this

Right away, you’ll probably notice a few things about this. First, these look like ovals, not circles. And second, there are only 2 circles when there should be 10. The reason they look like ovals is because the worksheet is wider than it is tall. It’s important when you place a radial chart on a dashboard that you set the width and height equal and that you Fix both the X and Y axis to the same range. The reason there are only two circles visible is because all 10 circles have the same starting position (0,0), so they are currently stacked on top of each other.

Arrange Your Circles

There are a number of techniques you can use to arrange these circles. You could place the [Circle ID] field on Rows to create a column of circles, or on Columns to create a row of Circles. Or, with a little more math, you could do a combination of these and create a trellis chart, or ‘small multiple’. But personally, I like to use ‘offset values’ which place everything on the same pane and give you total control of the placement of each object.

First, let’s place all of these circles in a single row. To do this, we’ll create a numeric parameter and set the value to 10. This is going to be used to set the spacing between each circle. To increase the spacing, set the parameter higher. To decrease the spacing, set the parameter lower.

Now we’ll create our ‘offset value’.

Circle Offset

[Circle ID]*[Circle Offset Parameter]

And next, we’ll add that value to our [X] calculation

X

[Radius]* SIN(2*PI() * [Position]) + [Circle Offset]

And here is the result

This works because it moves every point in each circle an equal amount. For Circle 1, the [Circle Offset] value will be 10 (Circle ID is 1 x Circle Offset Parameter is 10 = 10). Adding that to the [X] value that was previously calculated will move every point in that circle 10 to the right. For Circle 2, the [Circle Offset] value will be 20 (Circle ID is 2 x Circle Offset Parameter is 10 = 20), which will move every point in that circle 20 to the right.

If we add the [Circle Offset] value to the [Y] calculation instead of [X], the result will be a single column of circles. And if we add the [Circle Offset] field to both the [X] and the [Y] values, the result will be a diagonal line.

So those are some easy ways to plot your circles in a line…but this is a post about circles. So…let’s plot them in a circle. And to do this we’re going to use the same techniques we used to draw the circles.

First, let’s create one more parameter that will serve as the radius of our new circle. We’ll call it ‘Base Circle Radius’ and set the value to 30

That parameter will be one of our two inputs for plotting points around a circle. The second input is going to be the position. Previously, we had 50 points that we wanted to plot evenly around a circle. Now, we have 10 points (10 circles). Previously, we had values 1 thru 50 (the Points field). Now, we have values 1 thru 10 (the Circle ID field). So using the same technique we used earlier, we’ll calculate the position of each circle around our ‘Base’ circle.

Base Circle Position

[Circle ID]/{MAX([Circle ID])}

Now, we have our two inputs and we can use the same calculations to translate those into X and Y values

Base Circle X

[Base Circle Radius]* SIN(2*PI() * [Base Circle Position])

Base Circle Y

[Base Circle Radius]* COS(2*PI() * [Base Circle Position])

Now all you need to do is add these values to your [X] and [Y] calculations respectively, similar to what we did in the previous section

X

[Radius]* SIN(2*PI() * [Position]) + [Base Circle X]

Y

[Radius]* COS(2*PI() * [Position]) + [Base Circle Y]

And here is the result, a circle of circles

Now this is just one simple example of what’s possible once you know how to plot points around a circle. I use these same few calculations, with some modifications, in a ton of my Tableau Public visualizations. Here are a few examples that use this technique.

Thank you so much for reading the first of many posts on Do Mo(o)re With Data and keep an eye out for the second part of this series.

1 Here’s an article about a few studies demonstrating human’s innate affinity for curves. Link