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.

 

Advertisements

2 thoughts on “Bivariate Theming on Maps in Alteryx

  1. Outstanding explanation. Thanks for sharing. It displays the depth of knowledge that gets you atop the Alteryx Grand Prix podium. 🙂

    • Ha, thanks John. Yes, that Grand Prix title does mean I have to up my game when it comes to posting – need to prove I’m worthy 🙂

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s