Home / Blog / This month's CPI: how to query and chart it in 5 minutes
2026-05-20 · Harry Vass
This month's CPI: how to query and chart it in 5 minutes
ABS released monthly CPI yesterday. Here's a five-minute Python recipe to query it, chart the YoY series, and have something publishable.
The ABS dropped this month's Monthly Consumer Price Index Indicator yesterday at 11:30am AEST, on the usual fourth-Wednesday release cycle. If you write a newsletter or run a data desk, you have roughly two hours before the slow-cooked takes hit Twitter and you need to publish.
This post is a five-minute recipe, fetch, chart, caption, ship. Tested today.
<!-- IMG: cpi-yoy-chart-2020-2026.png -->
Step 1, install once
pip install ausdata matplotlib
If you already have ausdata installed, you're at step 2.
Step 2, query the series
from ausdata import Ausdata
api = Ausdata()
cpi = api.get_data(
source="abs",
dataset_id="CPI_MONTHLY",
filters={"measure": "all_groups_yoy", "region": "australia"},
period={"start": "2020-01"},
)
print(f"Got {cpi['row_count']} observations, period {cpi['period']['start']} to {cpi['period']['end']}")
print(f"Latest: {cpi['records'][-1]}")
Output:
Got 65 observations, period 2020-01 to 2026-04
Latest: {'period': '2026-04', 'value': 3.6, 'unit': 'pct_yoy'}
Five lines, one HTTP call, citation-ready response.
Step 3, chart it
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame(cpi["records"])
df["period"] = pd.to_datetime(df["period"])
df = df.set_index("period").sort_index()
fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(df.index, df["value"], linewidth=2, color="#1a1a1a")
ax.axhline(y=2.5, color="#888", linestyle="--", linewidth=1, label="RBA target midpoint (2.5%)")
ax.axhspan(2, 3, alpha=0.08, color="green", label="RBA target band (2-3%)")
ax.set_title("Australia, Monthly CPI Indicator, YoY %", fontsize=14, weight="bold")
ax.set_ylabel("YoY change (%)")
ax.set_xlabel("")
ax.legend(loc="upper left")
ax.grid(True, alpha=0.3)
fig.text(0.99, 0.01, "Source: ABS, CC-BY 4.0", ha="right", fontsize=8, color="gray")
fig.tight_layout()
fig.savefig("cpi-monthly-yoy.png", dpi=150)
That's a publishable chart in fifteen lines. Target band shaded, midpoint dashed, ABS attribution baked into the footer.
Step 4, pull the trimmed mean separately
The headline monthly CPI is volatile. The number every RBA-watcher actually cares about is the trimmed mean, the inflation measure that strips the most extreme 30% of price changes. ABS publishes it quarterly in 6401.0, but the monthly indicator includes a trimmed-mean approximation:
trimmed = api.get_data(
source="abs",
dataset_id="CPI_MONTHLY",
filters={"measure": "trimmed_mean_yoy", "region": "australia"},
period={"start": "2020-01"},
)
df_tm = pd.DataFrame(trimmed["records"])
df_tm["period"] = pd.to_datetime(df_tm["period"])
df_tm = df_tm.set_index("period").sort_index()
fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(df.index, df["value"], label="Headline CPI", color="#888", linewidth=1.5)
ax.plot(df_tm.index, df_tm["value"], label="Trimmed mean", color="#c0392b", linewidth=2.5)
ax.axhspan(2, 3, alpha=0.08, color="green")
ax.set_title("Headline vs trimmed-mean CPI, YoY %", fontsize=14, weight="bold")
ax.legend(loc="upper right")
ax.grid(True, alpha=0.3)
fig.text(0.99, 0.01, "Source: ABS, CC-BY 4.0", ha="right", fontsize=8, color="gray")
fig.tight_layout()
fig.savefig("cpi-headline-vs-trimmed.png", dpi=150)
Two lines on one chart, the RBA target band shaded, ready for the newsletter.
Step 5, overlay the cash rate, for context
The CPI chart by itself answers "what happened to prices". To answer "what is the RBA likely to do about it", overlay the cash rate on the same axes:
cash = api.get_data(
source="rba",
dataset_id="F1_1",
filters={"series": "cash_rate_target"},
period={"start": "2020-01"},
)
df_cash = pd.DataFrame(cash["records"])
df_cash["period"] = pd.to_datetime(df_cash["period"])
df_cash = df_cash.set_index("period").sort_index()
fig, ax1 = plt.subplots(figsize=(10, 5))
ax1.plot(df_tm.index, df_tm["value"], label="Trimmed mean CPI YoY", color="#c0392b", linewidth=2.5)
ax1.axhspan(2, 3, alpha=0.08, color="green")
ax1.set_ylabel("Inflation (% YoY)", color="#c0392b")
ax1.set_xlabel("")
ax2 = ax1.twinx()
ax2.plot(df_cash.index, df_cash["value"], label="RBA cash rate", color="#2c3e50", linewidth=2, linestyle="--")
ax2.set_ylabel("Cash rate (%)", color="#2c3e50")
ax1.set_title("Trimmed-mean CPI vs RBA cash rate", fontsize=14, weight="bold")
fig.text(0.99, 0.01, "Sources: ABS + RBA, CC-BY 4.0", ha="right", fontsize=8, color="gray")
fig.tight_layout()
fig.savefig("cpi-vs-cash-rate.png", dpi=150)
Two y-axes, two data sources, one chart. This is the picture that explains the last three years of monetary policy in one image.
Step 6, caption it (the part nobody automates)
Here's the bit you still write yourself:
> Monthly CPI ticked up to 3.6% YoY in April, from 3.4% in March. Trimmed mean held at 3.1%, the eighth straight print inside or just above the RBA's 2-3% target band. The April upturn is largely a base-effect echo of last year's electricity rebate roll-off, the underlying picture is the same disinflation that's been underway since Q3 2024.
Numbers from the API, framing from you. That's the trade.
Honest gaps
The monthly CPI indicator is not the full quarterly CPI. ABS itself warns about this, the monthly basket is narrower (around 62-73% of the quarterly basket by weight, depending on the month) and the trimmed-mean methodology is approximate. For final-of-record figures, use 6401.0 quarterly.
Also: the monthly indicator does not split by capital city. If you need Sydney-vs-Melbourne, that's quarterly only.
If you want the R equivalent of this recipe, readabs is the canonical tool, same series, cleaner pipeline if you're already in tidyverse-land.
What this isn't
This post is not:
- Investment advice. Don't trade on a five-minute chart.
- A forecast, we're publishing what happened, not what's next.
- A replacement for the ABS release notes. Read those for methodology footnotes that affect interpretation.
Pricing
This entire recipe runs on the free tier. The two API calls cost two of your 500 monthly free calls.
- Free: 500 calls/month, covers a daily newsletter habit comfortably.
- Analyst: $29/mo, 10k calls, for desks running multiple recipes per release.
- Pro: $99/mo, 100k calls + webhooks, get a push the moment ABS publishes, run the chart automatically.
Free key at ausdata.io.