Combining Multiple Hexmaps using Segments

After my #Data16 talk Chad Skelton challenged me to do a simple remake of the Guardian sunburst-type visualisation that I critiqued in my Sealed with a KISS talk (which you can now watch live at this link).

The original visualisation is show below:

2016-11-13_12-55-29.png

While initially engaging, I find this view complex to read and extracting any useful information involves several round trips to the legend. The circular format makes the visualisation appealing while sacrificing simple comprehension. Could I do better though?

Chad suggested small multiple maps and I agreed this might be the simplest approach but I was not happy with the resulting maps:

2016-11-13_18-22-51

 

Alaska and Hawaii why do you ruin my maps? The Data Duo have several solutions and my favourite is the tile map.

Thankfully Zen Master Matt Chambers has made Tile Maps very easy in this post and so I followed the instructions, joining the Excel file he provided onto my data and giving a much more visually appealing and informative result. The resulting visualisation is below (click for an interactive version):

cxjnfitxgae5mkn

However I still wasn’t satisfied with this visualisation, it has several problems:

  • it separates out the variables per state, meaning the viewer till has a lot of work to do to compare each states full rights.
  • it still requires the use of the legend to fully understand
  • the hover action reveals extra info meaning the users has to drag around to reveal the story
  • the legend is squashed due to space

How to solve these issues? I spent a while pondering it and eventually I found a possible answer: I could use a single map but split each hexagon into segments (ignoring marriage as it is allowed in all states – another solution woudl have been to cut out a dot in the middle for the seventh segment).

To do this I’d need to split up each Hexagon into segments, therefore I took out my drawing package and created six shapes:

These six shapes have transparent backgrounds and, importantly, when combined create a single hexagon.

Now with these shapes I can use a dimension (such as Group below) on shape, and then use colour to combine each hegaxon into different segment colours on the map (using Matt’s method and data for Hex positions).

2016-11-13_18-41-23.png

Using this technique I therefore created the visualisation below (click for interactive version):

2016-11-13_15-58-05

Using this method it would be possible to combine 3, 6, 9 or 12 (or possibly more) dimensions on a single map by segmenting the hexagons. Similarly using a circle in the middle would allow 4 or 7 dimensions.

I’m not sure how applicable this type of method is to other visualisations but please let me know if you use it as I’d love to see some more examples.

Advertisements

Bivariate Theming on Maps in Alteryx

“Bivariate Theming” is theming a map on two variables at once, typically showing the size of a point to show the scale of one variable and the colour of a variable to show the scale of another.

Alteryx doesn’t support bivariate theming by default on it’s maps, so users are typically left with no choice but to use software like Tableau to visualise bivariate data. However the Alteryx motto should be “where there’s a will there’s a way”, and that’s certainly the approach I take with any Alteryx problem.

The Aim

I wanted to produce a macro in Alteryx that would produce a bivariate map. Macros in Alteryx encapsulate pieces of functionality, which themselves are Alteryx modules, so they can be reused as simple tools. I wanted the user to choose some of the options Alteryx will typically offer the user when producing maps; namely number of bands and a start / end colour for the theme. I wanted to produce a prototype – not necessarily 100% polished enough for a client, but 90% of the way there to show it could be done.

The Result

For those who just want to see the final result then download it here. This is a package containing some data to test the macro, as well as the macro itself (plus a working “batch” macro).

Bivariate TestBivariate Questions

The questions should be self-explanatory, colours need to be entered using the hex RGB format; http://www.colorpicker.com/ is one of the sites that can be used to get hex codes.

The result is a bivariate map.

Themed Map

The legend overlays the map, which isn’t ideal if there, but it was the best way to get the legend to show nicely. It may not be ideal if the data has many decimal places but this would be easy to remedy or offer as an option to the user.

How I did it

bivariate macro

Well it’s a fairly involved macro – but it contains a lot of advanced Alteryx concepts that it’s worth picking out and dealing with one at a time.

1. Starting out – as with any Alteryx problem that I know will be complex then the first approach I always take is to try out how I’d solve the problem in a manual way. In this case I started by tiling two variables into 5 bands each using two tile tools, concatenating the results into a single variable (e.g. 1|1,1|2,1|3,…,4|5,..,etc) and then using a map tool and breaking out the tiles one at a time manually. This involved setting 25 manual themes, one for each combination of points, varying the size and colour as I needed.

In some ways I could have stopped there, but I didn’t want to stick to just 5 bands, or fixed colours. So I carried on.

2. Embedded Batch Macro – Batch macros are fairly advanced concepts in Alteryx useful for two things, firstly running the same process for multiple inputs, or secondly for updating a tool via data contained in the process. It’s the second use case we want here, we want to update the themes in the map tool config dynamically, the number of bands will determine what we need to do. However because the config for the map tool is currently hard-coded to 25 points then we need our second advanced concept.

3. XML updates – one way of getting the Alteryx to bend to your data-ninja will is to update the raw XML. Yes, Alteryx is simply XML underneath, and those nice chaps at Alteryx have exposed some methods for us to view and update it via macros. Firstly turn on the XML view in the properties window via User Setting -> Advanced -> Display XML in Properties Window. Now we can see what we are dealing with, you can see yourself – scanning down the XML for the map tool in macro.yxmc in the above package we see this XML.

The section we are interested in is in red, you’ll notice elements of that section repeat in the following sections with minor changes:

<Layers>
 <Layer name="1" order="0">
 <LayerType>Points</LayerType>
 <isBaseLayer value="False" />
 <isReorderedBaseLayer value="False" />
 <isRestlyedBaseLayer value="False" />
 <isThemeLayer value="False" />
 <DisplayName>#1 - Points</DisplayName>
 <DataConnection>#1
 <ShowInLegend value="True" />
 <ZoomToLayer value="True" />
 <Disable value="False" />
 <PointStyle StockPointStyle="circle" />
 <ThemeStyle TileMethod="IndividualValue" NumTiles="5" ColorMethod="Map" StartColor="#0000ff" EndColor="#ff0000" UniqueColors="#dc143c,#6495ed,#f0e68c,#228b22,#a9a9a9,#ffa500,#ba55d3,#a0522d,#ff69b4,#4b0082,#d3d3d3,#9acd32,#00ffff,#808000,#ffb6c1" SpecificValues="1|1
1|2
1|3
1|4
1|5
2|1
2|2
2|3
2|4
2|5
3|1
3|2
3|3
3|4
3|5
4|1
4|2
" ManualTiles="" NoneSpecificValuesAction="Color" UpperCutoffIncludedExcluded="Excluded" />
 <LabelStyle Disabled="false" />
 </Layer>
 <Layer name="Base Layers - Points" order="1">
 <DisplayName>Base Layers - Points</DisplayName>
 <DataConnection />
 <LayerType>Placeholder</LayerType>
 <ShowLabel value="False" />
 </Layer>
 <Layer name="Base Layers - Lines" order="2">
 <DisplayName>Base Layers - Lines</DisplayName>
 <DataConnection />
 <LayerType>Placeholder</LayerType>
 <ShowLabel value="False" />
 </Layer>
 <Layer name="Base Layers - Polygons" order="3">
 <DisplayName>Base Layers - Polygons</DisplayName>
 <DataConnection />
 <LayerType>Placeholder</LayerType>
 <ShowLabel value="False" />
 </Layer>
 <Layer name="2" order="1001">
 <LayerType>Points</LayerType>
 <isBaseLayer value="False" />
 <isReorderedBaseLayer value="False" />
 <isRestlyedBaseLayer value="False" />
 <isThemeLayer value="True" />
 <!--[CDATA[1|1
]]></DisplayName>
 <DataConnection>#1</DataConnection>
 <ShowInLegend value="True" />
 <ZoomToLayer value="True" />
 <Disable value="False" />
 <PointStyle Color="#ff0000" Size="10" />
 <ThemeStyle ColorMethod="Ramp" EndColor="#ff0000" ManualTiles="" NoneSpecificValuesAction="Color" NumTiles="5" SpecificValues="" StartColor="#0000ff" TileMethod="SmartTile" UniqueColors="#dc143c,#6495ed,#f0e68c,#228b22,#a9a9a9,#ffa500,#ba55d3,#a0522d,#ff69b4,#4b0082,#d3d3d3,#9acd32,#00ffff,#808000,#ffb6c1" UpperCutoffIncludedExcluded="Excluded" />
 <LabelStyle Disabled="false" />
 <ParentLayer>1</ParentLayer>
 <ThemeBandNumber>1</ThemeBandNumber>
 </Layer>
 <Layer name="3" order="1002">
 <LayerType>Points</LayerType>
 <isBaseLayer value="False" />
 <isReorderedBaseLayer value="False" />
 <isRestlyedBaseLayer value="False" />
 <isThemeLayer value="True" />
 <!--[CDATA[1|2
]]></DisplayName>
 <DataConnection>#1</DataConnection>
 <ShowInLegend value="True" />
 <ZoomToLayer value="True" />
 <Disable value="False" />
 <PointStyle Color="#ff8040" Size="10" />
 <ThemeStyle ColorMethod="Ramp" EndColor="#ff0000" ManualTiles="" NoneSpecificValuesAction="Color" NumTiles="5" SpecificValues="" StartColor="#0000ff" TileMethod="SmartTile" UniqueColors="#dc143c,#6495ed,#f0e68c,#228b22,#a9a9a9,#ffa500,#ba55d3,#a0522d,#ff69b4,#4b0082,#d3d3d3,#9acd32,#00ffff,#808000,#ffb6c1" UpperCutoffIncludedExcluded="Excluded" />
 <LabelStyle Disabled="false" />
 <ParentLayer>1</ParentLayer>
 <ThemeBandNumber>2</ThemeBandNumber>
 </Layer>
 <Layer name="4" order="1003">
 <LayerType>Points</LayerType>
 <isBaseLayer value="False" />
 <isReorderedBaseLayer value="False" />
 <isRestlyedBaseLayer value="False" />
 <isThemeLayer value="True" />
 <!--[CDATA[1|3
]]></DisplayName>
 <DataConnection>#1</DataConnection>
 <ShowInLegend value="True" />
 <ZoomToLayer value="True" />
 <Disable value="False" />
 <PointStyle Size="10" />
 <ThemeStyle ColorMethod="Ramp" EndColor="#ff0000" ManualTiles="" NoneSpecificValuesAction="Color" NumTiles="5" SpecificValues="" StartColor="#0000ff" TileMethod="SmartTile" UniqueColors="#dc143c,#6495ed,#f0e68c,#228b22,#a9a9a9,#ffa500,#ba55d3,#a0522d,#ff69b4,#4b0082,#d3d3d3,#9acd32,#00ffff,#808000,#ffb6c1" UpperCutoffIncludedExcluded="Excluded" />
 <LabelStyle Disabled="false" />
 <ParentLayer>1</ParentLayer>
 <ThemeBandNumber>3</ThemeBandNumber>
 </Layer>
 <Layer name="5" order="1004">
........etc

So if we can produce some XML to update the Layers (maybe by cycling through the data and creating the repeated red XML for each layer) we may be getting somewhere.

Now we’ve made that breakthrough the rest is simple (kinda).

4. Create the colours – creating the colour banding was straightforward. I just converted the start and end values I used as a test from Hex using Alteryx’s built hex conversion in the formula tool. Then I generated as many rows as I needed for the bands, then split the difference between the R, G and B values separately, iterating them over the bands evenly. This is simpler than it sounds, it’s only 7 tools in Alteryx!

5. XML crafting – an approach I always take with Alteryx when using XML us to break the problem into a top, middle and bottom. The top and bottom are the start and end of the XML and are static, the middle repeats as many times as you need – it’s this bit you “blast out” with the rows. I won’t go into detail here, as it’s complex to describe, but basically I copied the sections of XML I needed to replicate into Text Input tools and then altered those sections via formulae, before joining them one on another, in order, using a union. This produced the final XML to pass into the Batch macro to update the map tool within the batch.

6. Tidying up – Using the legend splitter on the output I then went to work on tidying up the legend so I didn’t get 25, or more, items in it. This was relatively easy, I just used the original data, summarised by tile, to update the text, then used the reporting tools – layout tools and overlay – to bring it all back together with the map.

7. Macro – The one last thing is then to use questions and actions to update the module where necessary, e.g. number of tiles, etc, based on user input.

And we’re done. Some advanced concepts but nothing that didn’t take more than about 6 or 7 hours spread over a few nights to blast out. The one thing I’m a little unhappy with is the tiling, with small amounts of data, or a low number of discrete values, the bands don’t go quite how I’d like because we don’t want to split a value over two bands. However this is fundamental to the data and banding rather than anything we can do much with.

Any comments or questions let me know, ChrisLuv on Twitter or via the comments below.