# Sankey: see where flows go and which customers change segment

> Get started with Sankey Plume: prepare a customer table, build a migration chart with new and lost customers, trace a path and select the customers of a flow.

- Language: English
- Web page: https://plumevisuals.com/en/tutorials/migrations-clients-alluvial
- Published: 2026-10-04
- Visual: Sankey Plume, technical reference: https://plumevisuals.com/ai/visuals/alluvial-shift.md
- If an option name in this tutorial differs from the technical reference, the reference is right (it is generated from the visual's code).

## In short

**The concept: flows that split and merge.** A Sankey diagram shows amounts moving from one place to another: visitors from one page to the next, revenue to its costs and its profit, customers from one segment to another. The thickness of a ribbon is proportional to the amount. Example: you have 100 Gold customers in 2024 and still 100 in 2025. Nothing changed? Maybe 30 Gold customers dropped to Silver and 30 Silver customers moved up to Gold: the total is stable, but a third of the segment was renewed. These moves from one category to another, from one period to the next, are called **migrations**. Add the **entries** (new customers) and the **exits** (lost customers).

- **What the visual does.** Sankey Plume draws these flows in columns: one block (a "node") per category in each column, and ribbons between the columns. It can be filled in three ways:
  - **Source and Destination**: one row per flow, like the Microsoft Sankey (page A to page B, cost item to cost item). A name found on both sides is a single node: flows go on over several levels.
  - **Stages**: one column per field (acquisition channel › region › segment).
  - **Over time**: each customer is followed from one period to the next, with new and lost customers.
- **When to use it:**
  - follow customers between segments or ABC classes from one year to the next, measure churn and acquisition;
  - show a journey (pages of a website, steps of a process, channel › region › segment) and its drop-offs;
  - show where a budget comes from and where it goes (income statement, energy, materials).
- **When to use something else:** for a simple change of a total over time, a line chart is enough; to compare amounts with no notion of moving from one place to another, bars are easier to read.
- **By the end, you will know how to:**
  - prepare a table with "one row per customer and per year";
  - build a migration chart with new and lost customers;
  - trace the path of a category on hover and select the customers of a flow;
  - (in the how-to guides) build a Source → Destination Sankey, set the category order, show percentages on the flows.
- **What you need:** Power BI Desktop, the Sankey Plume visual installed (see [the shared basics](/en/tutorials/bien-demarrer-visuels-plume)), a table that says, for each individual (customer, product…) and each period, which category it is in. The **PlumeAlluvialShift-Sample-EN** sample report, in your [**Downloads**](/en/account/downloads) space, shows the three modes (pages 1 to 3) and the ★ threads and highlighted flows (page "4 · Threads and highlights ★").

## The data to provide

**The expected shape for migrations: one row per customer and per year in which the customer is active.** Each row says "this customer, this year, was in this segment". Three **columns** (fields of your table, read row by row) are needed: the individual, the period and the category. A **measure** (a calculation that Power BI redoes according to the filters, written in DAX, the formula language of Power BI; see the [glossary](/en/tutorials/bien-demarrer-visuels-plume#glossary)) is optional: it gives the thickness of the flows.

Why columns? The visual has to find each customer again from one year to the next. So it needs the customer ID and the customer's category, row by row.

A customer who is absent one year has **no row** that year. That is exactly what lets the visual spot it: the customer becomes "Lost" in the next column, or "New" in the previous one.

Sample dataset (`Customers` table, fictitious data):

| Customer | Year | Segment | Revenue |
|---|---|---|---|
| C001 | 2023 | Bronze | 820 |
| C001 | 2024 | Silver | 2150 |
| C001 | 2025 | Gold | 5300 |
| C002 | 2023 | Gold | 6100 |
| C002 | 2024 | Gold | 5800 |
| C002 | 2025 | Silver | 2900 |
| C003 | 2023 | Silver | 2400 |
| C003 | 2024 | Bronze | 760 |
| C004 | 2024 | Bronze | 640 |
| C004 | 2025 | Bronze | 910 |
| C005 | 2025 | Silver | 1980 |
| C006 | 2023 | Bronze | 450 |

What it tells you: C001 moves up every year, C002 drops in 2025, C003 drops then disappears, C004 arrives in 2024, C005 arrives in 2025, C006 leaves after 2023.

The same data, ready to paste. In Power BI Desktop, on the **Modeling › New table** tab, paste:

```dax
Customers =
DATATABLE (
    "Customer", STRING,
    "Year", INTEGER,
    "Segment", STRING,
    "Revenue", DOUBLE,
    {
        { "C001", 2023, "Bronze", 820 },
        { "C001", 2024, "Silver", 2150 },
        { "C001", 2025, "Gold", 5300 },
        { "C002", 2023, "Gold", 6100 },
        { "C002", 2024, "Gold", 5800 },
        { "C002", 2025, "Silver", 2900 },
        { "C003", 2023, "Silver", 2400 },
        { "C003", 2024, "Bronze", 760 },
        { "C004", 2024, "Bronze", 640 },
        { "C004", 2025, "Bronze", 910 },
        { "C005", 2025, "Silver", 1980 },
        { "C006", 2023, "Bronze", 450 }
    }
)
```

Then create two measures (**Modeling › New measure**, one at a time):

```dax
// Counts each customer only once, even with several rows
Customer count = DISTINCTCOUNT ( Customers[Customer] )
```

```dax
// Adds up the revenue of the filtered rows
Customer revenue = SUM ( Customers[Revenue] )
```

> **Tip:** **Tip**: the measure is optional. Without it, each customer counts as 1, which already gives the number of customers. With `Customer revenue`, the thickness of the flows becomes the revenue: a flow can then get wider between origin and destination when customers spent more.

**The other shape: one row per flow (Source, Destination, Value).** This is the shape of the Microsoft Sankey, handy for a page journey or a budget. It is described in the how-to guides ("How do I build a classic Source → Destination Sankey?").

**Preparation pitfalls:**

- **One category per customer and per period.** If a customer appears in two segments the same year, the visual puts it in the larger of the two, with its total value.
- **A period stored as text** ("Q1 2025") is sorted in the order set by **Sort by column** (a model setting that tells Power BI to sort one column by another). Without it, periods may come out of order. Dates and numbers sort by themselves.
- **A period with no row does not exist.** A customer who comes back after a year of absence first counts as lost, then as new.
- **Negative values** (credit notes, returns) are left out, with the "Negative values ignored" warning.
- **Volume**: beyond 24 periods, only the 24 most recent ones are drawn.

## Step by step: your first migration chart in 10 minutes

Start from the `Customers` table and the two measures of "The data to provide".

1. In the **Visualizations** pane, click the **Sankey Plume** icon. An empty frame appears on the page; enlarge it to half the page.
2. In the **Data** pane, drag the `Segment` column to the **Categories (one column per field)** field.
3. Drag the `Year` column to the **Period (migrations over time)** field. Three columns of blocks appear: 2023, 2024 and 2025, with no flows between them. A message invites you to add an individual.
4. Drag the `Customer` column to the **Individual (customer, product…)** field. The flows appear. Hatched blocks are added: "New" at the bottom of a column for customers who arrive in the next column, "Lost" in a column for customers who were there in the previous one.
5. Drag the `Customer count` measure to the **Value or weight (optional)** field. The thicknesses do not change: without a Value, a customer already counted as 1. The how-to guides show how to switch to revenue.
6. In the **Format** pane, **Column headers** card, turn on **Total under the name**. The number of customers of each year is shown under its header.
7. In the **Category labels** card, set **Content** to *Name, value and %*. Each block shows its name, its number of customers and its share of the column.
8. In the **Title** card, type `Customer migrations between segments, 2023-2025` in **Title**.
9. Hover the **Gold** block of the 2023 column. The path of this customer is traced in every column: Gold in 2024, then Silver in 2025. The rest of the chart fades.
10. Click the flow going from **Bronze** (2023) to **Silver** (2024). The customer of this flow (C001) is selected: the other visuals of the page are filtered on it (cross-filtering, see the [glossary](/en/tutorials/bien-demarrer-visuels-plume#glossary)). Click an empty spot of the visual to clear.

**Expected result:** a three-column chart showing the upgrades (C001), the downgrades (C002, C003), the arrivals (C004, C005) and the departures (C006, C003), readable at a glance.

## Troubleshooting

| What you see | Likely cause | Fix |
|---|---|---|
| Columns, but no flows | A Period field with no Individual field | Drag the ID column (`Customer`) to **Individual (customer, product…)** |
| Periods are out of order | The period is text | Set **Sort by column** in the model, or use a date or a number (for example `Year * 10 + Quarter`) |
| The second Categories field does not show | With a Period, only the first Categories field is used | Remove the Period to switch to stages mode, or keep a single field |
| The landing page stays on screen with a Source field | Destination is missing (or the other way around) | Fill in both fields |
| All flows have the same thickness | Stages mode or Source → Destination with no Value: each row counts as 1 | Add a measure to **Value or weight (optional)** |
| A loop runs under the chart | A flow goes back to an earlier column (cycle) | Expected; set **Layout › Flows going backward (cycles)** to *Hide* to leave it out |
| The same name appears in two columns | *Two columns (origin → destination)* is selected | Choose *Chain* for a single node per name |
| "More than 30 levels" warning icon | The flows form very long chains | Filter the data or choose *Two columns* |
| The order dragged with the mouse is not kept | You were in reading view, or the report was not saved | Drag in edit mode (Power BI Desktop or "Edit" in the service), then save |
| Pale flows with a darker part | Another visual of the page highlights data (cross-highlighting) | Expected; click an empty spot of the other visual, or use Power BI's **Format › Edit interactions** to filter instead of highlighting |
| *By the « Flow color » field* changes nothing | The **Flow color (measure)** field is empty | Drag a numeric measure to it |
| An "Others" block groups categories | More categories than **Categories shown at most (the rest in « Others »)** | Raise this setting (up to 40), or use **Hide flows below (% of total)** to lighten the chart |
| "Negative values ignored" warning icon | Credit notes or returns in the Value measure | Expected: only positive amounts are drawn. Filter out negative rows if needed |
| A customer is counted in a single category although it has two in the same year | One category per individual and per period | The visual keeps the larger one; fix the source if this is not intended |
| A returning customer counts as lost, then new | It has no row in the year of its absence | Expected behavior |
| The first years have disappeared | More than 24 periods | Filter the page on the useful periods |
| "Threads unavailable" warning icon, solid ribbons | *Threads* requested with decimal values or more than 3,000 lines | Use a measure in whole numbers (customer count); filter, or use **Hide flows below (% of total)** |
| A flow named in **Highlight flows ★** stays gray | The name matches no flow, or the direction is reversed | Check the spelling of both categories and the direction `origin > destination` |
| A watermark appears | A ★ setting is on with no key (vertical, threads, highlighted category or flow, retention, changes, gradient, ★ style) | Turn it off or add a key (see [the shared basics](/en/tutorials/bien-demarrer-visuels-plume)) |

## Key takeaways

- Source + Destination: one flow per row, over several levels, like the Microsoft Sankey; cycles become loops.
- Category + Period + Individual: migrations from one period to the next, with new and lost; several Categories fields with no Period: a journey in stages.
- The category order is set from a list or by dragging, and no longer changes with filters.
- Hover to trace a path, click a flow to select its individuals; show conversion rates on the flows.
- **Retention rates ★**, **emphasized changes ★**, **highlighted categories or flows ★** answer "who stays, who moves, which way?" directly; with small headcounts, **threads ★** show one line per individual.

## Learn more

- [Sankey Plume how-to guides](/en/tutorials/sankey-plume-cas-pratiques): recipes for common needs.
- [Sankey Plume fields and settings](/en/tutorials/sankey-plume-champs-et-reglages): every field well and every setting.
- [Getting started with Plume visuals](/en/tutorials/bien-demarrer-visuels-plume): installation, license, styles and shared settings.
- The visual's page: [Sankey Plume](/en/visuals/alluvial-shift). A question? [Support](/en/support).
