Introduction
It’s nice to be invited back by the team, and thanks for having me! While it’s tempting for me to think of something for you explore with the Deneb or HTML Content custom visuals (and I’d still encourage that!), I’d like to continue some of the other threads we’ve recently seen around what we can do with Power BI out of the box.
Error bars are a fantastic feature of the core visuals, and you can use them to create some useful variations, as we’ve seen in two recent workouts (Week 19, by Diana Ackermann and Week 22, by Santhanalakshmi Ponnurasan).
For this week’s workout, we’ll be using the stuff we’ve learned over those examples, and more to create a box plot visual using the clustered column chart 📊. Each visual’s usage of the Cartesian coordinate system (x/y) and some lateral thinking around their features, combined with understanding how other chart types might be composed, can lead to some fun discoveries.
I like the idea of a box plot because even though there are custom visuals available that do this for you, they can’t use knowledge of the data model to perform analysis. Therefore, you will need to provide data at the same grain as the table you want to analyze, and you may fall afoul of row limits.
Instead, we can look at the composition of a box plot visual, and we can write measures that aggregate irrespective of how many rows are in your tables, and DAX is very good at this.
I’ve added some theory to the approach we’re going to take for this workout, but if you want to get started right now, head down to the Requirements section.
Our Box Plot
For the uninitiated, a box plot provides a simple graphical overview of the distribution of your data. There are many variations of how they can be used, and there are many valid criticisms of their usefulness (e.g., 1 | 2), but let’s not get caught up in this and treat this as an exercise in thinking about charts from a composition perspective.
Speaking of which, here’s a brief anatomy of the box plot we will create:
If we split this design up, we can think of it as three distinct parts (or layers):
Each layer is an element, bound to data:
- The whiskers are bound to the low and high 1.5 IQR values.
- The box is bound to the 1st and 3rd quartile values.
- The median line is positioned according to our median value.
We can easily create measures for all these values, and these have already been done for you in the provided workbook (in the Daily Readings table), allowing us to focus on building the visual.
Thinking Like a Clustered Column (or Bar) Chart
A clustered column chart lets us position multiple measures within the same series. For example, if we add measures for Minimum, Median, and Maximum by month, we get this (or similar) output:
Thanks to recent changes in Power BI, we can change the layout so all columns overlap and can use the same horizontal space, e.g.:
It now looks like a stacked column chart, but all columns are positioned vertically relative to the origin (0) on the y-axis.
And because error bars let us plot simple primitive shapes on a per-measure basis along the measure (y) axis, we can have fun with this.
So, let’s get building!
Requirements
Step 1: Data
Using the starter file, add a clustered column chart. Put the Month field (from the Date table) on the X-axis data role and add the Minimum Temperature, Maximum Temperature, and Median Temperature measures to the Y-axis data role.
In the Y-axis data role, rename:
- Minimum Temperature to Whiskers
- Maximum Temperature to Box
- Median Temperature to Median
(I find the process of renaming my measures to reflect their role in the downstream chart helpful while I’m configuring them)
Step 2: Formatting
Now, let’s throw away all the stuff that makes this chart what it is! Set Legend to Off, and Columns > Color > Transparency to 100%.
Optionally, remove the axis titles and update the chart title to reduce redundant elements – I’ve gone for: Temperature Distribution by Month (°C)
Step 3: Whiskers
Using the Error bars menu, select Apply settings to > Whiskers. This is where naming the measures comes in handy!
Set Options > Enabled to On.
Drag the following measures from the Daily Readings table:
- 1.5 IQR Temperature (Lowest) to the Lower bound property.
- 1.5 IQR Temperature (Highest) to the Upper bound property.
Under the Bar property card, set:
- Bar color to White, 60% darker (or #666666).
- Width to 2.
- Border size to 0.
Step 4: Quartiles (box)
Using the Error bars menu, select Apply settings to > Box.
Set Options > Enabled to On.
Drag the following measures from the Daily Readings table:
- 1st Quartile Temperature to the Lower bound property.
- 3rd Quartile Temperature to the Upper bound property.
Under the Bar property card, set:
- Bar color to White, 10% darker (or #e6e6e6).
- Width to 10 (maximum).
- Border color to White, 60% darker (or #666666).
- Border size to 2.
Set the Markers property to Off.
Step 5: Median
Using the Error bars menu, select Apply settings to > Median.
Set Options > Enabled to On.
Drag the following measures from the Daily Readings table:
- Median Temperature to the Lower bound property.
- Median Temperature to the Upper bound property.
(Note that although we’re using the Median measure as the basis for this column, just assigning the same measure to the Lower bound property is enough to keep it relative to that measure, but I find this a handy method to ensure that both the upper and lower bound are explicitly set as I want them to be for my design, in case I change the underlying measure for the layer).
Under the Bar property card, set:
- Bar color to White, 60% darker (or #666666).
- Border size to 0.
Under the Markers property card, set:
- Size to 8 (width of the box, minus the border).
Step 6: Layout
Using the Columns property menu, set:
- Overlap to On.
- Space between series to 100%.
We’re done!
At this point, we have leveraged the strengths of DAX to calculate our statistics quickly and utilized a core visual and error bars to visualize these key statistics.
Some Other Considerations
With great power comes great responsibility: remember that you are transforming a core visual away from its intended purpose, so some things may not be 100% as intended by Power BI’s developers. Here are a few things to bear in mind, which should help you consider this technique for any other designs or ideas you might have:
Draw Order
The order in which the measures are added to the Y-axis data role dictates the order in which they are drawn in the chart.
The first measure is the ‘furthest’ item, and the last measure is the ‘nearest’ item in terms of overlap.
You can manually re-position the measures in the data role to make them be drawn in the desired order if things don’t look correct in your designs, or you can use the Flip overlap property to draw measures in reverse order rather than flipping them manually.
Axis Scaling
Keeping the measure axis for a column or bar chart is the decent thing to do. If your error bars don’t quite reach zero, you may wish to set the axis min and max via a suitable measure (like 1.5 IQR) to maximize the available area for your custom chart. Our finished recipe has this applied.
If you are using bars or columns, make sure that the scale makes sense and nothing is truncated.
Cross-Filtering
In this example, you can slice and cross-filter this data just like normal. The trick here is to use measures that span the minimum and maximum range of our data for each series, which still draws the underlying column and therefore makes it a target for the click event. This is something to bear in mind if you use measures that don’t fall within the target area of your error bars.
If you want to cross-filter from other visuals, it may be worth changing the interaction to filter rather than highlight, as your underlying columns will remain contextually active. The complete workbook includes an example of this in the finished recipe.
Tooltips
Overlapping (and invisible) columns mean that your tooltip target information may not always be 100% correct. This can be mitigated with report page tooltips; the complete workbook includes an example of this in the finished recipe.
Visual Calculations
It’s also possible to solve many of the approaches we’re going for here in terms of visual ‘elements’ by using visual calculations rather than dedicated measures. As these are still in preview at the time of writing, I’ve opted not to use them for this workout, but bear in mind that these are scoped to the visual dataset rather than your entire semantic model.
Dataset
We will analyze a dataset sourced from Stats New Zealand, which in turn is derived from the National Institute of Water and Atmospheric Research (NIWA)’s seven-station temperature series from 1909 to 2022.
This is a dataset I like to work with regularly, as it’s simple enough but has a substantial volume (approximately 714,000 rows), which is more than we could fit into a conventional or custom visual at a row level. It’s also the wrong way round for our friends in the Northern Hemisphere 😉
You can learn more about this dataset and its findings here.
For this exercise, I’ve already prepared this data into a starter workbook that you can use for your work. The complete workbook, which includes our finished recipe, also utilizes this data.
Share
After you finish your workout, share on social media using the hashtags #WOW2025 and #PowerBI. Tag me (Daniel) on LinkedIn, along with Meagan, Kerry, and Shannon!
On Bluesky, tag @mmarie.bsky.social, @shan-gsd.bsky.social, and @merrykerry.bsky.social.
Solution
Download the complete workbook to see exactly how the report is built!