December 5, 2020

Beyond Dual Axis: Using Multiple Map Layers to Create Next-Level Visualizations in Tableau

By Luke Stanke

Tableau’s 2020.4 will be its boldest release yet. And while many people are sleeping on the release, a few people have already started to realize the power of upcoming features. I, at first was among the sleepy people, but I’ve seen the light. It started with a simple tweet by Tableau Zen Master Jeffrey Shaffer

When I saw this. I had to check it out.

But first its important to understand as part of the 2020.4 release, Tableau is unlocking unlimited map layers. Years in the making, when Tableau created this, they imagined being able to place points, polygons, lines, and rasters all on top each other on a single map. And it’s already delivered.

But back to Jeff’s post. After I saw this. I had to take a look at the feature. I knew that unlimited map layers were going to be available, but how did he do it? The secret was just a few clicks away. After experimenting for a bit, Jeff and I came to two different solutions, each with pros and cons. Neither true solutions but amazing hacks of maps.

Trying to make light of the new found ideas I was just playing around with pie charts. Little did I know what was to come.

After some time I was able to come up with a few different examples:

We’ve seen other great examples from Sam Parsons and Tableau Zen Master Adam McCann:

You could technically make each of these examples, but previously it would have required multiple sheets, either stacked on top of each other or stitched together with zero pixel padding to look like seamless visualization. Adam even mentioned his example would have taken at least 12 sheets in the past.

What unlimited map layers allows you to do is create visualizations with more than two layers of marks, previously the maximum through the use of dual axis charts. This means you could stack area charts, line chart, circles, even more circles, text, you name the mark type you can add as many as you want.

First, if you haven’t read Zen Master Jeffery Shaffer blog post, you can read it here. Second, I want to use this post to talk through some of the fundamentals and re-iterate some points.

The basic steps are:

  1. Identify your measure.
  2. Normalize the values.
  3. Use MAKEPOINT() to make points.
  4. Add each MAKEPOINT() calculation to a different layer.
  5. Turn off map layers.
  6. Choose your mark type.
  7. Format, format, format.

Step #1: Identify your measure.

Before you start layering it’ll probably be best to identify the measures you are going to use. For this example we are going to use the Sample – Superstore dataset. We are going to plot sales (a measure) for 2020 by month.

When working with measures I’ve found it best to use level-of-detail calculations to pre-aggregate your visuals. Since we are plotting sales by month for 2020, let’s build that calc.

When working with measures I’ve found it best to use level-of-detail calculations to pre-aggregate your visuals. Since we are plotting sales by month for 2020, let’s build that calc.

// 2020 Sales
{FIXED MONTH([Order Date] : 
    IF YEAR([Order Date]) = 2020 
    THEN [Sales] 

I’m going to do the same for 2019 sales.

// 2019 Sales
{FIXED MONTH([Order Date] : 
    IF YEAR([Order Date]) = 2019 
    THEN [Sales] 

Step #2: Normalize your values

In this technique you are taking standard values and placing them on a map. Latitude ranges from -90 to 90 and longitude -180 to 180 (but you can get away with larger values). The easiest approach is to get the values you are going to plot between -1 and 1 for both your x and y axes–unless you are working with dates, then you can extend the date axis a little bit further.

No matter what, get your values between -90 and 90.

There are many ways to normalized data, if you have positive and negative values, use this calculation:

// Normalize negative and positive values
(  [LOD Measure] - {MIN([LOD Measure])}  )
(  {MAX([LOD Measure])} - {MIN([LOD Measure])}  )

This will place your lowest value at 0 and your highest value at 1

For all positive values you probably want to use 0 as 0 and your maximum value as one. To do this you can normalize without subtracting the minimum values from the numerator or the denominator.

// Normalize only positive values
[LOD Measure]
{MAX([LOD Measure])}

So for my [2020 Sales] LOD:

// 2020 Sales Normalized
[2020 Sales]
{MAX([2020 Sales])}

and my [2019 Sales] LOD:

// 2019 Sales Normalized
[2019 Sales]
{MAX([2019 Sales])}

I’m also using months. I need to normalize this, too. But if I use months as integers, running from 1-12, I don’t have many worries because the values are between -180 and 180. This leave me with a month calculation of:

// Months
DATEPART('month', [Order Date])

Step #3: Use MAKEPOINT()

Once you’ve normalized points you can use the MAKEPOINT() function to build the points to be plotted. MAKEPOINT() takes two arguments, the Y axis and the X. Remember: MAKEPOINT(Y, X).

Here are my 2020 Sales by month:

// 2020 Sales Points
    [2020 Sales Normalized],

Here are my 2019 Sales by month:

// 2019 Sales Points
    [2019 Sales Normalized],

Step #4: Add Layers

Once you have your points created you can make the “map”. Double-click on [2019 Sales Points]. This will add the [Latitude (Generated)] and [Longitude (Generated)] values to rows and columns. 

You need to add the relevant dimensions to detail on the marks card. For this example its just [Months].

I’m not worried about my points being on a map. I’ll fix that in a second with a few clicks.

Now I have a base layer I can add more layers by dragging out my other layers. For this example I’ll add [2020 Sales Points].

You can add as many layers as you want (and you can re-name them!)

Here I have 4 layers. One for 2019, and 3 of the same for 2020. I’ll change the mark type in a second.

Step #5: Turn off the map layer

Go to the top menu, click Maps > Background Maps, then select None.

This will turn off background maps and my example visualization now looks like this:

This is don’t panic moment #2. Your mark types are all map mark types. you can change the mark types and your visualization will start to emerge.

Step #6: Change the mark types

Chang your mark types to your desired type. I’m going to change all mine at once. 

I’ve changed the 2019 layer to area, the 2020 Line layer to line, and the remaining 2 layers to circle. I now have 4 layers with three different mark types.

Step #7: Format everything.

This is the fun part. Now it’s time to format. Here’s what I am doing layer by layer:

2019: Nothing.

2020 Line: Change the line color to dark gray and change the thickness of the line.

2020 Circle: Change the color to white.

2020 Top: Change the size to be slightly smaller than the circle size on the 2020 Circle layer. Add [2020 Sales] to text. Show the minimum and maximum values.

Now for the other stuff. Remove gridlines, an axis ruler on columns, hide the Latitude (Generated) axis. Change the Longitude (Generated) axis label to Month (or hide it)

I’ve mostly showcased everything to this point. Here’s some Advanced tips.

Advanced: KPI Labels

With MAKEPOINT() you can add labels anywhere. I’m going to add a KPI for sales near the top left by centering at the point 1,1.

// KPI Label
    1, 2

Add this as a map layer (you’ll have to turn your map layers back on), change the mark type to text (turn the map layer back off). Add [2020 Sales] to text, and format.

The result is a KPI on the same sheet as the line and area chart.

Advanced: Custom Lines

I struggle with this being the end state because I want to use month names and I could also use gridlines. These are easy to do if you want to create one or two lines. If you want to create a set of gridlines it becomes slightly more complex. I’m going to remove my axis ruler and create a custom axis ruler. using MAKEPOINT(). There is a function called MAKELINE() but this doesn’t work when you turn off map layers.

// Axis Ruler
    IF MONTH([Order Date]) = 1 
    THEN 0 
    ELSEIF MONTH([Order Date]) = 12 
    THEN 13 
    ELSE MONTH([Order Date]) 

Add this layer. Set the mark type to line, size it really small and you have a horizontal line. You could add this line anywhere by adjusting the first value in the MAKEPOINT() function. You will also want to move this layer to the bottom.

This produces the following visualization.

If you wanted to add an axis label, you could set the text to show up at the start of the line.

Advanced: Custom Axis Labels

Because I’ve hidden my axis, i’ve lost labels. I can recreate these by using MAKEPOINT().

// Axis Labels
    MONTH([Order Date])

The -.05 value is below the axis, you can adjust this point later to get your labels to align. From there:

  • Add the layer at the bottom
  • Change the layer mark type to text.
  • Turn on deselect layer.
  • Add month labels (I use abbreviations).
  • I like to add a 4-point “|” on the line above to make it look like a tick.

The result is a visualization with no official axes shown, but axes that have been created with map layers.


Tableau 2020.4 and unlimited map layers is a game-changer. When you turn off the mark labels you can create visualizations that can use more than 2 mark types. It also allows you to remove measure names and measure values from your visualizations.

There is another technique that can be used to create these map layers. The pros of the alternative method is you can plot values beyond the traditional range of -90 to 90 and -180 to 180. The cons: you can only plot to those measures on your view. This post is coming early January 2021.

Data Coach is our premium analytics training program with one-on-one coaching from renowned experts.

Accelerate and automate your data projects with the phData Toolkit