# Pie charts

> Page: https://docs.plotwork.dev/pie-charts. Index of every page: https://docs.plotwork.dev/llms.txt

A pie chart shows how one total splits into parts: traffic by source, spend by team, bugs by cause. Plotwork draws it as a donut, with the total in the hole, a label on a thin line for each big slice, and a legend for the small ones. It is for anyone who has a few shares of one whole, and for an agent that has been asked to draw them without making the chart lie.

## TL;DR

| Question | Answer |
|---|---|
| What is it for? | A few shares of one whole: where visits come from, where the money goes, what caused the bugs. Not for comparing values that are not parts of a whole, and not for ranking shares that are close in size. |
| How do I start one? | Write `pie "Title"`, then one `slice "Name" 42` line for each share. The numbers can be anything (visits, dollars): the ring scales them to a full turn. |
| What does the picture show? | A ring of rounded segments with a small gap between them, the total in large type in the hole with a caption under it, and a pill with the name, the value, and the share beside each slice. |
| What do I never choose? | A color. The slices take the tones of the theme in a fixed, color-blind-safe order. You may choose a tone for a slice, and a slice named `Other` is grey. |
| How is it kept honest? | Largest first, clockwise from the top. The percentages add up to exactly 100. Lint warns past 6 slices, for slices too close in size to rank by eye, and for values that are not parts of a whole. |
| What does Mermaid convert? | `pie`, with `showData`, a title, and `"Label" : value` lines. See [From Mermaid](#from-mermaid). |
| How big can it be? | At most 30 slices. Use `fold=` to merge the smallest into one `Other` slice. |

## Ask your agent

```text
Use Plotwork to draw a pie chart of where the visits to our docs came from last month. Search 18,420, Direct 11,960, Social 6,310, Email 4,180, Referral 2,140, Paid 1,490. Put an icon on each slice and call the total "Visits in March".
```

```text
Use Plotwork to draw a donut of our cloud spend in dollars by service: compute 48,200, storage 21,400, network 12,900, databases 9,800, monitoring 3,100, queues 1,400, email 900, and DNS 300. Keep five slices and merge the smallest into Other.
```

## Example

Six shares of one total. The slices are in order of size, clockwise from the top, and each one takes the next tone. Every slice is big enough to be named beside the ring.

**Diagram source**

```diagram
pie "Where visits come from" total="Visits in March" desc="The share of one month's visits to the docs by the channel that sent them: search brings the most, then people who typed the address."

slice "Search"    18420  icon=lucide:search
slice "Direct"    11960  icon=lucide:globe
slice "Social"     6310  icon=lucide:share-2
slice "Email"      4180  icon=lucide:mail
slice "Referral"   2140  icon=lucide:link
slice "Paid"       1490  icon=lucide:megaphone
```

*Picture: Where visits come from: 6 slices of 44,500 in all, the largest Search at 42%. The share of one month's visits to the docs by the channel that sent them: search brings the most, then people who typed the address.*

**Text description**

**Slices, largest first:**

- Search: 18,420 (42%)
- Direct: 11,960 (27%)
- Social: 6,310 (14%)
- Email: 4,180 (9%)
- Referral: 2,140 (5%)
- Paid: 1,490 (3%)

## The language

One statement to a line. Text is always in double quotes, options are `key=value`, and `#` starts a comment.

| Statement | Meaning | Example |
|---|---|---|
| `pie "Title" unit=<text> total=<text> sort=<order> values=<on\|off> fold=<n> labels=<place> desc="<text>"` | The header. Every option is optional, and so is the title. | `pie "Where visits come from" total="Visits"` |
| `slice "Name" <number> tone=<tone> icon=<icon>` | One share of the whole: its name, then its number, then the options. | `slice "Search" 18420 icon=lucide:search` |
| `desc "<text>"` | The plain-language description. The same as `desc=` on the header. | `desc "Where one month of visits came from."` |

A slice has no id. Its name is its identity, compared in any case, so a name used twice is `E130`. The number is zero or more, written as digits with an optional fraction. A sign, a comma, a percent sign, and an exponent are errors, and the hint says what to write: `42`, not `42%` or `1,200`.

### Options

| Option | On | Values | Default |
|---|---|---|---|
| `unit=` | header | Up to 12 characters, such as `%`, `$`, `ms`, `visits` | none |
| `total=` | header | Text for the caption under the total in the hole | `Total` |
| `sort=` | header | `desc` (largest first), `written` | `desc` |
| `values=` | header | `on`, `off` | `on` |
| `fold=` | header | A whole number from 2 to 12 | no folding |
| `labels=` | header | `outside`, `legend` | `outside` |
| `desc=` | header | Quoted text | none |
| `tone=` | slice | `neutral`, `blue`, `violet`, `aqua`, `orange`, `green`, `amber`, `red` | the next tone of the order below |
| `icon=` | slice | Any bundled icon, such as `lucide:globe`, or `none` | none |

### Units

A unit is written after each number, set apart by a space when it starts with a letter or a digit: `42%`, `42 ms`, `42 visits`. A currency sign (`$`, `€`, `£`, `¥`) goes before it: `$42`. The total in the hole takes the same unit.

### Percentages

Every slice has a share, and the shares are written as whole percentages that add up to exactly 100. Each share is rounded down and the points left over go to the biggest fractions, the earlier slice first on a tie, so a chart never prints 99 or 101. A share too small to round to 1 is written `<1%`. The size of a slice in the ring always comes from its exact share.

A label writes the value and the share, `5,208 visits (42%)`. With `values=off` it writes the share alone. When the unit is `%` and the values add up to 100, the value already is the share, so a label writes it once: `62.5%`.

### Folding the small slices

`fold=5` draws at most five slices: the largest four stay and the rest are merged into one grey slice named `Other`, which is always last. The text description names what was merged, so folding loses nothing for a reader who needs it. A slice you named `Other` joins the merge and lends it its tone, so there is never a second one.

**Diagram source**

```diagram
pie "Cloud spend by service" unit="$" total="Spend in Q3" fold=5

slice "Compute"    48200  icon=lucide:cpu
slice "Storage"    21400  icon=lucide:database
slice "Network"    12900  icon=lucide:network
slice "Databases"   9800
slice "Monitoring"  3100
slice "Queues"      1400
slice "Email"        900
slice "DNS"          300
```

*Picture: Cloud spend by service: 5 slices of $98,000 in all, the largest Compute at 49%.*

**Text description**

**Slices, largest first:**

- Compute: $48,200 (49%)
- Storage: $21,400 (22%)
- Network: $12,900 (13%)
- Databases: $9,800 (10%)
- Other: $5,700 (6%), made of Monitoring, Queues, Email, DNS

### Where the names go

With `labels=outside`, the default, each slice of 3% or more is named in a pill beside the ring, joined to its slice by a thin line. The pills stand in a column on each side and are spread so that none touches another. Slices under 3% are named in a legend under the ring, with a dot in their tone, so nothing is left unnamed.

With `labels=legend`, every slice is named in the legend and the picture has no lines. It suits a narrow column, and a chart of shares that are all small.

**Diagram source**

```diagram
pie "Time spent in a sprint" unit="%" total="Share of the sprint" labels=legend sort=written

slice "Building"   52
slice "Reviewing"  21
slice "Meetings"   14
slice "Waiting"     8
slice "Planning"    5
```

*Picture: Time spent in a sprint: 5 slices of 100% in all, the largest Building at 52%.*

**Text description**

**Slices, in the order written:**

- Building: 52%
- Reviewing: 21%
- Meetings: 14%
- Waiting: 8%
- Planning: 5%

### Colors

The slices take `blue`, `orange`, `aqua`, `violet`, `amber`, `green`, `red`, and `neutral` in turn. These are the validated hues of the Plotwork data palette, arranged so that neighbours differ the most, with grey last because grey reads as the rest. A `tone=` on a slice keeps that tone and the others take the next ones that nobody has claimed, so two slices never share a hue until all eight are in use. A chart with an `Other` slice keeps grey for it, and the colors of the others repeat only after seven. Nobody writes a color value: the theme owns every color, in light and in dark, and every segment keeps at least 3:1 against the background.

## Limits and warnings

### Honest charts

A pie chart is the right picture for a few shares of one whole and a poor one for almost anything else. Plotwork warns instead of drawing a chart that misleads. A warning never stops the drawing.

| Warning | When it fires | What to do |
|---|---|---|
| `W200`, more than 6 slices | The colors stop being easy to tell apart. | Merge the smallest with `fold=`, group them into fewer categories, or draw a bar chart or a table. |
| `W200`, slices that cannot be ranked | Slices within 3 points of the largest of them, and less than a quarter bigger than the smallest, such as 25% and 24%. Slices under 3% are left out. | If the reader has to rank them, draw a bar chart. If the point is that they are about equal, say so in `desc=`. |
| `W200`, values that are not a whole | A single slice, or `unit="%"` with values that do not add up to 100. The hint says what is missing. | Add the missing share as a slice named `Other`, or fix the values. |
| `W200`, a slice of 0 | It takes no angle and is not drawn. | Remove the slice. |
| `W200`, a hairline slice | A slice under 1% of the ring. | Merge it with `fold=`, or leave it out. |
| `W203` | A name was cut with an ellipsis to fit its pill, or the caption or the total was cut to fit the hole. | Shorten the name or the caption. |

### Limits

| Limit | Value | What happens past it |
|---|---|---|
| Slices written | 30 | `E140` before anything is drawn, with the advice to group them. |
| A value | 1,000,000,000,000 | `E100`, at the number. |
| `fold=` | 2 to 12 | `E136`, at the number. |
| A unit | 12 characters | `E136`, at the value. |
| Label width | 280px | The name is cut with an ellipsis, with `W203`. |

### Errors

Every mistake comes back as a result with a code, a line, a column, and a hint. All the codes are the shared ones.

| Code | When it fires | Fix |
|---|---|---|
| `E100` | A slice with no number, a word or quoted text where the number goes, a negative value, a percent sign or a thousands separator, a name not in quotes, an empty name, or a chart with no slices. | Read the hint, which gives the line to write. |
| `E101` | A name that is never closed. | Close it with a double quote. |
| `E110` | An unknown statement. | Use `slice` or `desc`. |
| `E121`, `E122` | An unknown tone or icon. | The hint names the nearest. |
| `E130` | A name already used by another slice, in any case. | Add the two values into one slice, or tell them apart in the name. |
| `E135`, `E136` | An unknown option, or a bad value for `sort=`, `values=`, `labels=`, `fold=`, or `unit=`. | The hint lists the choices. |
| `E140` | More than 30 slices. | Group the small ones before writing them. |

## From Mermaid

Mermaid `pie` converts to a pie chart. Ask your agent to convert it, or use the `convert_mermaid` tool. The [migration guide](https://docs.plotwork.dev/migrating-from-mermaid.md) covers the converter in full.

```mermaid-source
pie showData title Browser share
    "Chrome" : 65.4
    "Safari" : 18.7
    "Edge" : 5.2
    "Firefox" : 2.8
    "Chrome" : 9
    "Other" : 7.9
```

The converter reports the repeated slice (`M209`) and keeps the order Mermaid was written in. A chart that also carries an `%%{init}%%` directive or front matter `config:` for `textPosition` converts the same way, and the converter reports the settings it dropped (`M200`):

```plotwork
pie "Browser share" sort=written

slice "Chrome" 65.4
slice "Safari" 18.7
slice "Edge" 5.2
slice "Firefox" 2.8
slice "Other" 7.9
```

| Mermaid | Plotwork | Report |
|---|---|---|
| `pie showData title X` | `pie "X" sort=written` | none |
| `pie title X`, with no `showData` | `pie "X" sort=written values=off`, because Mermaid then shows only the shares | none |
| `showData` and `title X` on lines of their own | The same | none |
| `"Label" : 42.96` | `slice "Label" 42.96`, in the order written | none |
| A value of 0 | Kept. Lint then says it is not drawn. | none |
| A repeated label, in any case | The first is kept and the later one is dropped. | `M209` |
| An empty label | Dropped. | `M216` |
| `<br/>`, HTML, and Markdown marks in a label | Removed. A line break becomes a space. | `M205` |
| Front matter `title:` and `accTitle:` | The title. | none |
| `accDescr:` | `desc=` | none |
| `%%{init}%%` and front matter `config:`, such as `textPosition` | Dropped. | `M200` |
| `%%` comments | Dropped. | none |
| A chart with no title | No title is written. | `M214` |
| A negative value, a value that is not a number, a label with no quotes, or a line that is not a slice | Nothing is converted, or the line is skipped when the conversion is lenient. | `M110`, or `M218` |
| More than 30 slices | Nothing is converted. | `M102` |
| A chart with no slices | Nothing is converted. | `M103` |

## See also

| Doc | Why |
|---|---|
| [Writing diagrams](https://docs.plotwork.dev/writing-diagrams.md) | The flow, sequence and schema languages, and the rules every kind shares |
| [Examples to copy](https://docs.plotwork.dev/examples.md) | Finished diagrams with the prompt that gets an agent to write each one |
| [Migrating from Mermaid](https://docs.plotwork.dev/migrating-from-mermaid.md) | Convert existing Mermaid diagrams, and what is dropped |
| [Gantt charts](https://docs.plotwork.dev/gantt-charts.md) | A plan drawn as tasks along a calendar |
| [Timelines](https://docs.plotwork.dev/timelines.md) | Events along a time axis |
| [Mind maps](https://docs.plotwork.dev/mind-maps.md) | A central idea and the branches that grow from it |
| [Language reference](https://docs.plotwork.dev/reference/language.md) | Every kind, node type, option and diagnostic |
| [Diagram kinds](https://docs.plotwork.dev/reference/language/kinds.md) | The kinds Plotwork draws and the header of each |
