Note: This is an incremental post to the circular andhive plot network graphing post. When looking back at my network graphing post recently I remembered one piece of the Hive Plot that I wanted to crack and didn't get to in that original effort. One design element that helps distinguish the Hive Plot is the concept of splitting an interconnected axis into two to help visualize this aspect of a network. I think this helps to view the interconnectivity of an axis within the network you are visualizing. Also, with tools like Tableau, we could even allow for an expand/collapse feature on this axis.
This post will walk you through the updates I made as well as where I just leveraged the original work.
What's the same?
As with most of my work implementing curves in Tableau I am leveraging the same underlying data layout, which I describe in my previous post, noted above.
Densification & Table Calculations
If it is not broken and there isn't a new Tableau feature to leverage, don't fix it. I carried forward the same data densification coupled with window table calculations technique, which I have used for numerous projects in the past. I will repeat the known scaling limitation that this technique has in Tableau with respect to the size of your data and the number of marks you end up plotting in the viz.
I once again leveraged Bézier curves to draw the edges in the Hive Plot. While my calculations have changed, the underlying equations to draw these curves remain unchanged and can be found littered across my Tableau public page.
For the example herein, I leveraged the Zen Master Twitter network data, which came from this post on the Tableau blog. When prepping for this Tableau Fringe Festival presentation I wanted to see how some of these network graphs compared to an existing ‘hairball’ type of layout. I started from the Hive Plot shown in this presentation and then worked to split the Zen Master axis to better visualize the interconnectivity of the Zens in the data. Here is a quick overview of how the network is laid out. The Zen axis is split into two with edges between Zens reflected in between the split axis.
In order to make node placement easier and more dynamic I based the layout in polar coordinates. Here is a good reference from wiki about how polar coordinates work. At a high level we leverage a radius (red dot at the end of the blue/green solid lines) to plot distance from the reference point (aka origin, aka 0,0) and polar angle (blue/green dashed lines) to plot the degrees from the polar axis (black line). Here is an illustration that can be found on the wiki page referenced above.
Once I had these polar coordinate fields defined I just needed to translate my radius and angle into cartesian coordinates which is done in Tableau with these two calculations.
- PolarX = [PolarR]*COS(RADIANS(MIN([PolarAngle])))
- PolarY = [PolarR]*SIN(RADIANS(MIN([PolarAngle])))
Big whoop, what does this really give us? Well… we can now do a couple things. (1) We can specify the distance from the origin dynamically based on the number of nodes on an axis and (2) we can assign degrees to my axes (and even do this automatically if need be) to place my nodes on the correct axis for the Hive Plot, believe it or not this greatly helps simplify how to plot my nodes within Tableau. Here is how the nodes are plotted directly in Tableau.
As an example, the polar coordinates for @datablick are radius = 19 and polar angle = 245 degrees. I do a little math to space out the Zens equidistant on their axis. With that considered, we have X and Y derived using the above set of equations to obtain the x, y of -417, -723 respectively for the @datablick node.
Thanks to the use of polar coordinates, the control points which are so critical to Bézier curves are easier to calculate directly in Tableau. Here is how I am doing this for the Hive Plot in pseudo code. For specifics on how to do this technically, I have embedded the Tableau workbook for you to work through at the end of this post.
- Control Point X: Start Node Radius + Mid point between start and end node radius
- Control Point Y: Start Node Angle + Mid point between start and end node angle
Then I used the same formula noted above to translate from polar to cartesian coordinates. Here is how the control points are plotted directly in Tableau.
View Manipulation Parameters
I really only added these to show how much we can manipulate the viz with this updated implementation. I have two main parameters I am showing in this example (1) extension of the size of a user-selected axis and (2) 360-degree rotation of the entire hive plot.
I have added logic into PolarR and PolarAngle calculations along the way to enable the view manipulations that these parameters drive. Also with the rotation parameter I had to modify the DeltaAngle calculation to adjust for when we cross the 360/0 degree threshold of the circle.
Nested Table Calcs
I needed two sets of table calculations and I needed them to work together. This caused some complexity in the overall implementation that I am sharing in this post, but at the same time made it possible to achieve. If you look into the Bézier curve calculations in the workbook you will see a number of table calculations within these fields. Ultimately I boil this down to two sets of calculations:
- The calculations which rank the nodes on their axes. This is partitioned by the class of the node (either Tableau, Zen or NonZen) and the node itself and sorted by the total number of tweets for the node. This is ultimately used to drive my x,y coordinates for the placement of each node in the hive and thus the end points for my curves.
- The supporting window calculations to draw the curves with the densification technique. These are the same calculations I have shared before with the additional calculations above nested within them. This nesting brings with it the additional fields for partitioning which all have to be on the detail shelf for the viz to work. This is the additional layer of complexity I refer to above.
Ultimately I had to do a lot of mouse clicking to make sure all of the nested table calculations where partitioned, restarting, calculating on and sorting on the correct fields. Yes, you could of course do more of this work prior to Tableau to simplify the actual Tableau workbook (this would also speed up the view as sorted, nested table calculations take longer to render), however that would produce a more static visual at the end of the day which is not what I was going for here (sacrificing speed for dynamic view in this specific implementation).
When comparing this viz to the original, this viz will adapt much more easily to different data sets. It is more dynamic in it's curve equations and it's node placement, which should make it more beneficial to the wider community. It also has the split interconnected axis built in, thus more in line with the guidance provided on hiveplot.com. If I have time and find the right data down the road, I plan to add more examples into the embedded workbook below, until then, enjoy the Tableau Hive Plot, Part Deux...