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

Chris Parmer

Chris Parmer

October 24, 2026

Gauge Charts - A Complete Guide

TL;DR

  • A gauge chart shows one value on a curved scale against a target, a limit or a set of bands. In Plotly it's go.Indicator with mode="gauge+number+delta".
  • Gauge charts are also known as speedometer charts, dial charts and radial gauges, and are similar to bullet charts.
  • Use one when a single KPI against a known target or official bands is the whole message: storage against its seasonal average, debt against its legal limit, air quality against EPA's categories.
  • Gauges take a lot of space for one number and show no history, so use a bullet gauge for a panel of KPIs, a number with a sparkline when the trend matters, and a line chart for anything over time.
  • Any coding agent can make one with Plotly in a minute, and make_subplots(specs=[[{"type": "indicator"}]]) puts several in one dashboard figure.

What is a gauge chart?

Gauge charts look like this:

Angular gauge of US Lower 48 natural gas storage at 3,644 Bcf for the week ending October 16, 2026, with the five-year range of 3,342 to 3,798 Bcf as a light band and the five-year average of 3,609 Bcf as a black line; +35 Bcf

Data: EIA, Weekly Natural Gas Storage Report, week ending October 16, 2026.

How do you read a gauge chart? In the example above, notice these things:

  • The blue bar is the value, the natural gas held in US storage in mid-October, and it fills the dial clockwise from the left end. The big number in the middle gives the same value, 3,644 billion cubic feet, so nobody has to read it off the arc.
  • The black line is the target the value is compared with, EIA's five-year average for the same week. The blue bar ends just past the line, which means storage is a little above normal.
  • The light blue band is the five-year range for this week, so a bar that ends inside it is within what the past five years have seen for mid-October.
  • The green number under the dial states the gap to the average, +35 Bcf, and the up arrow and the color say which way it goes.
  • The dial starts at 3,000 Bcf instead of zero, which makes a small gap easy to see. The length of the bar is therefore not a share of anything, and a bar that fills half the arc does not mean storage is half full.

It's often used for charts like these:

Angular gauge from 0 to 500 with EPA's six AQI category colors, showing an AQI of 278 (very unhealthy) for the New York metro area on June 7, 2023; +95 vs the day before

A reading on a scale with official bands. Canadian wildfire smoke pushed New York's daily air quality index to 278 on June 7, 2023, inside EPA's purple "very unhealthy" band. Data: U.S. EPA AirData, Daily AQI by CBSA.

Angular gauge whose arc ends at the $41.1 trillion debt limit, showing $40.24 trillion of debt subject to limit on October 22, 2026, with the last 5% shaded light red; +6.2% in a year

A stock growing toward a hard limit. US federal debt subject to the limit reached $40.24 trillion on October 22, 2026, 97.9% of the $41.1 trillion ceiling, so the empty sliver of the arc is the $860 billion of headroom. Data: U.S. Treasury, Daily Treasury Statement, Table III-C.

Speedometer gauge from 85 to 105 mph with a needle at 101.4 mph for Mason Miller's average four-seam fastball in 2026, a blue band for the middle half of pitchers (93.0 to 96.2 mph) and an orange band for the fastest 10%

A speed, where the speedometer is literal. Mason Miller's four-seam fastball averaged 101.4 mph in 2026, the fastest of 578 pitchers; the median was 94.6 mph. Data: MLB Statcast via Baseball Savant.

A short history

Dials came to dashboards from cars and control rooms, and in Information Dashboard Design (2006) Stephen Few argued they waste space and are hard to compare. He designed the bullet graph to replace them; his Bullet Graph Design Specification puts the same measure, target and bands on a straight line, because people judge position along a common scale more accurately than angle (Cleveland and McGill, 1984). Plotly's go.Indicator draws both, with gauge.shape="angular" or "bullet".

Alternatives to a gauge chart

Here's the same inflation reading drawn six ways. Some are better for the question, some worse, some just different:

PCE inflation of 3.4% in August 2026 against the Fed's 2% target drawn six ways: an angular gauge, a bullet gauge, a number with a +1.4 point delta, the same number with a three-year sparkline, a line chart from 2015 with a dotted 2% target line, and a donut filled to 3.4 out of 8
  • Bullet gauge (better for a panel of KPIs). The same value, target and bands in a strip, so several stack into one panel on a shared scale and are read more accurately than angles.
  • Number and delta (better when space is tight). A big number and its gap to the target say the same thing in a tenth of the space; it's the standard KPI card.
  • Number, delta and sparkline (better when the trend matters). Adds the last three years, which shows that inflation rose again in 2026, something no gauge can show.
  • Line chart with the target (better for history). Shows that PCE inflation has been above 2% since March 2021. Use it whenever the question is "how did we get here".
  • Angular gauge (works too, for one KPI on a big screen). Familiar and readable from across a room, but it takes the most space.
  • Donut or progress ring (worse). A ring reads as a share of a whole, and here the 8% maximum is arbitrary, so "3.4 out of 8" means nothing.

Here's where a dot plot wins. Twelve gauges fill a screen, while one dot plot shows the bed occupancy of all 50 states and DC against the same 85% line:

Dot plot of inpatient bed occupancy for 50 states and DC in the week ending October 17, 2026, sorted, with lines at 85% and the US average of 75.1%

How to make a gauge chart

With AI

ChatGPT, Claude Code, GitHub Copilot, Cursor and other AI tools are excellent at writing Plotly code. Name Plotly in the prompt, and say what the range, the target and the bands are:

Make a plotly gauge chart (go.Indicator) from kpis.csv
(columns: kpi, value, target, year_ago, unit, higher_is_better).
- One gauge per row, angular for a single KPI and bullet (gauge.shape="bullet") for a panel.
- Axis range from the data, not 0-100; threshold at target; delta referenced to the target.
- Delta colors by meaning: green when the move is good, red when it's bad (higher_is_better).
- Don't set number.font.size, so Plotly keeps the number and the delta apart.
- Number with units (suffix) and a sensible valueformat.
- Save it as gauge.html and as a PNG at 2x scale.

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 gauge the same way:

Show the latest weekly gas storage as a gauge from 3,000 to 4,200 Bcf, with the five-year range for the same week as a light band and the five-year average as a black threshold line. Show the difference from the average under the number, and add a line chart below of this year against the five-year range.

Make a gauge chart in Python or JavaScript

This is the code AI tools write under the hood. In Python:

import plotly.graph_objects as go
fig = go.Figure(go.Indicator(
mode="gauge+number+delta",
value=3.4,
number={"suffix": "%"},
delta={"reference": 2, "suffix": " pts vs target", "increasing": {"color": "#c4422f"}},
gauge={
"axis": {"range": [0, 8]},
"bar": {"color": "#2a78d6"},
"threshold": {"value": 2, "line": {"color": "black", "width": 4}},
},
title={"text": "PCE inflation"},
))
fig.show()

In JavaScript, plotly.js takes the same attributes. This draws a circular gauge, the default gauge.shape: "angular", and gauge.shape: "bullet" turns it into a linear gauge on a straight scale:

<div id="chart"></div>
<script src="https://cdn.plot.ly/plotly-4.1.1.min.js"></script>
<script>
Plotly.newPlot("chart", [{
type: "indicator",
mode: "gauge+number+delta",
value: 3.4,
number: { suffix: "%" },
delta: { reference: 2, suffix: " pts vs target", increasing: { color: "#c4422f" } },
gauge: {
axis: { range: [0, 8] },
bar: { color: "#2a78d6" },
threshold: { value: 2, line: { color: "black", width: 4 } }
},
title: { text: "PCE inflation" }
}]);
</script>

Plotly colors a rising delta green by default, so set delta.increasing.color to red whenever up is bad, as it is for inflation.

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

A gauge is only as good as its range and its reference. Here is the same August 2026 inflation reading both ways, in the same colors.

Don't use a 0-100 axis for a 3.4% rate, leave out the target and the units, compare with last month and let a rise in inflation show in green, or switch to a serif font:

A gauge of PCE inflation with mistakes: a 0 to 100 axis on which the 3.4 value is a sliver at the far left, no target line, no percent sign, a green up arrow of 0.1 against the previous month, and Times New Roman text

Do fit the axis to the data (0-8%), draw the 2% target as a threshold, measure the delta from the target and color it red because higher inflation is bad:

The same gauge designed on purpose: a 0 to 8% axis, a black threshold line at the 2% target, the value 3.4% and a red +1.4 points vs 2% target delta, in Inter

Checklist

Do

  • Write a title that states the takeaway with the number, like "PCE inflation was 3.4% in August 2026, 1.4 points above the Fed's 2% target."
  • Set gauge.axis.range on purpose: above zero when the action is in a narrow band, ending at a real maximum when there is one.
  • Show the target as a threshold and reference the delta to it when distance from target is the question.
  • Use steps only for bands that mean something: a normal range, official categories, the spread of peers.
  • Color deltas by meaning per KPI with delta.increasing.color and delta.decreasing.color.

Don't

  • Use traffic-light steps without defined thresholds behind them.
  • Fill a screen with gauges when bullets or a dot plot would hold the same values.
  • Set the number's font size when a delta sits under it; Plotly sizes both to fit, and a fixed size can push them into each other.
  • Rely on color alone for a category; name it in the title.

Options to customize

These are the go.Indicator options that matter most. The full list is in the Plotly indicator documentation and on the gauge charts page.

  1. mode: any of number, delta and gauge, joined with +.
  2. value: the number shown.
  3. number.prefix, number.suffix, number.valueformat: units and a d3 format such as .1f or ,.0f.
  4. delta.reference: what the delta compares with, such as a target, last year or an average.
  5. delta.relative: show a percent change instead of a difference.
  6. delta.increasing.color, delta.decreasing.color, delta.symbol: delta colors and arrows; set them by what's good for each KPI.
  7. delta.position: the delta above, below, left or right of the number.
  8. gauge.shape: angular (the dial) or bullet (a strip).
  9. gauge.axis.range, tickvals, ticktext: the scale and its labels; put units in ticktext.
  10. gauge.bar.color, gauge.bar.thickness: the value bar; thickness 0 hides it, for a custom needle.
  11. gauge.steps: background bands as {range, color}.
  12. gauge.threshold.value, line, thickness: a line at a target or limit.
  13. gauge.bgcolor, gauge.borderwidth: the track color and border.
  14. title.text, title.align: a short label inside the indicator.
  15. domain: where the indicator sits, for several in one figure.
  16. make_subplots(specs=[[{"type": "indicator"}]]): indicator cells in a grid, mixed with xy cells for sparklines.

More gauge chart examples

Ten more gauges, bullet gauges and KPI indicators built from real public data, each with its source, the technique that makes it work and a prompt to rebuild it.

1. Lake Mead and the Colorado River shortage tiers

Angular gauge of Lake Mead's elevation at 1,037 feet on October 22, 2026, on an axis from 1,000 to 1,229 feet with shortage tiers shaded at 1,075, 1,050 and 1,025 feet; down 20.5 feet from a year earlier

Lake Mead fell to 1,037.2 feet on October 22, 2026, 20.5 feet lower than a year earlier and below its July 2022 low of 1,040.6 feet. That puts it in the 1,025-1,050 foot band of the 2007 Interim Guidelines' second shortage tier.

Data: U.S. Bureau of Reclamation, RISE daily elevation; tiers from the 2007 Record of Decision.

Tip: the steps are the official tiers, darkening as shortages deepen, and tick labels sit on the tier boundaries.

Get the data from the Bureau of Reclamation's RISE API (data.usbr.gov, item 6123, Lake Mead daily
elevation) and shape it into a table (columns: date, elevation_ft).
Build a plotly go.Indicator gauge from 1,000 to 1,229 ft with steps at 1,025, 1,050 and 1,075 ft
(darker as shortages deepen), a thin dark bar, and the delta against the same day a year earlier.

Another way to see it: the daily record since 2000 shows a fall of about 177 feet, with short recoveries.

Line chart of Lake Mead's daily elevation from 1,214 feet in January 2000 to 1,037 feet in October 2026, with dotted lines at the three shortage tiers

2. California's largest reservoirs

Eight bullet gauges for California's largest reservoirs showing storage as a share of capacity with a black tick at the historical average; Pine Flat at 63%, Oroville at 81% and Folsom at 87% of average in orange, San Luis at 157%

The eight largest reservoirs held 105% of their historical average for October 22, 2026, but not evenly: San Luis was at 157% of average while Pine Flat was at 63% and Oroville at 81%.

Data: California DWR, CDEC Daily Reservoir Storage Summary.

Tip: eight shape="bullet" indicators stacked with domain share one 0-100% scale, which eight angular gauges couldn't.

Get the data from CDEC's Daily Reservoir Storage Summary (cdec.water.ca.gov, report RES) and shape it
into a table (columns: reservoir, capacity_af, storage_af, avg_storage_af).
Build one plotly go.Indicator bullet gauge per reservoir, stacked with domain: bar = % of capacity,
threshold = historical average as % of capacity, "% of average" as an annotation on the right.

3. Earth's temperature and the 1.5°C line

Angular gauge from 0 to 2°C showing the global temperature for October 2025 to September 2026 at 1.50°C above pre-industrial, with the 1.5°C threshold as a red line; -0.01°C against the previous 12 months

From October 2025 to September 2026, global surface air temperature averaged 1.50°C above 1850-1900 (1.495 before rounding), 0.01°C below the previous 12 months. The calendar year 2024 was 1.60°C.

Data: Copernicus C3S / ECMWF, ERA5 via Climate Pulse, with C3S's 0.88°C offset to pre-industrial (Global Climate Highlights 2024).

Tip: a 12-month average weighted by days steadies the needle, and the note says the Paris limit is a 20-year average.

Get the data from Copernicus Climate Pulse (sites.ecmwf.int/data/climatepulse, ERA5 daily global 2m
temperature) and shape it into a table of monthly means (columns: month, anomaly_pi_c, days), adding
0.88°C to the 1991-2020 anomaly.
Build a plotly go.Indicator gauge from 0 to 2°C with a red threshold at 1.5 and a light red step
above it; value = last 12 months, delta vs the 12 months before.

4. PCE inflation against the Fed's target

Two bullet gauges on a 0 to 8% axis: PCE inflation at 3.4% and core PCE at 3.0% in August 2026, each with a black line at the 2% target and deltas of +1.4 and +1.0 points

PCE inflation was 3.4% in August 2026 and core PCE 3.0%, 1.4 and 1.0 points above the FOMC's 2% goal. Headline PCE has been above 2% for 66 straight months.

Data: BEA via FRED (PCEPI, PCEPILFE).

Tip: two bullets on one shared axis compare headline and core, and the delta reference is the target.

Get the data from the BEA's PCE price index via FRED (series PCEPI and PCEPILFE) and shape it into a
table of 12-month changes (columns: date, pce_yoy, core_yoy).
Build two plotly go.Indicator bullet gauges (mode="number+delta+gauge") on a shared 0-8% axis,
threshold at 2, delta referenced to 2, orange when above target.

5. Unemployment against CBO's natural rate

Angular gauge from 0 to 15% showing US unemployment at 4.2% in September 2026, a band for the 2000-2026 range of 3.4% to 14.8%, and a black line at CBO's noncyclical rate of 4.39%

Unemployment was 4.2% in September 2026, 0.2 points below CBO's noncyclical rate of 4.39%. Since 2000 it has ranged from 3.4% to 14.8%.

Data: BLS (UNRATE) and CBO (NROU) via FRED.

Tip: the delta's colors are both gray, because being below or above an estimated natural rate isn't good or bad in itself.

Get the data from FRED: UNRATE (BLS unemployment rate) and NROU (CBO noncyclical rate), and shape it
into a monthly table (columns: date, unrate, nrou).
Build a plotly go.Indicator gauge from 0 to 15%: a step for the range since 2000, a threshold at
the latest NROU, delta referenced to NROU in neutral gray.

Another way to see it: over time, unemployment has been at or below CBO's estimate in 55 of the 56 months since January 2022.

Line chart of the US unemployment rate and CBO's noncyclical rate from 2000 to 2026; unemployment has been at or near the line since 2022

6. Markets in their 52-week ranges

Six bullet tracks from 52-week low to high with a marker at the latest close: S&P 500 at 96% of its range, WTI crude at 89%, the broad dollar at 87%, the 10-year yield at 74%, the VIX at 32%, Henry Hub gas at 2%

In October 2026 the S&P 500 sat at 96% of its 52-week range and WTI crude at 89%, while Henry Hub gas, at $3.10, was at 2% of a range stretched by a $30.72 spike in January 2026.

Data: FRED (S&P Dow Jones Indices, Federal Reserve, EIA, Cboe).

Tip: rescaling each price to 0-100% of its own range puts an index, a yield and a commodity on one axis; the bar is hidden and the threshold is the marker.

Get the data from FRED: SP500, DGS10, DCOILWTICO, DHHNGSP, DTWEXBGS and VIXCLS daily closes, and
shape it into a long table (columns: series, date, value) for the last 52 weeks.
Build one plotly go.Indicator bullet per series with axis 0-100 (position in range), bar.thickness 0,
and a colored threshold at the latest position. Low and high values under each track.

7. A US economy dashboard

A KPI dashboard of six indicators with sparklines: CPI inflation 3.7% (+0.7 points), unemployment 4.2%, 29,000 payroll jobs added in September 2026, GDP growth 2.2%, a 4.00% upper fed funds target and a 7.32% mortgage rate

CPI inflation rose to 3.7% in September 2026, 0.7 points higher than a year earlier, while payrolls added 29,000 jobs and the 30-year mortgage rate reached 7.32%.

Data: FRED (BEA, BLS, Federal Reserve, Freddie Mac).

Tip: make_subplots with indicator rows above xy rows puts each number, delta and sparkline in one grid.

Get the data from FRED: A191RL1Q225SBEA, CPIAUCSL (12-month change), UNRATE, PAYEMS (monthly change),
DFEDTARU and MORTGAGE30US, and shape it into a long table (columns: indicator, date, value).
Build a plotly make_subplots grid: indicator cells (number+delta vs a year earlier, colored by
whether up is good) above xy cells with a three-year sparkline and a dot on the latest value.

8. Hospital bed occupancy by state

A grid of 12 small angular gauges of inpatient bed occupancy for the week ending October 17, 2026: Washington 87.4%, Delaware 86.4% and DC 85.0% in orange past a red 85% line, then New York 83.5% down to Maryland 80.2%

Hospitals in Washington (87.4%), Delaware (86.4%) and DC (85.0%) were above 85% occupancy in the week ending October 17, 2026, a warning level that traces to Bagust et al., 1999. The US average was 75.1%.

Data: CDC NHSN, Weekly Hospital Respiratory Data.

Tip: make_subplots(specs=[[{"type": "indicator"}] * 4] * 3) gives every gauge the same scale and threshold, and only the ones past it turn orange.

Get the data from CDC's NHSN Weekly Hospital Respiratory Data (data.cdc.gov dataset ua7e-t2fy) and
shape it into a table for the latest week (columns: jurisdiction, pct_inpatient).
Build a plotly make_subplots 3x4 grid of go.Indicator gauges (0-100%) for the 12 highest states,
red threshold at 85, bars orange at 85 or more.

9. Kindergarten MMR coverage against the 95% target

Bullet gauge on a 70 to 100% axis showing US kindergarten MMR coverage at 92.4% in 2025-26, with gray bands for the state range of 75.2% to 98.9% and the middle half of states, and a red line at 95%; -2.8 points vs 2019-20

Coverage was 92.4% in 2025-26, 2.8 points below 2019-20 and under the Healthy People 2030 target of 95% for the sixth year in a row. Only 10 of the 49 reporting jurisdictions met it.

Data: CDC SchoolVaxView (data.cdc.gov).

Tip: two steps show the spread of states (full range and middle half) behind the national bar.

Get the data from CDC SchoolVaxView, Vaccination Coverage and Exemptions among Kindergartners
(data.cdc.gov dataset ijqb-a7ye), vaccine MMR, and shape it into a table (columns: school_year,
geography, coverage).
Build a plotly go.Indicator bullet from 70 to 100%: national value as the bar, steps for the state
range and middle half, threshold at 95, delta vs 2019-20 in red when lower.

Another way to see it: the national series shows the drop after 2019-20.

Line chart of US kindergarten MMR coverage by school year from 2009-10 to 2025-26 with a 95% target line; 95.2% in 2019-20, 92.4% in 2025-26

10. Medicare Part D's costliest drugs

Four number indicators: Eliquis $20.8 billion (+14% vs 2023, 7.2% of Part D), Ozempic $13.0 billion (+41%), Jardiance $11.4 billion (+29%) and Mounjaro $6.3 billion (+168%)

Medicare Part D spent $6.3 billion on Mounjaro in 2024, 2.7 times its 2023 spending. Eliquis was the largest at $20.8 billion, 7.2% of the $289 billion total.

Data: CMS, Medicare Part D Spending by Drug (gross cost, before rebates).

Tip: spending has no natural maximum, so these are mode="number+delta" tiles with relative=True, not gauges.

Get the data from CMS Medicare Part D Spending by Drug (data.cms.gov, data year 2024 release) and
shape it into a table (columns: brand, year, spending), Overall rows only.
Build four plotly go.Indicator tiles (mode="number+delta") for the top four drugs: $ billions,
relative delta vs 2023, share of total Part D spending in each title.

FAQ

bluesly
x
instagram
youtube
medium
fcaebook

Product

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