Rose Curves in Tableau

Always good to start with a bit of inspiration...

I love when people get creative and come up with visuals like these, if you want to see more, check out Shirley Wu’s project with Nadieh Bremer at datasketch.es for starters. Techniques like these (or using things like the rose curve) to encode data will definitely require a more engaged user base. Readers will need to take some time to understand what each rose petal/shape is and then it will take them time to compare the petals across the visual. This type of technique is probably not the best choice to visualize your data when granular differences between your marks need to be analyzed by your reader.


How to build it

Data Prep/Densification

The data prep for this follows the same process which I have shown on a number of densification implementations. You will need a “path” approach for each data element which you are looking to map to the rose curve calculations. I am again using data densification to calculate the curves’ marks running from 0 to 2Pi (see step 3 below).

Calculation Details

Refer to the wiki page for additional details and equations which I am leveraging to build rose curves in Tableau.

We will pick up the calculation work assuming that you have already implemented the data densification technique. This leaves you with a path/bin combination of fields in Tableau (if you are following along in the embedded workbook you have “Path Density (bin)” created at this point.

Step 1: Don’t forget to densify PI() (thank you Noah Salvaterra!). Recently at #tc16, Jonathan Drummey showed me a more processing efficient way to go about “copying” data across your densified bin. Here is that method applied to PI().

Step 2: Create your index along your binned field.

Step 3: Theta (incrementing from 0 to 2*PI()). There are a few pieces to this one. In the example workbook we are going through, I am presenting the user with the “Point Density” parameter. Changing this will modify two things: (1) the upper bound of the binned field used for densification, and (2) the denominator of the Theta Increment.

To get to Theta, we need Theta Increment which is the following calculation. This basically takes the range of 0 to 2PI() and creates an increment value based on the density of the bin selected by the user.

Now that we have our increment value, we can use the PREVIOUS_VALUE() formula to leverage that increment across our densified data, like so.

Step 4: With our Theta running along our bin from 0 to 2PI(), we can take a look at plotting our X/Y coordinates for our rose curve. Here is what we need:

  • X: [Amplitude]*COS([K]*[Theta])*COS([Theta])
  • Y: [Amplitude]*COS([K]*[Theta])*SIN([Theta])

Where “Amplitude” is a parameter (or calculation, see below section) to increase/decrease the distance of the rose curve from the origin, and “K” is an integer resulting in either K (odd number) or 2*K (even number) “petals” in the rose curve.

We are now presented with a dynamic rose curve calculated directly within Tableau…


How to map data to it

Ok, pretty cool, we have a math flower in Tableau, and I could even make it pink to get my two young daughters interested in it (they LOVE anything pink), so what…

This all actually started with the below visualization I put on Tableau Public and me reaching out to Adam McCann for some impromptu feedback.

Adam had a couple different thoughts (which are always worth listening to), one of which referred me to the OECD Life Index site mentioned above. Putting these pieces together, I set forth to create rose curves and then map the NFL yardage data to it, flowers and football, an obvious combination, and a fun challenge for me.

Using the above calculated fields as a starting point, I need to account for a few things:

  • I wanted a “flower” for every NFL team
  • I wanted to have four petals, one of reach position combination of yards gained,
  • I wanted to size the petals against the maximum value in the dataset, and
  • I wanted to rotate the “flower” 45 degrees.

Creating a “flower” for every team was easy, just add more data and use columns/rows/details shelf as needed, I already had most of this layout done from my initial radial bar version (shown above), thus I just leveraged that existing sheet structure.

To have four petals I just needed to set K to the value of 2, however, assigning each petal to separate position combination meant I had to find a way to “split” 4 pieces of the same polygon. I took the easy route on this one, identifying the values of Index for each of the four petals and then creating an if statement to utilize the correct field depending on the petal. This also required me to create four densified LOD functions, one for each grouping. There is most likely a better way to do this, happy to hear it if you have one in mind, but here is the simple if statement.

Sizing the petals needs to be done by area (to prevent skewing results), thus I would need to back into the “Amplitude” value from my first example using an area function. For K=2 of the rose curve (aka a Quadrilfolium), I can size based on the area of the corresponding circumcircle that the rose curve sits within. This may not work for all K values of the rose curve though so be sure to take caution when sizing petals of your own rose.

Note: I added a “Scale By” parameter in the workbook to show how drastic of a difference this makes to the visualization, this is available if you download the workbook.

Lastly I used a rotation matrix to rotate the petals to be on 45°, 135°, 225° and 315° (instead of 0°, 90°, 180°, 270°).

  • Rotated X: [X]*(COS([Pi()]*.25))-[Y]*(SIN([Pi()]*.25))
  • Rotated Y: [X]*(SIN([Pi()]*.25))+[Y]*(COS([Pi()]*.25))

This additional view, provides a visual “summary” of the denser, detailed radial bar distribution I started with. To me, it ended up looking a little more like insects instead of flowers. But it does make it possible to see teams 'weighting' towards one position or another (like KC and how TE heavy they are). What do you think?