Saturday, August 8, 2026

NZ and US petrol (‘gasoline’) and diesel costs


That is one other quick, easy weblog publish constructing a chart I’m going to be updating recurrently as a part of monitoring the impression of the slow-burn gasoline disaster attributable to the USA conflict with Iran.

I’ve a web page on this web site with a couple of charts on the gasoline disaster.

Petrol (or gasoline) and diesel costs

Right here’s at present’s new chart.

For these , listed here are a number of the key options I believed by and are intentionally a part of the polish right here

  • Each New Zealand and US costs on the identical foundation for direct comparability (and to shock USians with how a lot the remainder of the world pays for gasoline).
  • Mapping color to nation and utilizing the sides for gasoline sort, fairly than vice versa; doing it this manner makes it simpler to match country-to-country (fairly than fuel-to-fuel, which I discovered much less attention-grabbing).
  • Utilizing color within the title (due to ggtext by Claus O. Wilke and Brenton M. Wiernik) fairly than a legend or direct labelling of the strains—very robust clutter-reduction method on this context, I feel.
  • Annotations, in rigorously chosen gray italics, to point the important thing occasions/intervals of curiosity and reply the plain questions that anybody wanting on the chart (together with me, this morning) would have eg “what occurred in XXX?”
  • Colors for nations chosen to recommend their flags.
  • Be sure the viewers understands the peculiar tax state of affairs for diesel in New Zealand (diesel and electrical autos pay a highway consumer cost per distance travelled, not gasoline consumed, which isn’t included in these costs).
  • I thought-about, and ultimately determined in opposition to, forcing the vertical axis scale to go right down to zero. Nonetheless a bit uncertain about this one, I see professionals and cons of each choices.

I’ve additionally bought a zoomed in model of the chart simply 2026. That is really fairly a bit much less attention-grabbing. I like the massive sweep of the previous twenty years proven in the principle chart, and the way in which we are able to hyperlink value adjustments to main occasions.

Knowledge sources and code

So there’s nothing significantly complicated within the code. I wanted three information sources:

  • New Zealand gasoline costs, supplied by the Ministry of Enterprise, Innovation and Employment
  • USA gasoline costs supplied by the Power Info Administration
  • NZD / USD trade charge, which I’ve taken from FRED, the St Louis Federal Reserve information service.

There have been decisions to make about precisely which collection to match up and present, however not too tough and I feel I selected proper.

There’s additionally a little bit of fiddling round to not obtain the information recordsdata each time the script is run, however solely when the information is to some extent stale. The costs collection are weekly so there’s no level hitting the supplier’s server for one more copy of the file when the final revealed statement was six days or much less in the past.

library(tidyverse)
library(janitor)
library(readxl)
library(patchwork)
library(ggtext)

#---------------New Zealand----------------------

# Obtain petrol costs from MBIE. Undecided find out how to decide whether it is 'stale'
# or not, appears to get 10 days outdated a minimum of.
obtain.file(
  "https://www.mbie.govt.nz/property/Knowledge-Information/Power/Weekly-fuel-price-monitoring/weekly-table.csv",
  destfile = "nz-petrol-prices.csv"
)

# For some cause this crashes R
# nz <- read_csv("nz-petrol-prices.csv")
# so want to make use of learn.csv as an alternative

# The trade charge file is a bit sluggish to donwload so solely need to obtain it
# if crucial ie newest worth is greater than 10 days outdated
stale_fx <- TRUE

if (file.exists("nzd_usd.csv")) {
  nzd_usd <- read_csv("nzd_usd.csv")
  if (as.numeric(Sys.Date() - max(nzd_usd$observation_date)) < 10) {
    stale_fx <- FALSE
  }
}
if (stale_fx) {
  obtain.file(
    "https://fred.stlouisfed.org/graph/fredgraph.csv?id=DEXUSNZ",
    destfile = "nzd_usd.csv"
  )
  nzd_usd <- read_csv("nzd_usd.csv")
}


nz <- learn.csv("nz-petrol-prices.csv") |>
  as_tibble() |>
  clean_names() |>
  mutate(date = as.Date(date)) |>
  filter(variable == "Adjusted retail value") |>
  left_join(nzd_usd, by = c("date" = "observation_date")) |>
  prepare(date) |>
  fill(DEXUSNZ, .path = "down") |>
  mutate(value_usd_gallon = worth * DEXUSNZ * 3.78541 / 100) |>
  mutate(gasoline = ifelse(gasoline == "Premium Petrol 95R", "Premium Petrol", gasoline)) |>
  choose(date, gasoline, value_usd_gallon) |>
  mutate(nation = "New Zealand")

# Adjusted retail value is
# "The nationwide common value  paid by shoppers for a given gasoline for the week. "
# be aware, completely different from "Board value" which is the marketed charge Determined the
# Adjusted retail value (i.e. what really paid) was most similar to the USA
# collection within the subsequent part.

#------------------USA---------------------
# See https://www.eia.gov/dnav/pet/pet_pri_gnd_dcus_nus_w.htm

stale_usa <- TRUE
if (file.exists("usa-petrol-prices.xls")) {
  tmp <- read_excel("usa-petrol-prices.xls", sheet = "Knowledge 1", skip = 2)
  if (as.numeric(Sys.Date() - max(as.Date(tmp$Date))) < 7) {
    stale_usa <- FALSE
  }
}


if (stale_usa) {
  obtain.file(
    "https://www.eia.gov/dnav/pet/xls/PET_PRI_GND_DCUS_NUS_W.xls",
    destfile = "usa-petrol-prices.xls",
    mode = "wb"
  )
}

usa <- read_excel("usa-petrol-prices.xls", sheet = "Knowledge 1", skip = 2) |>
  mutate(Date = as.Date(Date)) |>
  choose(
    date = Date,
    `Common Petrol` = `Weekly U.S. Common All Formulations Retail Gasoline Costs  ({Dollars} per Gallon)`,
    `Premium Petrol` = `Weekly U.S. Premium All Formulations Retail Gasoline Costs  ({Dollars} per Gallon)`,
    Diesel = `Weekly U.S. No 2 Diesel Extremely Low Sulfur (0-15 ppm) Retail Costs  ({Dollars} per Gallon)`
  ) |>
  collect(gasoline, value_usd_gallon, -date) |>
  mutate(nation = "USA")

#------------combine the two----------------
combined_petrol <- usa |>
  rbind(nz) |>
  filter(date >= min(nz$date)) |>
  filter(gasoline != "Premium Petrol") |>
  mutate(gasoline = fct_relevel(gasoline, "Common Petrol"))

#-----------------plot drawing---------------
annotations <- tibble(
  date = as.Date(c(
    "2008-01-01",
    "2013-01-01",
    "2016-10-01",
    "2022-06-01",
    "2026-02-01"
  )),
  value_usd_gallon = 8.5,
  gasoline = "Common Petrol",
  nation = "USA",
  label = c(
    "Buildup to GlobalnFinancial Disaster",
    "'$100 oil plateau'",
    "US shale comes on-line",
    "Russia invades Ukraine",
    "USA assaults Iran"
  )
) |>
  mutate(gasoline = issue(gasoline, ranges = ranges(combined_petrol$gasoline)))

# Base definition of chart, utilized in each variations:
p0 <- combined_petrol |>
  ggplot(aes(x = date, y = value_usd_gallon, color = nation)) +
  facet_wrap(~gasoline, ncol = 1) +
  geom_line(linewidth = 0.7) +
  scale_y_continuous(label = greenback) +
  scale_colour_manual(values = c("New Zealand" = "blue", "USA" = "purple")) +
  labs(
    x = "",
    color = "",
    y = "Worth (USD per gallon)",
    title = "Retail petrol and diesel costs 2004-2026, **New Zealand** vs **USA**, (USD/gallon).",
    subtitle = "New Zealand costs embrace petrol excise, GST and different taxes however exclude diesel gasoline excise.",
    caption = "Supply: New Zealand MBIE, USA EIA"
  ) +
  theme(legend.place = "none", plot.title = element_markdown())

# Foremost chart:
p1 <- p0 +
  geom_text(
    information = annotations,
    aes(label = label),
    color = "grey40",
    vjust = 1,
    dimension = 2.9,
    fontface = "italic"
  )

# Zoomed in on 2026:
p2 <- p0 +
  filter(combined_petrol, date >= "2026-01-01") +
  geom_point() +
  labs(
    title = "Retail petrol and diesel costs 2026, **New Zealand** vs **USA**, (USD/gallon)."
  ) +
  scale_x_date(
    date_breaks = "1 month",
    date_labels = "%B"
  )

print(p1)
print(p2)

That’s all for at present.



Related Articles

Latest Articles