U.S. Disposable Income by Quintile (2020–2025)

Below is a self‐contained Python recipe that will fetch the latest mean disposable-income-per-capita (PPP USD) series for the U.S. by income quintile, restrict it to 2020–2025, and plot it. You can paste this into a Jupyter notebook or .py file and run it end-to-end. It uses the OECD’s SDMX-JSON API directly (no pandasdmx), parses the returned JSON into a DataFrame, and then plots.

python

import requests import pandas as pd import matplotlib.pyplot as plt # 1. Build the API URL. # - Dataset: IDD (Income Distribution Database) # - Key: {Country}.{Measure}.{Unit}.{Group} # • Country = USA # • Measure = INC_DISP (mean disposable income per capita) # • Unit = USD_USD (PPP-adjusted USD) # • Group = Q1+Q2+Q3+Q4+Q5 (the five 20%-bands, i.e. quintiles) base = "https://stats.oecd.org/SDMX-JSON/data" flow = "IDD/USA.INC_DISP.USD_USD.Q1+Q2+Q3+Q4+Q5" params = { "startTime": "2020", "endTime": "2025" } url = f"{base}/{flow}/all" # 2. Download and parse JSON resp = requests.get(url, params=params) resp.raise_for_status() js = resp.json() # 3. Extract the time‐series observations # The SDMX-JSON structure is a little nested, but: # • series key "0:0:0:0" … "0:0:0:4" correspond to Q1…Q5 # • each series has an "observations" dict of { timeIndex: [ value, ... ] } series = js['dataSets'][0]['series'] dim = js['structure']['dimensions']['series'] # find the position of the “InequalityGroup” dimension (should be the 4th of 4 dims) grp_pos = [d['id'] for d in dim].index('InequalityGroup') time_dim = js['structure']['dimensions']['observation'][0]['id'] rows = [] for key, dd in series.items(): # get the quintile code from the series key tuple idxs = key.split(':') grp = dim[grp_pos]['values'][int(idxs[grp_pos])]['id'] for t_idx, val in dd['observations'].items(): year = js['structure']['dimensions']['observation'][0]['values'][int(t_idx)]['id'] rows.append((int(year), grp, val[0])) df = pd.DataFrame(rows, columns=['Year','Quintile','Income']) df = df.pivot(index='Year', columns='Quintile', values='Income') # 4. Plot ax = df.plot(marker='o', figsize=(10,6)) ax.set_title('U.S. Mean Disposable Income per Capita (USD PPP)\nby Income Quintile (2020–2025)') ax.set_xlabel('Year') ax.set_ylabel('Income (USD PPP)') ax.legend(title='Quintile', loc='upper left') plt.tight_layout() plt.show()

How it works:

  • API URL
    We use the OECD SDMX-JSON endpoint to request dataset IDD, filtered to the U.S. (USA), the disposable-income measure (INC_DISP), PPP dollars (USD_USD), and all five quintiles (Q1…Q5) over the years 2020–2025.
  • Parsing
    In the JSON, each series is keyed by a string like "0:0:0:2", where the last number picks out which quintile it is (e.g. 0→Q1, 4→Q5). We loop over those, extract the year and the observed value.
  • Reshaping
    We build a DataFrame with columns (Year, Quintile, Income) then pivot it so that each quintile becomes its own line.
  • Plotting
    A simple matplotlib plot with one line per quintile, markers at each year.

Note

  • At the time of writing, the latest available data in IDD goes through 2022 (2023 is often provisional, and 2024–25 may not yet be in the OECD release). Any years without published data will show up as gaps or NaNs in the plot.
  • If you hit an HTTP or JSON‐parsing error, double-check that your network allows calls to stats.oecd.org, and that the dimension IDs (InequalityGroup, INC_DISP, etc.) match what your OECD Data Explorer shows in its “Developer API” panel.
  • You can adapt the same pattern to any other OECD country simply by swapping USA for its ISO code (e.g. DEU, FRA, GBR).

Let me know if you’d like me to help with any of the following:

  • Exporting the data to a CSV or Excel file once fetched.
  • Automatically annotating the latest provisional year (e.g. 2023) on the chart.
  • Overlaying another country for comparison.