# Create a climate ridgeline in Power BI

> Get started with Ridgeline Plume: go from weather data to a ridgeline chart, prepare the columns, add the visual to your report and set the key options.

- Language: English
- Web page: https://plumevisuals.com/en/tutorials/ridgeline-climatique
- Published: 2026-09-29
- Visual: Ridgeline Plume, technical reference: https://plumevisuals.com/ai/visuals/ridgeline-pulse.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

- **What the visual does.** Ridgeline Plume draws a filled curve per category (one "ridge" per year, per weather station, per product…), then stacks these ridges one below the other so that they overlap, like a mountain range seen from the front. It's the image on the cover of Joy Division's *Unknown Pleasures* album, and the one used for "climate ridgelines" where recent years spill over the top. You can see at a glance what changes from one ridge to the next: a peak that shifts, a season that gets longer, an unusual year.
- **When to use it:**
  - track the same curve over many periods (daily temperatures, one ridge per year);
  - compare how values are distributed across groups (delivery times by warehouse, grades by class);
  - spot an unusual year or group among 20 to 100 others;
  - tell the story of a trend as an animation, ridge after ridge ★.
- **When to use something else:** for 2 to 5 series you need to read precisely, a classic line chart (Line Chart Plume) is easier to read; for a total per category, use a bar chart.
- **By the end of this tutorial, you will know how to:**
  - prepare a table in the right shape (one row per ridge and per X position);
  - build a readable ridgeline in under 10 minutes, with the free version;
  - adjust the overlap, the scale, the colors and the labels;
  - compare each ridge with a reference, animate the ridges and open focus mode ★;
  - troubleshoot common problems (flat ridges, averaged values, disappearing years).
- **What you need:** Power BI Desktop, the Ridgeline Plume visual installed (see [the common basics](/en/tutorials/bien-demarrer-visuels-plume), "Install a Plume visual"), and data with at least one category (the ridges), one position (day, month, value bin) and one numeric value.

## The data to provide

### What a ridge draws: a series or a distribution?

Each ridge is a curve drawn from points (position on the X axis, height). There are two possible uses.

- **A time series.** X is a day, a week or a month; the height is the value measured that day (temperature, sales, response time). One ridge per year lets you compare the years with each other. This is the example used in this tutorial.
- **A distribution.** A distribution is the way values are spread out: how many orders were delivered in 1 day, how many in 2 days, how many in 3 days… A **density curve** draws this spread as a hill: the higher the hill at a given spot, the more values there are at that spot. "Statistical" ridgelines stack one hill per group to compare the distributions. In Ridgeline Plume, X is then a **value bin** (1 day, 2 days…) and the height is the **number** or **share** of observations in that bin: it's a histogram, which the *Smooth* curve rounds into a hill. See the [how-to guide "How do I compare distributions?"](/en/tutorials/ridgeline-plume-cas-pratiques#how-do-i-compare-distributions-a-histogram-per-group).

> **Warning:** **Warning**: the visual does not calculate a density from raw values by itself. Your measure (see the [glossary](/en/tutorials/bien-demarrer-visuels-plume#glossary)) gives the height of each point: for a distribution, you count the observations per bin yourself.

### The expected shape: one row per ridge and per X position

The visual reads a "long" table: **one row per (Ridge, X) pair**.

- **Ridge**: a **column** (a field in your table, see the [glossary](/en/tutorials/bien-demarrer-visuels-plume#glossary)), for example `Year`. One ridge is drawn for each distinct value.
- **X axis**: a **column** that gives the position along the ridge. Its type determines the axis:
  - whole or decimal number: numeric axis (day of the year 1 to 366, hour 0 to 23, week 1 to 53, value bin);
  - date: the date is converted to a **day of the year**, so each ridge runs from January 1 to December 31;
  - text: axis in the column's sort order in Power BI.
- **Height**: a **measure** (a DAX calculation that Power BI recomputes for each point, see the [glossary](/en/tutorials/bien-demarrer-visuels-plume#glossary)). Power BI evaluates it for each (Ridge, X) pair. A measure rather than a column, because the visual needs a value calculated in the context of each point: the average of the 2003 days for day 196, for example.

Here is a small fictitious dataset to understand the shape: 3 years, 4 days per year (mid-January, mid-April, mid-July, mid-October).

| Year | DayOfYear | MaxTemp |
|---|---|---|
| 1995 | 15 | 6.8 |
| 1995 | 105 | 14.2 |
| 1995 | 196 | 25.1 |
| 1995 | 288 | 17.9 |
| 2010 | 15 | 7.4 |
| 2010 | 105 | 15.6 |
| 2010 | 196 | 26.8 |
| 2010 | 288 | 18.6 |
| 2024 | 15 | 8.9 |
| 2024 | 105 | 16.3 |
| 2024 | 196 | 29.4 |
| 2024 | 288 | 20.2 |

The same dataset, ready to paste into **Modeling › New table**:

```dax
Weather =
DATATABLE (
    "Year", INTEGER,
    "DayOfYear", INTEGER,
    "MaxTemp", DOUBLE,
    {
        { 1995, 15, 6.8 }, { 1995, 105, 14.2 }, { 1995, 196, 25.1 }, { 1995, 288, 17.9 },
        { 2010, 15, 7.4 }, { 2010, 105, 15.6 }, { 2010, 196, 26.8 }, { 2010, 288, 18.6 },
        { 2024, 15, 8.9 }, { 2024, 105, 16.3 }, { 2024, 196, 29.4 }, { 2024, 288, 20.2 }
    }
)
```

Four points per ridge are enough to understand, not for a nice result. For the walkthrough, create this table of 30 years × 365 days (10,950 rows) instead, with **the same columns**. It simulates a maximum temperature that rises in summer, with slight warming from year to year and a little "noise" (day-to-day variations):

```dax
Weather =
ADDCOLUMNS (
    CROSSJOIN (
        SELECTCOLUMNS ( GENERATESERIES ( 1995, 2024, 1 ), "Year", [Value] ),        -- one row per year
        SELECTCOLUMNS ( GENERATESERIES ( 1, 365, 1 ), "DayOfYear", [Value] )        -- crossed with each day
    ),
    "MaxTemp",
        ROUND (
            14
                + 10 * SIN ( 2 * PI () * ( [DayOfYear] - 110 ) / 365 )   -- season: peak around July 20
                + 0.05 * ( [Year] - 1995 )                               -- warming of 0.05 °C per year
                + 3 * SIN ( [DayOfYear] * 0.7 + [Year] ),                -- day-to-day "noise"
            1
        )
)
```

### The measures to create

Create them with **Modeling › New measure**.

```dax
Avg max temp =
AVERAGE ( Weather[MaxTemp] )   -- average temperature of the rows visible for this point (here a single row)
```

A raw daily temperature is very irregular: the ridges become unreadable. A **7-day moving average** (the average of the day, the 3 days before and the 3 days after) brings out the shape of each year:

```dax
Smoothed temp 7d =
VAR currentDay = SELECTEDVALUE ( Weather[DayOfYear] )   -- the day of the point being calculated
RETURN
    CALCULATE (
        AVERAGE ( Weather[MaxTemp] ),                     -- average the temperatures…
        FILTER (
            ALL ( Weather[DayOfYear] ),                   -- …removing only the filter on the day
            Weather[DayOfYear] >= currentDay - 3          -- …to keep the 3 days before
                && Weather[DayOfYear] <= currentDay + 3   -- …and the 3 days after
        )
    )
```

`ALL ( Weather[DayOfYear] )` only removes the filter on the day: the filter on the year, set by the ridge, is kept. Each point of the 2003 ridge is therefore the average of the 7 days around that day, **in 2003**.

> **Tip:** **Tip**: in a real model, calculate the year and the day of the year in a **date table** related to your facts: `Year = YEAR ( 'Date'[Date] )` and `DayOfYear = DATEDIFF ( DATE ( YEAR ( 'Date'[Date] ), 1, 1 ), 'Date'[Date], DAY ) + 1`. The principle is the same.

### Data preparation pitfalls

- **Granularity** (the level of detail of a row: a day, a month…). If a ridge receives several rows for the same X, the visual **averages** them and shows a warning in edit mode. Typical case: a Date column in **X axis** but nothing in **Ridge**: all the years collapse onto the same day of the year. Put the year (or the right level) in **Ridge**.
- **Dates in X axis**: they become a day of the year. This is intended (one ridge per year, from January to December). To follow a period that spans two years (ski season, school year), use a numeric "day of the season" column.
- **Months as text**: without a sort order, "April" comes before "January". Select the month column, then **Column tools › Sort by column** › the month number.
- **Ridge names**: numbers (years) are sorted numerically; text keeps Power BI's sort order (use **Sort by column** too if needed).
- **Blank values**: a measure that is blank for every point gives an empty visual. Check the page filters.
- **Volume**: the visual loads data in batches of 30,000 rows and automatically requests the rest (70 years × 366 days ≈ 25,600 rows fit in one go). Beyond 500 ridges or 500,000 rows, it stops and says so in edit mode.

## Step by step: your first ridgeline in 10 minutes

We use the generated 30-year table and the `Smoothed temp 7d` measure from ["The data to provide"](#the-data-to-provide). This whole walkthrough is **free**: no watermark.

1. On the **Modeling** tab, click **New table**, paste the formula `Weather = ADDCOLUMNS ( CROSSJOIN (…` and confirm. The `Weather` table appears in the **Data** pane with its `Year`, `DayOfYear` and `MaxTemp` columns.
2. Select the `Weather` table, click **New measure** and paste the `Smoothed temp 7d` measure. It appears under the table, with the calculator icon.
3. In the **Visualizations** pane, click the **Ridgeline Plume** icon. An empty frame appears with a welcome screen that lists the fields to fill in.
4. Drag `Year` into the **Ridge (one per value)** field.
5. Drag `DayOfYear` into the **X axis** field.
6. Drag `Smoothed temp 7d` into the **Height** field. Thirty ridges appear, from 1995 (top) to 2024 (bottom), each with a summer dome.

7. Also drag `Smoothed temp 7d` into the **Color** field. Each ridge is colored point by point: cold in winter, warm in summer (default setting *Gradient along the curve*).
8. In the **Format** pane, **Ridges** card › **Overlap (%)**: type `200`. The ridges climb onto one another: the "mountain" effect appears.
9. **Category labels** card › **Show 1 label every N**: type `5`. Only one year in five stays written on the left, giving the text room to breathe.
10. **Legend** card › **Title text (empty = field name)**: type `Max temp (°C)`. The legend at the bottom of the visual takes this title.
11. Hover over a ridge: it stands out, the others fade, and the tooltip gives the year, the day and the temperature. Click it: the other visuals on the page are filtered to that year (Ctrl+click to add more, click an empty area to cancel).

You now have a complete ridgeline, with cross-filtering, tooltips and highlighting, in the free version.

> **Tip:** **Tip**: the **▶** button (at the top of the visual) and **double-clicking** a ridge (focus mode) are on by default so you can try them. These are ★ features: without a key, a watermark appears while you use them, then disappears.

## Troubleshooting

| What you see | Likely cause | Solution |
|---|---|---|
| The visual stays empty or asks for a measure in **Height** or a field in **X axis** | A required field is missing, or the measure is blank for the current filters | Fill in **X axis** and **Height**; check the filters on the page and in the **Filters** pane |
| The ridges are flat or all identical | With **Height scale** = *Shared by all ridges*, a ridge with small variations looks flat | Switch to *Per ridge* (the color keeps the real values) or set **Baseline** to *Minimum ★* |
| Warning "several values per X on a ridge: averaged" in edit mode | The **Ridge** field is missing or too broad: several rows fall on the same X | Put the year (or the right level of detail) in **Ridge** |
| Too many ridges, unreadable | Too many ridges for the height of the visual | Increase **Overlap (%)**, set **Show 1 label every N**, or use **Keep N ridges (0 = all) ★** or **Scroll when crowded ★**. Beyond 500 ridges, the visual draws no more and says so in edit mode |
| Months appear in alphabetical order | The month text column has no sort order | **Column tools › Sort by column** › month number |
| All ridges run from January to December even though X contains dates over several years | A date in **X axis** is always converted to the day of the year | This is intended; for a period spanning two years, use a numeric "day of the season" column |
| A slicer makes the other years disappear | The slicer **filters** the visual | Set the slicer's interaction to **Highlight** ([how-to guide "you are here"](/en/tutorials/ridgeline-plume-cas-pratiques)) |
| A single click doesn't open focus | Focus opens with a double-click; a single click filters the other visuals | Double-click, or change **Focus mode ★ › Open focus with** |
| The "Premium preview" watermark appears | A ★ option is selected or a ★ field is filled in without a valid key | Paste your key in **Plume Studio License › License key**, or go back to the free settings |
| In a PDF export, the black background of the *Unknown Pleasures* or *Neon* styles disappears | Version older than 1.8: Power BI Desktop's PDF export ignored that background | Update the visual (since 1.8, the background is drawn inside the visual); otherwise, add a black background to the report page (**Format page › Canvas background**) |

## Key takeaways

- One row per ridge and per X, a column in **Ridge**, a column in **X axis**, a measure in **Height**: your ridgeline is ready.
- **Overlap (%)** and **Height scale** do most of the work; *Shared by all ridges* keeps the ridges comparable.
- For a distribution, it's up to you to count the values per bin: X = bin, Height = share of observations.
- Clicking filters the report for free; double-clicking opens focus ★.
- Reference, animation and annotations ★ turn the chart into a story.

## Learn more

- [Ridgeline Plume: 8 how-to guides (Unknown Pleasures, normals, animation…)](/en/tutorials/ridgeline-plume-cas-pratiques): recipes for everyday needs.
- [Ridgeline Plume: every field and setting explained](/en/tutorials/ridgeline-plume-champs-et-reglages): each field well and each setting.
- [Getting started with Plume visuals](/en/tutorials/bien-demarrer-visuels-plume): installation, license, styles and settings shared by all visuals.
- The visual's page: [Ridgeline Plume](/en/visuals/ridgeline-pulse). A question? [Support](/en/support).
