🎨 Transform Figma mockups into production-ready Dash apps. Join us November 10. Save your spot.

Chris Parmer

Chris Parmer

October 24, 2026

Ternary Plots - A Complete Guide

TL;DR

  • A ternary plot draws items that split into three parts adding up to 100% as points in a triangle. Each corner is 100% of one part, so a point's position shows the whole split at once.
  • Ternary plots are also known as ternary diagrams, ternary graphs, triangle plots and Gibbs triangles, and are similar to 100% stacked bar charts and scatter plots.
  • Use one for many items with a three-way split (electricity mixes, vote shares, soil, diets, budgets) or for one item's split changing over time, drawn as a trail.
  • Use 100% stacked bars instead when you have about a dozen items and readers need exact values, and a line chart when only one of the shares matters.
  • Any coding agent can make one with Plotly in a minute. In Python it's px.scatter_ternary(df, a=..., b=..., c=...).

What is a ternary plot?

Ternary plots look like this:

Ternary plot of 154 countries' electricity mix in 2024 with nuclear at the top, fossil bottom left and renewables bottom right, bubbles sized by generation and colored by continent. China (10,087 TWh) sits at 62% fossil, the US at 58% fossil and 18% nuclear, France near the nuclear corner at 68%, and Brazil and Norway near the renewables corner

Data: Ember, Yearly Electricity Data, 2024.

How do you read a ternary plot? In the example above, notice these things:

  • Each bubble is one country, placed by how its electricity splits between fossil fuels, nuclear and renewables. Its area is how much electricity it generated, which is why China is by far the biggest bubble.
  • Each corner is 100% of one source, so the closer a bubble sits to a corner, the more of its power comes from that source. France sits high up toward the nuclear corner, while Brazil and Norway sit near the renewables corner at the bottom right.
  • The bottom edge means no nuclear at all. Most countries generate no nuclear power, so they line up along that edge, from Saudi Arabia near the fossil corner to Norway at the renewables corner, with Germany at 59% renewables in between.
  • The dotted lines mark 50%, which splits the triangle into regions where one source makes most of a country's power. Only France and Slovakia are above the nuclear line, while the United States and China are in the fossil region.
  • To read exact values, follow the gridline through a point to the edge that carries its tick labels instead of dropping straight down to the nearest edge, because ternary gridlines meet the edges at 60 degrees.

It's often used for charts like these:

The USDA soil texture triangle with clay at the top, sand bottom left and silt bottom right, its 12 classes drawn as filled regions shaded by their share of mapped US soils. Silt loam (24.9%), loam (22.3%) and sandy loam (21.8%) are the darkest; small dots show soils on a 1% grid sized by area

A classification drawn as regions. Soil scientists name soils by their share of sand, silt and clay, and weighted by area, three loams cover 69% of the mapped soil in the United States. Data: USDA NRCS SSURGO, via Soil Data Access (398,308 soil horizons, 1.45 billion acres).

Ternary plot of 21,463 sediment samples from the USGS East Coast Sediment Texture Database with clay at the top, sand bottom left and silt bottom right, each sample a small dot colored by its class in Shepard's sand-silt-clay classification. Sand (50.6%) fills the sand corner, and silty sand, sandy silt, clayey silt, silty clay and sand-silt-clay form bands across the rest of the triangle

Sediment classified by grain size. Geologists sort seafloor and lake sediments by their share of sand, silt and clay, usually with Shepard's 1954 classification, and half of the 21,463 samples in the USGS East Coast database are sand. Data: USGS East Coast Sediment Texture Database (Poppe and others, 2014).

Ternary plot with a trail for each of nine countries from 2000 (hollow marker) to 2025 (filled marker). The UK's trail runs from 75% fossil toward renewables, ending at 36% fossil and 52% renewables; France stays near the nuclear corner; Japan's trail jumps toward the fossil corner in 2012; Brazil stays near the renewables corner

A split changing over time. The UK's trail shows fossil fuels falling from 75% to 36% of its electricity between 2000 and 2025, while Japan's jumps toward the fossil corner after its reactors shut down in 2012. Data: Ember, Yearly Electricity Data, 2000-2025.

Reading exact values takes one more step. Follow the gridline through a point to the edge that carries the matching tick labels, as in this reading of the world's electricity in 2024 (59% fossil, 9% nuclear and 32% renewables):

A ternary plot with one black point for the world's electricity in 2024 at 59% fossil, 9% nuclear and 32% renewables. Each axis's line, title and tick labels share a color (purple nuclear, dark gray fossil, green renewables), and a dotted line in each color runs from the point along that axis's gridline to the edge carrying its labels

A short history

J. Willard Gibbs described a mixture of three substances as a point in an equilateral triangle in "On the Equilibrium of Heterogeneous Substances" (1876), which is why chemists still call it the Gibbs triangle and use it for three-component phase diagrams. In 1926 the mathematician Bruno de Finetti used the same triangle for genotype frequencies in a paper in Metron, and showed that every population in Hardy-Weinberg equilibrium falls on one curve:

De Finetti's diagram redrawn with Plotly: a ternary plot with AA at the bottom left, aa at the bottom right and the heterozygous Aa at the top, and a blue curve from corner to corner that peaks at 50% Aa when the allele frequency p is 0.5, with points marked at p = 0.1, 0.3, 0.5, 0.7 and 0.9. The curve is computed from the formula, not data

Geologists later classified igneous rocks with Albert Streckeisen's QAP triangle (Streckeisen, 1976), soil scientists adopted the texture triangle shown above, and John Aitchison's work on compositional data (Aitchison, 1982) explained why shares that must add up to 100% need their own statistics.

Alternatives to a ternary plot

Here's the same electricity data for the 12 largest generators drawn six ways. Some are better for the question, some worse, some just different:

The electricity mix of the 12 largest generators in 2024 drawn six ways: a ternary plot, 100% stacked bars sorted by fossil share from France to Saudi Arabia, a Marimekko chart whose bar widths are total generation with China the widest, a scatter of fossil share against renewables share, twelve small pie charts, and a dot plot with three dots per country
  • 100% stacked bar chart (better for a dozen items and exact values). One bar per country, sorted by fossil share, makes it easy to read that Saudi Arabia gets 98% of its electricity from fossil fuels and France 5%. Past about 20 items the bars turn into a wall, and showing change over time needs one chart per item.
  • Marimekko chart (better when size matters too). The same stacked bars with widths set by total generation show that China's 10,087 TWh dwarfs everyone else, which shares alone hide. See our Marimekko chart guide.
  • Scatter plot of two shares (works too). Fossil against renewables uses ordinary x and y axes, and nuclear is the gap below the diagonal. It works when one of the three parts matters less than the others.
  • Small-multiple pie charts (worse). One pie per country shows each split, but people compare angles across separate pies poorly, and 12 pies take far more space than 12 points.
  • Dot plot (different). Three dots per country on one shared percent scale give exact values for every part, at the cost of the clusters a ternary plot shows.

The ternary plot is the only one of these that still works with 154 countries, or with one country's split over 25 years.

How to make a ternary plot

With AI

ChatGPT, Claude Code, GitHub Copilot, Cursor and other AI tools are excellent at writing Plotly code. Name Plotly in the prompt, say which part goes in which corner and what size and color mean, and list the checks you want:

Make a plotly ternary plot from plant_mix.csv (columns: plant, region, coal_mwh, gas_mwh, clean_mwh).
- Normalize each row to percent; assert every row has a positive total and print rows that don't.
- Clean power at the top (a), coal bottom left (b), gas bottom right (c), sum=100.
- Axis titles in plain words, ticksuffix="%", light gray gridlines, white background.
- Bubble area = total MWh (sizemode="area"), one color per region. Label the 10 largest plants.
- Shade the region where coal is at least 50% with fill="toself" in light gray.
- If all points sit in one part of the triangle, set the axis minimums to zoom and say so in the subtitle.
- Hover shows all three shares. A title that states the main takeaway.
- Save it as ternary.html and as a PNG at 2x scale.

The normalization check is worth keeping in every ternary prompt, because Plotly places any row in the triangle, even one with missing parts.

With Plotly Studio

Plotly Studio is a desktop app where you point an AI at a dataset and it builds charts and a Dash app around your questions. Ask for a ternary plot the same way:

Show a ternary plot of each country's electricity mix with nuclear at the top, fossil at the bottom left and renewables at the bottom right, in percent. Size the bubbles by total generation, color them by continent and label the 12 largest countries. Add a year slider.

Make a ternary plot in Python or JavaScript

This is the code AI tools write under the hood. In Python, Plotly Express takes one row per item and a column for each part, and divides each row by its total, so raw amounts work:

import plotly.express as px
df = px.data.election() # Montreal 2013 mayoral election by district
fig = px.scatter_ternary(df, a="Joly", b="Coderre", c="Bergeron",
color="winner", size="total", hover_name="district")
fig.update_ternaries(sum=100, aaxis_ticksuffix="%", baxis_ticksuffix="%", caxis_ticksuffix="%")
fig.show()

In JavaScript, plotly.js takes a scatterternary trace with the three parts in a, b and c. These are 2024 TWh from Ember:

<div id="chart"></div>
<script src="https://cdn.plot.ly/plotly-4.1.1.min.js"></script>
<script>
Plotly.newPlot("chart", [{
type: "scatterternary",
mode: "markers+text",
text: ["France", "Germany", "Brazil"],
textposition: "top center",
a: [380, 0, 16], // nuclear
b: [29, 205, 79], // fossil
c: [153, 291, 651], // renewables
marker: {size: 14}
}], {
ternary: {
sum: 100,
aaxis: {title: {text: "Nuclear"}, ticksuffix: "%"},
baxis: {title: {text: "Fossil"}, ticksuffix: "%"},
caxis: {title: {text: "Renewables"}, ticksuffix: "%"}
}
});
</script>

To draw a region, such as a soil texture class or "more than half fossil", add another trace with the region's corners in a, b and c, mode: "lines" and fill: "toself". For a trail, sort by time and use mode: "lines+markers".

Share it

Every Plotly chart has a Share chart button (the cloud icon in its toolbar) that uploads it to Plotly Cloud and gives you a link. Only you can see it until you change its visibility.

For a live app, put the chart in a Dash app and publish it with the Plotly Cloud CLI. Coding agents can run these commands for you:

pip install "dash[cloud]"
plotly user login
plotly app publish

If your data has to stay in your own cloud or data center, publish to Dash Enterprise instead.

Dos and don'ts

Most of the work on a published ternary plot is in the axes and the labels. Here are the 30 largest electricity generators of 2024 both ways, with the same bubbles and colors.

Don't leave column names such as nuclear_twh as axis titles, show the shares as fractions from 0 to 1, or force a label onto every point until they overlap:

A ternary plot of the 30 largest electricity generators as blue bubbles sized by generation, with the axis titles nuclear_twh, fossil_twh and renewables_twh, ticks from 0 to 1, and a label on every country, so the names along the bottom edge such as Egypt, Thailand, Malaysia, Australia and Vietnam overlap into an unreadable row

Do show shares in percent with plain axis titles, and label only the countries readers will look for, leaving the rest to the hover:

The same 30 countries with percent ticks, the axis titles Nuclear, Fossil and Renewables, blue bubbles sized by total generation on a white background, and direct labels for China, the United States, India, Russia, Japan, Brazil, Canada, France and Germany

Use size and color for one other thing

Position already shows the three shares, so size and color are free to say something else. Here are four options on the same data.

Plain points. Positions only, which is enough when every item matters equally.

The 30 largest generators as equal-sized blue points in the ternary plot

Size by amount. Bubble area adds the total generation that shares hide, so China (10,087 TWh) and Norway no longer look alike.

The 30 largest generators as blue bubbles sized by total generation, with China (10,087 TWh), the United States (4,391 TWh) and India (2,037 TWh) labeled

Color by group. One hue per continent, which works for five or six groups and shows that most of Europe sits away from the fossil corner.

The 30 largest generators sized by generation and colored by continent: Asia blue, Europe orange, North America green, South America yellow, Africa purple and Oceania pink, with a legend

Highlight one story. The 8 countries that made most of their electricity from renewables are green, the rest gray, and the majority-fossil and majority-renewables regions are shaded.

The 30 largest generators with Brazil, Canada, Germany, the United Kingdom, Spain, Italy, Sweden and Norway in green inside a shaded majority-renewables region, every other country in gray, and the majority-fossil region shaded gray

Checklist

Do

  • Write a title that states the takeaway, such as "27 US states made at least half their electricity from coal in 2001, and 5 did in 2025".
  • Use sum=100 and ticksuffix="%" so ticks read 20% instead of 0.2.
  • Name the axes in plain words, and color-code them when the audience is new to ternary plots.
  • Zoom in with aaxis.min, baxis.min and caxis.min when the data uses a small part of the triangle, and say so in the subtitle.
  • Draw reference lines and regions (50% lines, ties, classes) with a Scatterternary trace and fill="toself".
  • Put all three values in the hover with hovertemplate.
  • Use trails (mode="lines+markers") for change over time, with a hollow marker at the start.

Don't

  • Label every point, because labels pile up along the edges where items with a zero share sit.
  • Give every item its own color, because thirty colors can't be told apart.
  • Read values by dropping a perpendicular to an edge; follow the gridlines.
  • Plot three parts that don't add up to the whole without saying what was left out.
  • Use a ternary plot for a few items that readers need to compare exactly.

Options to customize

These are the go.Scatterternary (and px.scatter_ternary, px.line_ternary) options and layout.ternary settings that matter most. The full list is in the Plotly ternary plots documentation.

  1. a, b, c: the three parts for the top, bottom-left and bottom-right corners. Raw amounts are fine, Plotly normalizes them.
  2. ternary.sum: the total the axes show (1 by default). Set it to 100 for percent ticks.
  3. sum (trace): the total each point is normalized to; match it to ternary.sum when your values are already shares.
  4. aaxis, baxis, caxis .title and .ticksuffix: axis titles and tick labels, in plain words and with %.
  5. aaxis.min, baxis.min, caxis.min: raise a minimum to zoom into a smaller triangle when the data sits in one part.
  6. color, linecolor, gridcolor, tickvals (on each axis): color-code axes for new readers and hide the corner ticks.
  7. ternary.bgcolor, ternary.domain: the background and the triangle's place in the figure, for several triangles side by side.
  8. mode: markers, lines, text or a combination; lines+markers for trails, text for labels.
  9. marker.size, sizemode, sizeref: bubble size, to add the absolute amount that shares hide.
  10. marker.color, colorscale, opacity: color by group or by a value such as the year, and transparency for dense data.
  11. marker.symbol, marker.angleref: marker shape; angleref="previous" points arrows along a line for before and after.
  12. fill="toself", fillcolor: fill a closed polygon for regions and classifications.
  13. line.dash, line.width: reference lines such as ties and 50% lines.
  14. text, textposition, cliponaxis: direct labels, and whether they can spill past the triangle.
  15. hovertemplate, customdata: hover text with %{a}, %{b} and %{c}.
  16. subplot: which ternary, ternary2 and so on a trace belongs to, for small multiples.

More ternary plot examples

Eleven more ternary plots built from real public data, each with its source, the technique that makes it work and a prompt to rebuild it.

1. US states moving off coal

Ternary plot with an arrow for each US state from its 2001 to its 2025 electricity mix, with coal bottom left, gas bottom right and clean power at the top. Almost every arrow leaves the shaded majority-coal region; Iowa's arrow points toward clean power, Pennsylvania's and Ohio's toward gas, and West Virginia and Kentucky stay near coal

In 2001, 27 US states made at least half their electricity from coal, and in 2025, 5 did. The arrows show where they went: Iowa from 85% coal to 63% clean power, mostly wind, and Pennsylvania from 57% coal to 59% gas. Data: Ember, US Electricity Data (from EIA-923), 2001 and 2025.

Tip: marker.symbol=["circle", "arrow"] with angleref="previous" turns a two-point line into an arrow that points along the move.

Get the data from Ember's US Electricity Data (ember-energy.org, compiled from EIA-923), 2001 and 2025
and shape it into a table
(columns: state, state_code, year, total_twh, coal_twh, gas_twh, clean_twh; 50 states and DC;
gas includes other fossil; clean = nuclear + renewables).
Build a plotly ternary plot with one arrow per state from 2001 to 2025: clean at the top, coal bottom left, gas bottom right.
- Each state is a Scatterternary line with marker.symbol ["circle", "arrow"] and angleref="previous".
- Gray for all states, six states in color with labels (Iowa, Pennsylvania, Ohio, Texas, West Virginia, Kentucky).
- Shade the region where coal >= 50% with fill="toself".
- Title with the number of majority-coal states in each year.

2. Germany, month by month

Zoomed ternary plot of Germany's monthly electricity mix from January 2015 to June 2026, with fossil bottom left, wind and solar bottom right and other low-carbon at the top. Points colored from light blue (2015) to dark blue (2026) drift from the fossil side toward wind and solar; June 2025 is labeled at 59% wind and solar

Fossil fuels made 55% of Germany's electricity in 2015 and 40% in 2025. Month by month, the cloud of 138 points drifts toward wind and solar, which peaked at 59% of generation in June 2025. Data: Ember, Monthly Electricity Data, January 2015 to June 2026.

Tip: setting aaxis.min, baxis.min and caxis.min zooms into a smaller triangle, and a sequential color by year turns 138 points into a visible drift.

Get the data from Ember's Monthly Electricity Data (ember-energy.org) for Germany since January 2015
and shape it into a table
(columns: date, total_twh, fossil_twh, wind_solar_twh, wind_twh, solar_twh, other_twh;
other = nuclear + hydro + bioenergy + other renewables).
Build a plotly ternary plot of every month: other low-carbon at the top, fossil bottom left, wind and solar bottom right.
- Markers colored by year on a light-to-dark blue scale with a colorbar; a thin gray line joining months.
- Zoom: fossil axis min 20%, the other two min 5%; say so in the subtitle.
- Label the month with the highest wind and solar share.
- Title with the fossil share in 2015 and 2025 (full years).

3. Who holds US federal debt

Zoomed ternary plot of who held US federal debt held by the public each quarter from 1970 to 2026: the Federal Reserve at the top, foreign and international investors bottom left, other US holders bottom right. The path runs from 1970 near other US holders toward foreign holders, peaking at 49% in Q2 2008, then toward the Fed at 26.5% in Q4 2021, and back to Q1 2026 at 30% foreign

Foreign investors held 49% of US federal debt held by the public in 2008 and 30% in early 2026, while the debt grew from $5.3 trillion to $31.5 trillion. The Federal Reserve's share peaked at 26.5% in late 2021, after its pandemic purchases. Data: US Treasury via FRED (FYGFDPUN, FDHBFRBN, FDHBFIN), 1970-2026.

Tip: label only the turning points on a long trail with a hollow ring marker and text, and let the color scale carry the years.

Get the data from FRED (fred.stlouisfed.org) series FYGFDPUN (federal debt held by the public), FDHBFRBN
(held by Federal Reserve Banks) and FDHBFIN (held by foreign and international investors), quarterly since 1970
and shape it into a table
(columns: date, public_bn, fed_bn, foreign_bn, domestic_other_bn = public - fed - foreign; US$ billions).
Build a plotly ternary trail: Fed at the top, foreign bottom left, other US holders bottom right.
- Markers colored by year on a sequential scale with a colorbar; thin gray connecting line.
- Zoom with caxis.min=30; say so in the subtitle.
- Ring and label the first quarter, the foreign peak, the Fed peak and the latest quarter.
- Title with the foreign share at its peak and now.

4. What the rich and the rest own

Ternary plot of the composition of US household assets by wealth group from 1989 to 2026, with stocks and private businesses at the top, real estate bottom left and everything else bottom right. The top 1% trail climbs to 68% stocks and businesses, the next 9% sits at 41%, the next 40% at 16% and the bottom 50% at 5%, near the real estate edge

The top 1% of US households now hold 68% of their assets in stocks and private businesses, up from 46% in 1989. For the bottom half, that share is 5%, and real estate and everything else (cars, deposits, pensions) make up the rest. Data: Federal Reserve, Distributional Financial Accounts, 1989 Q3 to 2026 Q2.

Tip: four trails in four parts of the triangle tell a story by position alone, so labels can replace the legend.

Get the data from the Federal Reserve's Distributional Financial Accounts (federalreserve.gov, dfa.zip,
dfa-networth-levels.csv), quarterly since 1989
and shape it into a table
(columns: date, group [Top 1%, Next 9%, Next 40%, Bottom 50%], assets_bn, real_estate_bn,
business_bn = corporate equities and mutual funds + unincorporated businesses, other_bn = the rest).
Build a plotly ternary plot with one trail per wealth group: stocks and businesses at the top,
real estate bottom left, everything else bottom right.
- One color per group, hollow marker at the first quarter, label with the latest share at the end.
- Check that the three parts add up to assets for every row.
- Title with the top 1%'s stocks and businesses share then and now.

5. The federal budget since 1962

Zoomed ternary plot of US federal outlays by category each fiscal year from 1962 to 2025: net interest at the top, discretionary bottom left, mandatory bottom right. The path runs from 1962 near the discretionary side toward mandatory spending, rises toward interest around 1991, drops in 2021 and climbs back toward interest in 2025

Discretionary spending fell from 68% of federal outlays in 1962 to 27% in 2025, as mandatory programs such as Social Security, Medicare and Medicaid grew to 59%. Net interest climbed back to 13.8% in 2025, from 5.2% in 2021. Data: OMB Historical Tables, FY2027 budget, Table 8.1.

Tip: year labels every decade along the trail are enough to anchor the timeline without a colorbar.

Get the data from the OMB Historical Tables, FY2027 budget, Table 8.1 (whitehouse.gov/omb), actual years 1962-2025
and shape it into a table
(columns: year, total_bn, discretionary_bn, mandatory_bn, interest_bn; US$ billions).
Build a plotly ternary trail: net interest at the top, discretionary bottom left, mandatory bottom right.
- Markers colored by year on a light-to-dark blue scale; label 1962, 1970, 1980, 1991, 2000, 2010, 2021 and 2025.
- Zoom: discretionary and mandatory axes start at 20%.
- Assert the three categories add up to the total. Title with discretionary's share in 1962 and 2025.

Another way to see it: a 100% stacked area chart reads more easily as a timeline and shows that net interest's 13.8% in 2025 is the highest share since 1998, but the thin interest band at the top is harder to compare across decades than its distance from the ternary plot's edge.

100% stacked area chart of US federal outlays from 1962 to 2025: mandatory spending grows from about 26% to 59%, discretionary shrinks from about 68% to 27%, and net interest is 14% in 2025

6. What people die of, by country income

Zoomed ternary plot of deaths by broad cause from 2000 to 2023 for World Bank income groups: injuries at the top, communicable diseases bottom left, noncommunicable diseases bottom right. The low-income trail moves from 69% communicable toward noncommunicable, high-income countries sit near the noncommunicable corner, and every trail loops back toward communicable in 2020-2021

In low-income countries, communicable, maternal, perinatal and nutritional conditions fell from 69% of deaths in 2000 to 48% in 2023. The loops are COVID-19, which WHO counts as communicable: in high-income countries the communicable share went from 6% in 2019 to 18% in 2021. Data: WHO Global Health Estimates, 2000-2023.

Tip: an ordered blue scale for the income groups and a dashed black line for the world keep five trails readable without a legend.

Get the data from the WHO Global Health Estimates (who.int, GHE_REGIONS on the xMart API), 2000-2023
and shape it into a table
(columns: region [Low income, Lower-middle income, Upper-middle income, High income, World], year,
communicable, noncommunicable, injuries; deaths).
Build a plotly ternary plot with one trail per group: injuries at the top, communicable bottom left, noncommunicable bottom right.
- Light-to-dark blue by income, the world as a dashed black line; hollow marker at 2000, label at 2023.
- Zoom with caxis.min=20. Mention the COVID-19 loops in the subtitle.
- Title with the low-income communicable share in 2000 and 2023.

7. Population aging since 1960

Zoomed ternary plot of population by age group: 65 and over at the top, 0-14 bottom left, 15-64 bottom right. Gray bubbles show 217 countries in 2023; colored trails since 1960 show Japan rising to 30% over-65s, Italy and South Korea following, China and Brazil moving fast, and Nigeria and Niger barely moving from about 45% children. A dashed line marks where children and over-65s are equal

Japan went from 30% children and 6% over-65s in 1960 to 12% and 30% in 2023, and 48 countries now have more people over 65 than under 15. Nigeria and Niger have barely moved. Data: World Bank, World Development Indicators (UN World Population Prospects 2024), 1960-2023.

Tip: gray bubbles for every country in the latest year give the trails context without competing with them.

Get the data from the World Bank's World Development Indicators (SP.POP.0014.TO.ZS, SP.POP.1564.TO.ZS,
SP.POP.65UP.TO.ZS, SP.POP.TOTL), 1960-2023
and shape it into a table
(columns: country, iso3, region, year, pop, age_0_14, age_15_64, age_65_plus; percent of population).
Build a plotly ternary plot: 65+ at the top, 0-14 bottom left, 15-64 bottom right; zoom with caxis.min=45.
- All countries in 2023 as light gray bubbles sized by population.
- Trails since 1960 for Japan, South Korea, Italy, China, United States, Brazil, India, Nigeria and Niger, labeled at the end.
- A dashed line where 0-14 equals 65+. Title with Japan's 1960 and 2023 shares.

8. What 7,244 foods are made of

Ternary plot of 7,244 foods from USDA's database by share of calories from protein (top), carbohydrate (bottom left) and fat (bottom right), colored by food group. Meat and fish line the protein-fat edge, fruit, vegetables and grains crowd the carbohydrate corner, oils sit in the fat corner, and cod, whole egg, almonds, avocado, whole milk, black beans and banana are labeled

Of 7,244 foods in USDA's SR Legacy database, 3,182 get at least half their calories from carbohydrate, 1,822 from fat and 1,650 from protein. Meat and fish line the protein-fat edge with almost no carbohydrate, and cod is 92% protein. Data: USDA FoodData Central, SR Legacy.

Tip: small markers with opacity=0.45 turn overlap into density, so 7,244 points still read as shapes.

Get the data from USDA FoodData Central, SR Legacy (fdc.nal.usda.gov), nutrients protein (1003), fat (1004)
and carbohydrate by difference (1005)
and shape it into a table
(columns: fdc_id, food, category, protein_g, fat_g, carb_g, kcal_macro = 4*protein + 9*fat + 4*carb;
grams per 100 g; drop foods under 5 kcal and the Baby Foods and Restaurant Foods categories).
Build a plotly ternary plot of calorie shares: protein at the top, carbohydrate bottom left, fat bottom right.
- Group the 23 USDA categories into 8 food groups, one color each, "other" in gray drawn first.
- Marker size 5, opacity 0.45; label 7 everyday foods with ring markers.
- Title with the number of foods that get at least half their calories from each macronutrient.

9. The shape of big pharma's pipelines

Ternary plot of the 30 largest industry sponsors of clinical trials started in 2015-2025 by share of trials in phase 1 (bottom left), phase 2 (bottom right) and phase 3 (top), bubbles sized by number of trials and colored by headquarters region. Chong Kun Dang (80% phase 1) and Boehringer Ingelheim (68%) sit toward phase 1, Novartis (21% phase 1) and Akeso toward phase 2, AbbVie, Vertex and Sanofi toward phase 3, and a cross marks all industry trials

Among the 30 biggest industry sponsors of trials started in 2015-2025, the share in phase 1 ranges from 21% for Novartis to 80% for South Korea's Chong Kun Dang. Across all 41,391 industry trials, 40% were phase 1. Data: ClinicalTrials.gov, 2015-2025.

Tip: a cross for the all-industry average gives every sponsor a reference point, and only the extremes need labels.

Get the data from the ClinicalTrials.gov API v2 (clinicaltrials.gov/api/v2/studies): interventional trials
with an industry lead sponsor, start date 2015-2025, in phase 1, 2 or 3
and shape it into a table
(columns: sponsor, hq, phase1, phase2, phase3, trials; phase 1/2 counts as phase 2, phase 2/3 as phase 3;
merge subsidiaries into parents; keep the 30 sponsors with the most trials).
Build a plotly ternary plot: phase 3 at the top, phase 1 bottom left, phase 2 bottom right.
- Bubble area = trials, color by headquarters region; label the extremes, all sponsors in the hover.
- An "x" marker for the share of all industry trials in each phase.
- Title with the lowest and highest phase 1 share.

Another way to see it: 100% stacked bars sorted by phase 1 share give each sponsor's exact split, such as AstraZeneca's 44% phase 1, 26% phase 2 and 29% phase 3, but the clusters by region are harder to spot.

100% stacked horizontal bars of the 30 sponsors' trials by phase, sorted by phase 1 share from Chong Kun Dang (80%) and Boehringer Ingelheim (68%) at the top to Akeso and Novartis (21%) at the bottom

10. Paid work, unpaid work and leisure

Zoomed ternary plot of how women (orange) and men (blue) in 35 countries split their time between paid work (bottom left), unpaid work (bottom right) and leisure (top), with a gray line joining each country's pair. Every line runs from men toward unpaid work for women; India, Turkey, Portugal and Mexico have the longest lines and Finland and Sweden the shortest

Women do more unpaid work than men in all 35 countries, from 47 more minutes a day in Finland to 300 in India. Every pair of points runs the same way, with women toward unpaid work and men toward paid work and leisure. Data: OECD Time Use Database.

Tip: a gray line between two Scatterternary points per country makes a dumbbell inside the triangle, drawn before the markers so they sit on top.

Get the data from the OECD Time Use Database (OECD SDMX API, dataflow DSD_TIME_USE@DF_TIME_USE)
and shape it into a table
(columns: country, iso3, sex, paid, unpaid, leisure, flag; minutes per day, ages 15-64).
Build a plotly ternary plot of shares of paid + unpaid + leisure time: leisure at the top, paid work bottom left,
unpaid work bottom right.
- Women orange, men blue, a gray line joining each country's two points (draw lines first).
- Zoom: leisure min 15%, paid work min 10%. Label 8 countries.
- Title with the smallest and largest gap in unpaid minutes.

Another way to see it: a dumbbell chart of unpaid minutes alone ranks the countries exactly and shows the average gap of 127 minutes a day, but it leaves out the paid work and leisure that the ternary plot shows move the other way. See our dumbbell chart guide.

Dumbbell chart of minutes of unpaid work per day for men and women in 35 countries, sorted by the gap from India (+300 minutes) and Turkey (+237) to Sweden (+49) and Finland (+47)

11. A three-way election

Ternary plot of 649 UK constituencies in the 2024 general election by Labour (bottom left), Conservative (bottom right) and all other candidates (top) vote share, colored by winner. Hundreds of red Labour wins sit left of a dashed Labour-equals-Conservative line and mostly above a dotted Labour 50% line; Liberal Democrat and other winners sit near the top

Labour won 411 of 649 seats in the 2024 UK general election with 33.7% of the vote, and 341 of those seats were won with less than half the votes because the rest of the vote was split between the Conservatives and everyone else. Each seat is a point, colored by its winner. Data: House of Commons Library, election results, 4 July 2024.

Tip: draw the reference lines (here Labour equal to Conservative, and Labour at 50%) as two-point Scatterternary lines before the markers, so readers can see which side of each line a seat falls on.

Get the data from the House of Commons Library election results for the UK general election of 4 July 2024
(https://electionresults.parliament.uk/general-elections/6/candidacies.csv) and shape it into a table
(columns: constituency, nation, valid_votes, lab, con, other, winner; vote counts, Speaker's seat left out).
Build a plotly ternary plot of each constituency's vote shares: all other candidates at the top,
Labour bottom left, Conservative bottom right.
- One point per seat, colored by the winning party, with the seat count in the legend.
- A dashed line where Labour equals Conservative and a dotted line at Labour 50%.
- Title with Labour's seats, vote share and the number of seats won with under half the vote.

FAQ

bluesly
x
instagram
youtube
medium
fcaebook

Product

© 2026
Plotly. All rights reserved.
Cookie Preferences
aicpa/soc2