With the release of Multiple marks layer support in Tableau 2020.4, the possibilities for creating rich, complex visualizations have exploded. No longer limited to dual-axis hacks, advanced developers can now design intricate charts within a single worksheet. Whether you’re crafting a detailed table or pushing the boundaries of a classic chart, map layers open up a whole new world of creative flexibility.
One of my favorite discoveries? Building hexagon radar charts using nothing but map layers.

If you’re just getting started with map layers, I highly recommend checking out Philippe Le Borgne’s No Limit Map Layers visualization on Tableau Public. It’s one of the best tools I’ve seen for understanding how the feature works — and honestly, it deserves way more recognition.
I recently earned my first #VOTD on Tableau Public with a Map Layers Radial Bar Chart — a milestone that inspired me to explore other creative chart types that don’t have clear, step-by-step guides for Tableau’s Map Layers feature.
As a huge football fan, one of my go-to apps for tracking scores and line-ups is Fotmob (no sponsorship here — I just genuinely love it!). When you tap on a player’s profile, you’re greeted with a sleek and informative hexagon radar chart showcasing their key attributes. That chart got me thinking: could I recreate something like this in Tableau using Map Layers?


How I approached the problem
First, I had to figure out how to plot this on an X/Y plane. Since I wanted each triangle section of the radar chart to be equilateral, I decided to base the shape on a circle. I placed points around the circle at 60-degree intervals, starting from the top (0°), and connected them to form the hexagon.



To help visualize it, I thought of each segment spanning 60 degrees, with points plotted at angles like 0°, 60°, 120°, and so on, wrapping around the circle. For each axis, a mirrored version (like 30° and -30°) helped position the lines symmetrically.
Now that I had the angles, I used basic trigonometry to calculate the X and Y coordinates using the SIN() and COS() functions. The Flerlage Twins explain this concept brilliantly in one of their Beyond Show Me blog posts.
Next, I had to figure out how to bring this into Tableau. I was already familiar with the MAKEPOINT() function and knew I’d need it here. From past experience, I also knew that to connect points and form shapes in Tableau, I’d need to densify my data. After some research, I came across Brittany Rosenau’s excellent post, Tableau Polygons 101, which helped me realize that I could form each triangle by connecting just three points. That meant, for this type of chart, I would need to densify the data by a factor of three — one row for each point per triangle.
Implementation in Tableau
Setting Up the Data
To set up the data, you can use either a horizontal or vertical structure. In my most recent Tableau Public visualization, I used a horizontal format, but the template I’ve shared includes options for both. This way, users can choose the structure that best fits their workflow or existing dataset.


Now that we’ve set up the structure and densified the data, we’re ready to read in the dataset of our choice. I’ll walk through the horizontal data version first, as that’s what I used in my Game.Hex.Match visualization. However, I’ll also include the necessary calculations for the vertical version further down.
To keep things as clear and reusable as possible, I’ll use the generic metric names from the template version, rather than the specific ones from my tennis dashboard.
Writing the Calculations
Before we can plot anything, the first step is to set up parameters for each metric axis of the chart. In my template, I created six parameters — one for each of the six axes on the radar — named Metric 1 through Metric 6. These allow users to choose which fields are displayed on each axis.
Next, I created calculated fields to return the corresponding value based on each selected parameter. For example, the calculation for Metric 1 looks like this:

// Value | Metric 1
CASE [Metric 1]
WHEN 'M1' THEN [M1]
WHEN 'M2' THEN [M2]
WHEN 'M3' THEN [M3]
WHEN 'M4' THEN [M4]
WHEN 'M5' THEN [M5]
WHEN 'M6' THEN [M6]
END
This logic is repeated for each metric, resulting in six calculated fields. These will feed directly into the normalized values.
Before moving on to those calculations, there’s one more step: normalization. Since the metrics may be on different scales (e.g., one out of 100, another out of 10), we need to bring them onto a consistent range to plot them accurately.
I used Min-Max feature scaling, which maps each value to a range between 0 and 1. This keeps the chart balanced and proportional.
The formula is:

// N-Value | Metric 1
([Value | Metric 1] -
{MIN([Value | Metric 1])})
/
({MAX([Value | Metric 1])} - {MIN([Value | Metric 1])} )
This logic is repeated for each metric, resulting in six calculated fields. These will feed directly into the trigonometry calculations.

Right, now let’s get into each one of the hexagon triangles representing each metric:


// Map | Polygon Metric 1
IF [Path] = 1 THEN
MAKEPOINT([N-Value | Metric 1], 0)
ELSEIF [Path] = 2 THEN
MAKEPOINT(SIN(RADIANS(30))*[N-Value | Metric 1],
COS(RADIANS(30))*[N-Value | Metric 1])
ELSE MAKEPOINT(0,0)
END


// Map | Polygon Metric 2
IF [Path] = 1 THEN
MAKEPOINT(SIN(RADIANS(30))*[N-Value | Metric 2], COS(RADIANS(30))*[N-Value | Metric 2])
ELSEIF [Path] = 2 THEN
MAKEPOINT(SIN(RADIANS(-30))*[N-Value | Metric 2], COS(RADIANS(-30))*[N-Value | Metric 2])
ELSE MAKEPOINT(0,0)
END


// Map | Polygon Metric 3
IF [Path] = 1 THEN
MAKEPOINT(SIN(RADIANS(-30))*[N-Value | Metric 3], COS(RADIANS(-30))*[N-Value | Metric 3])
ELSEIF [Path] = 2 THEN
MAKEPOINT(-[N-Value | Metric 3], 0)
ELSE MAKEPOINT(0,0)
END


// Map | Polygon Metric 4
IF [Path] = 1 THEN
MAKEPOINT(-[N-Value | Metric 4], 0)
ELSEIF [Path] = 2 THEN
MAKEPOINT(-SIN(RADIANS(30))*[N-Value | Metric 4], -COS(RADIANS(30))*[N-Value | Metric 4])
ELSE MAKEPOINT(0,0)
END


// Map | Polygon Metric 5
IF [Path] = 1 THEN
MAKEPOINT(-SIN(RADIANS(30))*[N-Value | Metric 5], -COS(RADIANS(30))*[N-Value | Metric 5])
ELSEIF [Path] = 2 THEN
MAKEPOINT(-SIN(RADIANS(-30))*[N-Value | Metric 5], -COS(RADIANS(-30))*[N-Value | Metric 5])
ELSE MAKEPOINT(0,0)
END


// Map | Polygon Metric 6
IF [Path] = 1 THEN
MAKEPOINT(-SIN(RADIANS(-30))*[N-Value | Metric 6],
-COS(RADIANS(-30))*[N-Value | Metric 6])
ELSEIF [Path] = 2 THEN
MAKEPOINT([N-Value | Metric 6], 0)
ELSE MAKEPOINT(0,0)
END
Now we have all our calculations we can now bring them into a worksheet!
Creating the Hexagon Radar Chart
- Drag Map | Polygon Metric 1 in the middle of the worksheet.

- Drag Map | Polygon Metric 2 into the worksheet and a pop-menu will appear allowing you to drop the pill into ‘Add a Marks Layer’, which will add the second layer.
Note: when using map layers you should always drag a second mark into the view before turning the background map to none. If you do it after the first mark is dragged in you won’t be able to add in the second.

- Go to Map in the Toolbar and then select Background Maps and select None. This will turn the world map and switch it to an X and Y coordinate pane.
- Let’s go into each Mark and change the Type from Automatic to Polygon and add Path to the Path Mark. This will create the view below. Don’t panic, you can kind of see two triangles glued together!

- Next lets edit each axis and fix the range from -1.1 to 1.1. This will allow us to see all the polygons as we add them to the view.


- Similar to Steps 1 and 2, let’s add in the remaining four metrics to the view, change the mark to Polygon and add Path to the Paths mark. Additionally, let’s select the Colour mark and change the Opacity to 80% and also add a white border so we can see the Triangles a little easier.

- There we have it, I have also renamed each mark so I can keep track of where they are! Only one last thing to do now is add the background image.
- Go to Map in the toolbar and select Background Images. Once the next pop-up menu opens up select Add Image and add in your hexagon image. Be sure to set the longitudes and lattitudes between -1 and 1.
Feel free to use one of the hexagon templates that I have created in Figma below:

And there we have it! We now have our Hexagon Radar Chart!

Now that we’ve built the core chart in a single view, it’s time to shift focus to formatting, labeling, and adding that extra layer of polish — the visual magic that transforms it from a functional chart into a beautiful, intuitive dashboard.
This is where thoughtful design choices come into play:
- Label placement to ensure readability without clutter
- Consistent color schemes to reinforce the narrative
- Interactive elements like tooltips or parameter controls that invite exploration
Just like the final touches on a project, thoughtful design and formatting help bring the dashboard to life — making insights clear and engaging.
Be sure to check out my “Using Map Layers to Build Hexagon Radar Templates” dashboard on Tableau Public, where you can also download the accompanying Excel template. It includes both horizontal and vertical data structures to help you get started building your own version of this chart.
And if you’re looking for inspiration on how this technique can be applied to real-world data, take a look at my Game.Hex.Match dashboard — a deep dive into the top 50 ATP tennis players. It showcases how hexagon radar charts can be used to compare player attributes in a clean, interactive, and visually compelling way using nothing but Map Layers.
Thanks for reading! If you have any questions or thoughts, feel free to leave a comment below — I’d love to hear from you.
Calculations for Vertical Dataset
Below are the calculations that are needed if you are using a vertical dataset. They are also available in my Hexagon Radar Templates dashboard:

// N-Value
([Value] - {FIXED [Metric] : MIN([Value])} )
/
( {FIXED [Metric] : MAX([Value])} - {FIXED [Metric] : MIN([Value])} )

// Map | Polygon Points
IF [Path] = 1 THEN
CASE [Metric]
WHEN 'M1' THEN MAKEPOINT([N-Value], 0)
WHEN 'M2' THEN MAKEPOINT(SIN(RADIANS(30))*[N-Value], COS(RADIANS(30))*[N-Value])
WHEN 'M3' THEN MAKEPOINT(SIN(RADIANS(-30))*[N-Value], COS(RADIANS(-30))*[N-Value])
WHEN 'M4' THEN MAKEPOINT(-[N-Value], 0)
WHEN 'M5' THEN MAKEPOINT(SIN(RADIANS(30))*-[N-Value], COS(RADIANS(30))*-[N-Value])
WHEN 'M6' THEN MAKEPOINT(SIN(RADIANS(-30))*-[N-Value], COS(RADIANS(-30))*-[N-Value])
END
ELSEIF [Path] = 2 THEN
CASE [Metric]
WHEN 'M1' THEN MAKEPOINT(SIN(RADIANS(30))*[N-Value], COS(RADIANS(30))*[N-Value])
WHEN 'M2' THEN MAKEPOINT(SIN(RADIANS(-30))*[N-Value], COS(RADIANS(-30))*[N-Value])
WHEN 'M3' THEN MAKEPOINT(-[N-Value], 0)
WHEN 'M4' THEN MAKEPOINT(SIN(RADIANS(30))*-[N-Value], COS(RADIANS(30))*-[N-Value])
WHEN 'M5' THEN MAKEPOINT(SIN(RADIANS(-30))*-[N-Value], COS(RADIANS(-30))*-[N-Value])
WHEN 'M6' THEN MAKEPOINT([N-Value], 0)
END
ELSE MAKEPOINT(0,0)
END

// Map | Triangle Labels
IF [Path] = 0 THEN
CASE [Metric]
WHEN 'M1' THEN MAKEPOINT(SIN(RADIANS(60)), COS(RADIANS(60)))
WHEN 'M2' THEN MAKEPOINT(0, 1)
WHEN 'M3' THEN MAKEPOINT(SIN(RADIANS(-60)), COS(RADIANS(-60)))
WHEN 'M4' THEN MAKEPOINT(-SIN(RADIANS(60)), -COS(RADIANS(60)))
WHEN 'M5' THEN MAKEPOINT(0,-1)
WHEN 'M6' THEN MAKEPOINT(-SIN(RADIANS(-60)), -COS(RADIANS(-60)))
END
ELSE NULL
END

One thought on “Beyond Dual Axis Part 1: Creating Hexagon Radar Charts in Tableau with Map Layers”