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

Chris Parmer

Chris Parmer

November 4, 2026

Dual-Axis Charts - A Complete Guide

TL;DR

  • A dual-axis chart draws two series with different units on one time or category axis, one measured on the left y axis and one on the right, such as rain in inches and temperature in degrees for the same months.
  • Dual-axis charts are also known as dual y-axis charts, double y axis charts, secondary axis charts and twin axes (matplotlib's twinx), and when one series is bars and the other a line they are called combination or combo charts. They are similar to line charts, small multiples and Pareto charts, which are a kind of combo chart.
  • They are at their best for time series and sensor logs, where you want to see which signals rise and fall together and whether one lags the other. Some data visualization writers dislike them because hand-picked ranges can make either line look flat; with Plotly's default autorange each axis fits its own data.
  • You can make a dual-axis chart with Plotly in Python with make_subplots(specs=[[{"secondary_y": True}]]) and secondary_y=True on the second trace, or in JavaScript with a yaxis2 that has overlaying: "y". Since plotly.js 4.0 (Plotly for Python 7.0), the second axis's ticks snap to the first axis's gridlines by default (tickmode="sync"), so you get one clean grid.

What is a dual-axis chart?

Dual-axis charts look like this:

Climograph of Miami with blue bars for monthly precipitation on the left axis, from 1.8 inches in January to 10.5 in June, and an orange line for average temperature on the right axis, from 68.6°F in January to 84.2°F in August; June to October is shaded and labeled 45.3 of 67.4 inches (67%)

Data: U.S. Climate Normals 1991-2020 from the National Oceanic and Atmospheric Administration's National Centers for Environmental Information (NOAA NCEI), Miami International Airport (station USW00012839).

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

  • Each series has its own axis, and the colors tell you which: the blue bars are precipitation in inches on the blue left axis, and the orange line is average temperature in °F on the orange right axis.
  • Read each series against its own axis. June's bar reaches 10.5 on the left (10.51 inches of rain), and August's dot sits at about 84 on the right (84.2°F, the warmest month).
  • The point of putting them together is the season. June to October brings 45.3 of Miami's 67.4 inches of rain a year, 67%, and each of those months averages above 80°F, so the wet season and the hot season line up.
  • There is one set of gridlines. Both axes use Plotly's default autorange, and the right axis's ticks sit on the left axis's gridlines, so the grid doesn't double up.

It's often used for charts like these:

Biogen daily closing price as a blue line on the left axis and trading volume as gray bars on a right axis kept to the bottom third; on June 7, 2021 the close jumps from $286.14 to $395.85 and an orange volume bar reaches 18.0 million shares, 19 times the April-May median of 0.93 million

Price and volume. Biogen's stock rose 38% on June 7, 2021, the day the US Food and Drug Administration (FDA) approved Aduhelm, on 18.0 million shares, 19 times its usual daily volume. Data: Yahoo Finance chart API (ticker BIIB); approval date from the FDA's announcement, as reported by the Regulatory Affairs Professionals Society (RAPS).

Bar and line combo chart of US crude oil production as gray bars, from 5.0 million barrels a day in 2008 to 13.7 in 2025, and the average WTI price as a blue line on the right axis, with labels at $100 in 2008, $43 in 2016, $39 in 2020 and $95 in 2022

Bar and line combo charts. US crude oil production rose 2.7 times from 2008 to 2025, from 5.0 to 13.7 million barrels a day, while the yearly average price of West Texas Intermediate (WTI) crude swung between $39 and $100. Data: US Energy Information Administration (EIA), series MCRFPUS2 and RWTC.

Combo chart of Medicare Part D gross spending on Ozempic as green bars, from $1.5 billion in 2020 to $13.0 billion in 2024, and beneficiaries as a purple line on the right axis, from 0.27 million to 1.95 million people

Spending and patients. Medicare's gross spending on Ozempic grew 8.9 times from 2020 to 2024, to $13.0 billion, mostly because 7.2 times as many people filled a prescription, 1.95 million in 2024. Data: Centers for Medicare & Medicaid Services (CMS), Medicare Part D Spending by Drug.

A short history

William Playfair published a chart in 1821 that put the price of wheat as bars and the weekly wages of a good mechanic as a line over 256 years. Michael Friendly's HistData documentation calls it "a classic in the history of data visualization" that "commits the sin of showing two non-commensurable Y variables on different axes", and suggests plotting the ratio as well (Friendly and Denis 2005). This is Playfair's data, redrawn:

Redraw of Playfair's 1821 chart: gray bars for the price of a quarter of wheat in shillings from 1565 to 1821, rising to 99 shillings in 1810, and a red line for a mechanic's weekly wages rising slowly from 5 to 30 shillings

Another way to see it: dividing one series by the other answers the question Playfair was asking, how many weeks of work a quarter of wheat cost, on a single axis. It fell from 8.2 weeks in 1565 to 3.3 in 1810.

Line chart of the weeks of a mechanic's wages needed to buy a quarter of wheat, 8.2 weeks in 1565, a peak of 11.6 in 1595 and 3.3 in 1810

Climate scientists built a second axis into a standard chart. Walter and Lieth's 1960 Klimadiagramm-Weltatlas fixed the scale at 2 mm of precipitation per °C, so that a month where the rain line falls below the temperature line counts as dry (climatol documentation); example 7 below draws two of them. Engineers and scientists use the same idea for measured signals, and the tools they use build it in: MATLAB's yyaxis is documented as "Create chart with two y-axes", matplotlib has twinx and Plotly has secondary_y.

Why some people dislike dual-axis charts

The critics' argument is that each axis range is a choice, and nothing ties the two choices together. Stephen Few's 2008 article "Dual-Scaled Axes in Graphs: Are They Ever the Best Solution?" concluded "I can't think of a single case when there isn't a better solution", and ggplot2 only allows a second axis that is "a one-to-one transformation of the primary axes", such as °C and °F. Here is the case at its strongest, with the same US crude oil production and WTI price data drawn three times:

The same monthly US crude production and WTI price data three times: in panel A, production on a hand-picked 0 to 60 axis is a nearly flat gray line under a jumpy blue price line; in panel B, the price on a hand-picked 0 to 360 axis is a flat line while production climbs; in panel C, with autorange on both axes, both lines fill the chart and you can follow each one

Panels A and B are misleading, and they are misleading for the same reason: someone picked a range that squashes one of the series. Panel C uses Plotly's default autorange on both axes, which fits each axis to its own data, and both series are readable: production climbed most of the time and the price went up and down. Where the two lines cross in panel C still means nothing, because the two scales are independent, and that is the one thing to keep in mind when you read any dual-axis chart.

Why I like dual-axis charts

Many people in data visualization don't like them, but I disagree, and I use them a lot for time series where I'm trying to see how different variables rise and fall together. Putting two signals on top of each other lets you see three things that are hard to see in separate panels: which peaks and troughs line up, whether the relationship holds over the whole period or only part of it, and whether one signal moves first.

This is a chart from my post Analyzing Apple Health Data in Plotly Studio, made in Plotly Studio:

Small multiples of one person's Apple Health data from January 2024 to mid 2026, one panel per activity (walking, cycling, strength training, hiking, Pilates, running, functional strength training and all exercise), each with weekly minutes as bars and a 30-day sum as a line on one axis and heart rate variability (HRV SDNN, in ms) as a thin black line on a second axis; the long hiking period in 2024 and three running periods are shaded

Data: one person's Apple Health export, from Chris Parmer's post.

Each panel puts weekly exercise minutes on one axis and heart rate variability (HRV, measured as SDNN, the standard deviation of the intervals between normal heartbeats) on another, and the shaded periods make the pattern easy to check: HRV "increased every time she introduced running into her training". In the same analysis, VO2 max (the most oxygen the body can use during exercise) "appears to be a lagging indicator", rising only after a long stretch of hiking and cycling to work, and resting heart rate (in beats per minute, BPM) "decreased about 5 BPM from 60BPM to 55BPM during the intense period of hiking training" and went back up afterwards. Seeing a delay like that is exactly what a second axis is good at.

Engineering and science data works the same way, and examples 8 to 10 below are a battery test, a tide gauge and the Texas grid. On a hot August week in Texas, electricity demand on the Electric Reliability Council of Texas (ERCOT) grid tracks the temperature at Dallas/Fort Worth (DFW) airport hour by hour, and it peaks a little later each day (example 10 below). You can put a number on that delay with cross-correlation, the correlation between one series and the other shifted by each possible lag:

Two cross-correlation charts: ERCOT demand against DFW temperature, highest at r = 0.903 at a 1-hour lag (and 0.903 at zero), and water level at The Battery against the current at The Narrows, highest at r = 0.753 with the current 72 minutes earlier

For the Texas week the correlation is 0.903 at both 0 and 1 hours, so the lag is about an hour at hourly resolution, and on six of seven days demand peaked one or two hours after the temperature did. In New York Harbor the delay is clearer: the tidal current at The Narrows runs 72 minutes ahead of the water level at The Battery (example 9).

Another way to see it: plot one signal against the other, one dot per hour in time order. This is a connected scatter plot, which mathematicians call a parametric plot because each point is (x(t), y(t)) with time t as the parameter; in dynamical systems the same picture is a phase portrait. When one signal lags the other, the path out and the path back differ and the curve makes a loop, which is what hysteresis looks like when it comes from a time lag:

Connected scatter plot of ERCOT demand against DFW temperature for August 20, 2024, one dot per hour, making a loop: at 11:00 it was 90°F and 67.7 GW, at 22:00 it was 91°F and 76.7 GW, with the evening path above the morning path

At about 90°F, Texas used 9.0 gigawatts (GW) more at 10 pm than at 11 am, because demand lags the temperature.

What keeps these charts clean is the styling, not the range. Color each axis like its line, keep one set of gridlines (Plotly does this by default now), and draw the line on top of any bars. Some people like to stagger the two lines, one in the upper part of the chart and one in the lower part, by setting the ranges by hand, as in examples 1 and 4 below. That's a nice touch when the lines would otherwise tangle, but it's a matter of preference.

Alternatives to a dual-axis chart

Here's the same crude oil data drawn four ways. Each one is good at something different:

US crude oil production and the WTI price since January 2010 drawn four ways: a dual-axis line chart with autorange; both series indexed to 100 in January 2010, with production at 258 and WTI at 107 in August 2026; small multiples with production on top and price below, sharing the time axis; and a connected scatter (parametric) plot of price against production that moves from the upper left in 2010 to the right
  • Dual-axis chart (good for seeing both in their own units, in one place). You can read the actual production and price at any month and see which moves happened together, like the 2020 drop in both.
  • Indexed line chart (good for comparing growth). Dividing both series by their January 2010 value puts them on one axis in percent: production ended at 258 and the price at 107, so output grew 2.6 times while the price ended about where it started. This is Few's suggestion for time series, and the line chart guide shows it too. You lose the units.
  • Small multiples (good for many signals). Panels stacked with a shared time axis keep each series in its units and scale to five or ten signals. It's Plotly's make_subplots(rows=2, shared_xaxes=True); see the small multiples guide. Lining up peaks across panels takes more effort.
  • Connected scatter or parametric plot (good for the relationship itself). Price against production, one dot per month, shows that output kept rising whatever the price did, and it shows lags as loops (Haroz, Kosara and Franconeri 2016 studied how people read them). The time order is harder to follow; see the scatter plot guide.

How to make a dual-axis 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 which series goes on which axis and how each axis should look:

Make a plotly dual-axis chart from miami_normals.csv (columns: month, prcp_in, tavg_f).
- Use make_subplots(specs=[[{"secondary_y": True}]]).
- Precipitation as blue bars on the left y axis, titled "Precipitation (inches)".
- Average temperature as an orange line with markers on the right y axis (secondary_y=True).
- Keep Plotly's default autorange and synced ticks; hide the right axis's own gridlines.
- Color each axis title and its tick labels like its series.
- A title that states the takeaway, with the share of rain that falls from June to October computed from the data.

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 dual-axis chart the same way:

Show hourly ERCOT electricity demand as a blue line and the Dallas temperature as a red line on a second y axis, one week in August 2024, and mark each day's peak of both.

Make a dual-axis chart in Python or JavaScript

This is the code AI tools write under the hood. In Python, make_subplots with secondary_y gives you a second y axis on the right, and the Plotly multiple axes documentation covers third and fourth axes:

import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
df = pd.read_csv("miami_normals.csv") # month, prcp_in, tavg_f
fig = make_subplots(specs=[[{"secondary_y": True}]])
fig.add_trace(go.Bar(x=df.month, y=df.prcp_in, name="Precipitation", marker_color="#2a78d6"),
secondary_y=False)
fig.add_trace(go.Scatter(x=df.month, y=df.tavg_f, name="Temperature", mode="lines+markers",
line_color="#eb6834"), secondary_y=True)
fig.update_yaxes(title_text="Precipitation (inches)", secondary_y=False)
# tickmode="sync" is the default for an overlaying axis since Plotly 7; it's written out here to show it
fig.update_yaxes(title_text="Average temperature (°F)", tickmode="sync", showgrid=False, secondary_y=True)
fig.update_layout(title="Miami gets 67% of its rain from June to October", template="simple_white")
fig.show()

Traces on the secondary axis are drawn on top of the primary ones, so put the line there and the bars on the left. The plotly.js 4.0.0 changelog (August 24, 2026) lists the change as "Set default layout.axis.tickmode to 'sync' when axis is overlaying", and Plotly for Python 7.0.0 ships that version. With sync, the second axis's ticks sit on the first axis's gridlines and are labeled from its own range, so the labels may not be round numbers; set tickformat (for example ".1f") to choose how many decimals they show. tickmode="auto" brings back an independent set of ticks.

In JavaScript, the second axis is a yaxis2 with overlaying: "y", and the trace points at it with yaxis: "y2":

<div id="chart"></div>
<script src="https://cdn.plot.ly/plotly-4.1.1.min.js"></script>
<script>
// Miami climate normals, 1991-2020 (NOAA NCEI, station USW00012839)
const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
const rain = [1.83, 2.15, 2.46, 3.36, 6.32, 10.51, 7.36, 9.58, 10.22, 7.65, 3.53, 2.44]; // inches
const temp = [68.6, 70.7, 73.1, 76.7, 80.1, 82.8, 84.1, 84.2, 83.0, 80.1, 74.8, 71.2]; // °F
Plotly.newPlot("chart", [
{type: "bar", x: months, y: rain, name: "Precipitation", marker: {color: "#2a78d6"}},
{type: "scatter", mode: "lines+markers", x: months, y: temp, name: "Temperature",
yaxis: "y2", line: {color: "#eb6834", width: 3}} // the second axis
], {
width: 800, height: 450, legend: {orientation: "h", y: 1.12},
yaxis: {title: {text: "Precipitation (inches)"}},
yaxis2: {title: {text: "Average temperature (°F)"}, overlaying: "y", side: "right",
tickmode: "sync", tickformat: ".1f", showgrid: false} // sync is the default in plotly.js 4
});
</script>

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 command-line interface (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 dual-axis charts that are hard to read have the same problems: you can't tell which line goes with which axis, and two grids fight each other. Here is the Miami climograph both ways.

Don't draw both series in the same color with no axis titles, so the reader has to guess which axis is which, turn on a second set of gridlines that don't line up with the first, let the bars cover the line, or leave months as numbers in a default serif font:

The Miami climate data with bars and line in the same blue, no axis titles, two sets of misaligned gridlines (solid and dotted), the temperature line partly hidden behind the bars, months as numbers 1 to 12 and a serif font

Do color each axis title and its tick labels like its series, keep Plotly's autorange and its synced gridlines (one grid), draw the line on top of the bars, and write units in the axis titles:

The same data with blue bars on a blue left axis titled Precipitation (inches), an orange temperature line drawn above them on an orange right axis titled Average temperature (°F), one set of gridlines and month names

Checklist

Do

  • Color each axis title and tick labels like its series, or label each line directly.
  • Keep one set of gridlines: Plotly's default tickmode="sync" with showgrid=False on the second axis.
  • Draw the line over the bars by putting it on the secondary axis.
  • Say in the subtitle which series is on which axis.
  • Look for what rises and falls together and for delays, and measure a lag with cross-correlation before you claim one.

Don't

  • Read meaning into the exact point where two lines cross; the two scales are independent.
  • Squash one series with a hand-picked range to make a point.
  • Use a second axis when the two series share a unit; put them on one axis.
  • Add a third or fourth axis unless each line is labeled and readers know the signals.

Options to customize

A dual-axis chart in Plotly is two traces on two y axes, the second one overlaying the first, so these are the options that matter most. The full lists are in the make_subplots reference and the layout.yaxis reference.

  1. make_subplots(specs=[[{"secondary_y": True}]]): creates a figure with a second y axis on the right.
  2. secondary_y=True in add_trace and update_yaxes: puts a trace on, or styles, the second axis.
  3. yaxis2=dict(overlaying="y", side="right") and yaxis="y2" on a trace: the same thing without make_subplots, and how plotly.js does it.
  4. tickmode="sync": places the second axis's ticks on the first axis's gridlines; the default for overlaying axes since plotly.js 4.0 and Plotly for Python 7.0. Use "auto" for independent ticks.
  5. tickformat: the number of decimals on synced tick labels, like ".0f" or ".2f".
  6. showgrid=False on the secondary axis: one set of gridlines instead of two.
  7. title.font.color, tickfont.color: color each axis like its series, so readers know which is which.
  8. range (optional styling): set the ranges by hand to stagger the two lines, one high and one low, or to hang bars from the top with a reversed range, as in examples 1 and 4. Autorange is the default.
  9. anchor="free", autoshift=True, shift, position: a third or fourth y axis next to the second one.
  10. tickprefix, ticksuffix: units on the ticks, like $, ° or %.
  11. go.Scattergl: WebGL traces, for hundreds of thousands of markers; for lines, the SVG (scalable vector graphics) go.Scatter was faster in our test (see the FAQ).

More dual-axis chart examples

Ten more dual-axis charts built from real public data, from hydrology and climate to markets, a battery test and the power grid, each with its source, the technique that makes it work and a prompt to rebuild it.

1. A Hurricane Harvey hydrograph

Hydrograph of Hurricane Harvey: blue rain bars hanging from the top on a reversed right axis, peaking at 16.07 inches on August 27, 2017, and a purple filled line of Greens Bayou flow on the left axis rising from 36.5 cubic feet per second on August 24 to 20,200 on August 27

Greens Bayou near Houston went from 36.5 to 20,200 cubic feet per second in three days, after 31.3 inches of rain fell at Bush Intercontinental Airport from August 25 to 29, 2017. The flow peaked on the same day as the rain, and the chart shows how fast it fell away afterwards. Data: NOAA NCEI Global Historical Climatology Network Daily (GHCN-Daily), station USW00012960, and the US Geological Survey (USGS) National Water Information System (NWIS), site 08076000.

Tip: hanging the rain bars from the top with a reversed axis is the hydrologists' convention and an optional styling choice that keeps the bars clear of the flow line.

Get the data from NOAA NCEI's GHCN-Daily service (station USW00012960, daily PRCP in inches) and the USGS
water services daily values API (site 08076000, parameter 00060, statistic 00003), August 20 to
September 10, 2017, and shape it into a table (columns: date, rain_in, flow_cfs).
Build a plotly dual-axis chart with make_subplots: flow as a filled line on the left axis, rain as bars on
a reversed right axis so they hang from the top, and the peak flow and wettest day labeled.

2. The warmest year in NASA's record, in two units

Line chart of the global temperature anomaly from 1880 to 2025 with degrees Celsius on the left axis and the same values in Fahrenheit on the right; 2024 is labeled at +1.28 °C (+2.30 °F)

2024 was 1.28 °C, or 2.30 °F, above the 1951-1980 average, the highest in the National Aeronautics and Space Administration's (NASA's) record since 1880. The right axis converts the left one exactly, so it only saves readers the arithmetic. Data: NASA Goddard Institute for Space Studies (GISS) Surface Temperature Analysis (GISTEMP v4).

Tip: a conversion axis is the one case where the second range has to be set from the first (here times 9/5), and an invisible trace makes Plotly draw it.

Get the data from NASA GISS's GISTEMP v4 global table (GLB.Ts+dSST.csv, annual column J-D) and shape it into
a table (columns: year, anomaly_c, anomaly_f), where anomaly_f = anomaly_c * 9 / 5.
Build a plotly dual-axis chart: the anomaly in °C as a line on the left axis, a right axis in °F whose range
is the left range times 9/5, a zero line for the 1951-1980 average, and the warmest year labeled.

3. Gas storage and the Henry Hub price

Weekly US natural gas in storage as a gray sawtooth area on the left axis, filling each summer and drawing down each winter, and the Henry Hub price as an orange line on the right axis, with red dots at the weeks of February 19, 2021 ($12.18, storage -338 Bcf) and January 30, 2026 ($13.80, storage -359 Bcf)

The two biggest weekly storage draws since 2019, 359 billion cubic feet in the week of January 30, 2026 and 338 in the week of February 19, 2021, came in weeks when Henry Hub averaged over $12, two of the three such weeks in the data. Gas traders read the storage sawtooth against the price because the cold snaps show up in both. Data: US EIA, Weekly Natural Gas Storage Report and Henry Hub spot price.

Tip: mark the events the chart is about on both series, so readers see them happen at the same moment.

Get the data from the US EIA's weekly Lower 48 working gas in storage (series NW2_EPG0_SWO_R48_BCF) and
weekly Henry Hub spot price (series RNGWHHD), 2019 to today, and shape it into a table (columns: week,
storage_bcf, henry_hub).
Build a plotly dual-axis chart: storage as a gray filled area on the left axis, Henry Hub as an orange line
on the right axis, default autorange, and the two largest week-over-week draws marked and labeled.

4. The S&P 500 and the VIX in the April 2025 sell-off

Daily S&P 500 closes as a blue line in the upper half and the VIX as an orange line in the lower half, July 2024 to June 2025, with a dotted line on April 8, 2025, when the S&P 500 closed at 4,982.77 and the VIX at 52.33

On April 8, 2025, the Cboe Volatility Index (VIX) closed at 52.33, its high for the 12 months, and the S&P 500 closed at 4,982.77, its low. Daily changes in the two had a correlation of -0.86 over the year. Data: Federal Reserve Economic Data (FRED), series SP500 (from S&P Dow Jones Indices) and VIXCLS (from Cboe).

Tip: this one shows the optional staggered style: hand-set ranges keep the index in the upper half and the VIX in the lower half, so the lines only meet on the day that matters.

Get the data from FRED (series SP500 and VIXCLS), daily closes from July 1, 2024 to June 30, 2025, and
shape it into a table (columns: date, sp500, vix).
Build a plotly dual-axis chart: the S&P 500 on the left axis and the VIX on the right axis, each axis colored
like its line, a dotted line on the day of the VIX high, and both values labeled on that day.

5. Three climate records on three y axes

Line chart with three y axes from 1979 to 2025: CO2 in gray rising from 337 to 427 ppm on the left axis, the temperature anomaly in red rising to +1.18 °C on the first right axis, and September Arctic sea ice in blue falling from 7.05 to 4.75 million square kilometers on a second right axis

September Arctic sea ice shrank from 7.05 million km² in 1979 to 4.75 million in 2025, while carbon dioxide (CO2) at Mauna Loa rose from 337 to 427 parts per million (ppm). Plotly can add as many y axes as you need; past two, label each line at its ends so readers don't have to match colors to axes. Data: NOAA Global Monitoring Laboratory (GML), NASA GISS GISTEMP v4, National Snow and Ice Data Center (NSIDC) Sea Ice Index v4.

Tip: give the third axis anchor="free" and autoshift=True so Plotly moves it clear of the second.

Get the data from NOAA GML (Mauna Loa annual mean CO2), NASA GISS GISTEMP v4 (global annual anomaly) and
NSIDC's Sea Ice Index v4 (Arctic September extent, N_09_extent_v4.0.csv), 1979 on, and shape it into a
table (columns: year, co2_ppm, anomaly_c, sea_ice_mkm2).
Build a plotly line chart with three y axes: CO2 on yaxis, temperature on yaxis2 (overlaying, right) and
sea ice on yaxis3 (overlaying, right, anchor="free", autoshift=True), each axis colored like its line, and
the first and last values labeled.

6. A Pareto chart of US natural gas production

Pareto chart of 2024 US marketed natural gas production: green bars from Texas at 12,020 billion cubic feet down to Kansas at 126 and a gray bar for the other 20 states at 491, with a black cumulative line on a right axis passing 72.7% after five states and a dashed line at 80%

Five states produced 72.7% of US marketed natural gas in 2024, and Texas alone 29%. A Pareto chart is a combo chart whose second axis is the running share of the total, and the Pareto chart guide covers it in depth. Data: US Energy Information Administration, marketed production by state.

Tip: in a Pareto chart the left axis often runs from 0 to the total so each gridline is 20% on both axes; that's the chart's convention rather than a requirement.

Get the data from the US EIA's natural gas marketed production by state (NG_PROD_SUM_A_EPG0_VGM_MMCF_A.xls),
year 2024, whole states plus the federal offshore Gulf, and shape it into a table (columns: state, bcf,
share, cum_share), sorted from largest.
Build a plotly Pareto chart with make_subplots(secondary_y=True): bars for the top 15 plus "Other", the
cumulative share as a line on the right axis in percent, a dashed 80% line and the top-5 share labeled.

7. Walter-Lieth climate diagrams for Seattle and Los Angeles

Two Walter-Lieth climate diagrams side by side: Seattle, where the blue precipitation line drops below the red temperature line only in July and August, shaded orange as dry months, and Los Angeles, where it stays below from April to November, eight dry months

Los Angeles has eight dry months a year by the Walter-Lieth rule and Seattle two. Because 10 °C on the left lines up with 20 mm on the right by convention, the crossings mean something here: a month is dry when the rain line drops below the temperature line. Data: NOAA NCEI U.S. Climate Normals 1991-2020.

Tip: when a convention ties the two scales together, as Walter and Lieth's does, set both ranges from it (0-50 °C and 0-100 mm).

Get the data from NOAA NCEI's U.S. Climate Normals 1991-2020 monthly files for stations USW00024233
(Seattle) and USW00023174 (Los Angeles), and shape it into a table (columns: station, month, tavg_c, prcp_mm).
Build plotly Walter-Lieth climate diagrams as two panels: temperature on the left axis from 0 to 50 °C,
precipitation on the right axis from 0 to 100 mm, and the area between the lines shaded orange where
prcp_mm < 2 * tavg_c and blue otherwise, with the number of dry months in each panel.

8. A battery test log with voltage, current and temperature

A lab test log of NASA battery #5 with three y axes: voltage in blue rising to 4.2 V during charging and falling to 2.59 V at the end of a 2 A discharge, current in green at 1.5 A then tapering, then at -2 A, and temperature in red rising from about 25 to 39.0 °C during the discharge

The charger held 1.5 A until the cell reached 4.2 V at 0.93 hours, then held the voltage while the current tapered off. During the 55-minute, 2 A discharge the temperature rose from 24.7 to 39.0 °C, and it peaked 20 seconds after the current stopped. Data: NASA Prognostics Center of Excellence, Battery Data Set (Saha and Goebel 2007), B0005.

Tip: shade the test phases, so readers can match each change in one signal to what the others were doing.

Get the data from NASA's PCoE Battery Data Set (5. Battery Data Set.zip, BatteryAgingARC-FY08Q4, B0005.mat),
charge cycle 2 and discharge cycle 3, and shape it into a table (columns: hours, phase, voltage, current,
temperature).
Build a plotly line chart with three y axes: voltage on yaxis, current on yaxis2 and temperature on yaxis3
(anchor="free", autoshift=True), each axis colored like its line, default autorange, and the constant
current, constant voltage and discharge phases shaded and labeled.

9. Tide height and tidal current in New York Harbor

Water level at The Battery as a blue filled area on the left axis and the tidal current at The Narrows as an orange line on the right axis, October 1-3, 2025, with the current's peaks coming before the water level's peaks; high water of 6.1 ft at 16:24 on October 1 is labeled

The current at The Narrows peaks about 72 minutes before the water level at The Battery, the lag where the cross-correlation is highest (r = 0.75, against 0.62 with no lag). On one chart you can see each flood current arrive before the high water it brings. Data: NOAA Center for Operational Oceanographic Products and Services (CO-OPS), stations 8518750 (The Battery) and n03020 (The Narrows).

Tip: turn a current's speed and direction into one signed value along its main axis (flood positive), so it can share a chart with the water level.

Get the data from the NOAA CO-OPS Data API: water_level at station 8518750 (The Battery, feet above mean lower low water, MLLW) and
currents at station n03020 (The Narrows, knots and direction), October 1-3, 2025, and shape it into a table
(columns: time, water_level_ft, current_kn), with the current projected on its principal axis.
Build a plotly dual-axis chart: water level as a filled area on the left axis, current as a line on the right
axis with a zero line, default autorange, and print the lag where the cross-correlation peaks.

10. Texas electricity demand and the afternoon heat

ERCOT hourly electricity demand as a blue line on the left axis and the temperature at Dallas/Fort Worth airport as a red line on the right axis, August 18-24, 2024, rising and falling together every day, with dots at each day's peaks and the week's high of 85.5 GW at 6 pm on August 20 labeled

Texas electricity demand peaked at 85.5 GW in the hour ending 6 pm on August 20, 2024, and on six of the seven days demand peaked one or two hours after the temperature at Dallas/Fort Worth did. Data: US EIA Hourly Electric Grid Monitor (Form EIA-930), balancing authority ERCO; NOAA NCEI Global Hourly, station 72259003927 (DFW).

Tip: mark each day's peak on both lines, so the delay between them is visible without a ruler.

Get the data from the US EIA Hourly Electric Grid Monitor six-month file EIA930_BALANCE_2024_Jul_Dec.csv
(ERCO, Demand (MW) (Adjusted), UTC time at end of hour) and NOAA NCEI Global Hourly for station 72259003927
(TMP), August 18-24, 2024 in US Central time, and shape it into a table (columns: time, demand_gw, temp_f).
Build a plotly dual-axis chart: demand on the left axis, temperature on the right axis, default autorange,
dots at each day's peaks, and print the cross-correlation at lags from -12 to 12 hours.

FAQ

bluesly
x
instagram
youtube
medium
fcaebook

Product

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