Beeswarm Plume: 9 use cases to read a distribution well
Step by step: animate dots from one year to the next, compare with last year, raincloud, box plot, in-visual search, large volumes and group order.
Lire en françaisThese recipes start from a Beeswarm Plume already in place. If you do not have one yet, start with the getting started guide: the examples reuse its data (Stores table, Total sales measure). Features marked ★ are premium: they work without a license, with a watermark.
How do I animate dots from one year to the next ★?
You have one value per item and per year (price per m² by town, sales by store and year) and you want to see the swarm move.
- Drop the year column (or a date on January 1) into Play axis ★. Use the column itself, not the date hierarchy.
- A play bar appears under the swarm: click ▶. Each dot glides from its value in one year to its value in the next; medians glide with it; the current year is written in large type.
- Set the speed in Format › Playback ★ › Playback › Duration of a frame (ms), or with the ×1 button of the bar (×0.5 to ×4). Turn on Loop for a presentation.
- Click an item: it stays selected in every year, so you can follow its path.
Result: dots never overlap, even while moving, and keep the same size from one year to the next. The play axis is a ★ feature: without a key, the "Premium preview" watermark appears as soon as the field holds data. With Format › Playback ★ › More settings › Dot history = Selected dots, a trail shows the past values of the item you follow.
A town that exists only in some years fades in when it appears and fades out when it leaves. "Reduce motion" (Format › Style › Animations, or Windows) turns transitions off.
How do I compare each dot with last year ★?
You want to see who moves up and who moves down, not only where each one stands.
- Create the reference measure:
Sales PY = CALCULATE ( [Total sales], SAMEPERIODLASTYEAR ( 'Date'[Date] ) ) -- or a "Sales 2024" column
- Drop it into Compare with ★. Each dot gets a stem from last year's value and a hollow dot at that value.
- In Format › Comparison ★, turn on Color dots by their gap: green if favorable, red if unfavorable.
- If a decrease is good news (lead times, costs), turn off An increase is favorable.
Result: each dot's tooltip gives the reference and the gap, as a value and in %, with ▲ or ▼ written (the direction never relies on color alone).
How do I build a raincloud plot ★?
A raincloud plot combines three views of a distribution: the density, the box and the dots.
- Format › Swarm › Layout › Side = One side (above or right).
- Format › Statistics › Violin ★: turn on Violin (density).
- Format › Statistics › Box plot ★: turn on Box plot.
Result: in each band, the dots on one side, half a violin on the other, a thin box in between. Values beyond the whiskers get a red ring.
How do I show a box plot behind the dots ★?
- Format › Statistics › Box plot ★: turn on Box plot.
- Whiskers: 1.5 × interquartile range (Tukey) (the standard), Minimum and maximum, 5th and 95th percentiles or 10th and 90th percentiles.
- Ring the outliers: dots beyond the whiskers get a ring.
- To name them: Format › Data labels › Labeled dots = Outliers (1.5 × interquartile range) ★.
Quartiles are computed like PERCENTILE.INC in DAX: a measure gives the same values.
How do I let readers search for an item ★?
In a swarm of 500 dots, a reader wants to find "their" store.
- Format › Search ★ › Search box in the visual ★: turn it on. For a video or a presentation, Hide while playing (play axis) (on by default) and Hide in reading view remove the box.
- In reading view, type a few letters in the box at the top of the visual: dots whose name contains that text stand out (case and accents ignored) and are labeled; the number found is shown.
- Press Enter: the found dots are selected and filter the page. Esc clears the search.
To highlight items chosen in advance, type their names in Highlight ★ › Highlighted dots ★ (one per line), or drop a measure into Highlight ★ (not blank and not 0 = highlighted).
How do I show 100,000 dots?
- Drop the detailed field into Details: Power BI sends 30,000 rows, then the visual asks for the rest, up to 200,000 rows.
- Keep Shrink dots so that everything fits on: dots get very small (never below 0.6 px) but none spills out of its band.
- Enlarge the visual and keep the number of groups low so that dots stay visible.
Beyond about 20,000 dots in one band, the visual switches to a fast layout (staggered grid): each dot moves at most one radius away from its exact value.
How do I sort groups by median ★?
- Format › Swarm › Groups (bands) › Group order = Median, descending ★ (or Median, ascending ★).
- Groups do not move during playback: the median used is the one of all years.
Other options, free: Number of dots, Name (A → Z), or the data order (the sort of the column in the model, for instance an "Order" column).
How do I build a dot histogram ★?
- Format › Swarm › Layout › Layout = Sieve (dot columns) ★.
- Side = One side (above or right) for columns standing on a baseline.
Result: each column holds the dots of an interval one dot wide, stacked in value order: a histogram where you can still hover and select each item.
How do I title the swarm with the current median?
Dynamic formatting drives any setting with a measure (free).
- Create the measure:
Swarm title =
"Sales of " & COUNTROWS ( ALLSELECTED ( Stores ) ) & " stores · median "
& FORMAT ( CALCULATE ( MEDIAN ( Stores[Sales] ), ALLSELECTED ( Stores ) ), "$#,0" )
- Drop it into Dynamic format and rename it for this visual
title.text(right-click the field › Rename for this visual).
Result: the title follows the page slicers. The list of keys is in dynamic formatting.
How do I keep the same scale when filtering?
A Format slicer removes the stores of the other format: the value axis refits to the remaining dots, and the eye can no longer compare. Pin the bounds with measures that ignore this filter.
- Create the measures:
Axis min =
CALCULATE ( MIN ( Stores[Sales] ), REMOVEFILTERS ( Stores[Format] ) ) -- the lowest sales, all formats
Axis max =
CALCULATE ( MAX ( Stores[Sales] ), REMOVEFILTERS ( Stores[Format] ) )
- Drop them into Dynamic format, then rename them for this visual
valAxis.minandvalAxis.max. - Pick a format in the slicer: the axis no longer moves, only the dots change.
Don't use ALLSELECTED (): it follows slicers, so the scale would still move. REMOVEFILTERS ( Stores ) (or ALL ( Stores )) ignores every filter. A highlight sent by another visual does not change the scale (Interactions › Scale during cross-highlighting).