3How has giving by donation size changed over time?
Each household’s giving in a given year is put into one of four size tiers — <$100, $100–999, $1,000–4,999, and $5,000+ — so we can watch the mix of small and large donors shift over time. Giving is counted the same way as elsewhere: SUCCEEDED individual gifts (DONATION and PLEDGEPAYMENT), rolled up to the household (see Methodology). Donors are defined in Are large donors going away?; where they live is in Where do donors live?.
Code
import pandas as pdimport plotly.express as pxfrom hh.clean.accounts import clean_accountsfrom hh.clean.donations import clean_donationsfrom hh.analytics.donors import annual_gifts, donors_by_size_year, TIER_LABELSfrom hh.viz import style, SEQUENTIAL_BLUE, moneySIZE_COLORS = [SEQUENTIAL_BLUE[i] for i in (1, 5, 9, 12)]COLOR_MAP =dict(zip(TIER_LABELS, SIZE_COLORS))ag = annual_gifts(clean_donations(accounts=clean_accounts()))sby = donors_by_size_year(ag)# the latest year in the data is the current, partial year — keep it out of the trendmax_year =int(ag["year"].max())complete_years = [y for y insorted(ag["year"].unique()) if y < max_year]plot_df = sby[sby["year"].isin(complete_years)].copy()ytd_donors =int(sby.loc[sby["year"] == max_year, "donors"].sum())ytd_dollars =float(sby.loc[sby["year"] == max_year, "dollars"].sum())# lifetime tier totals (all years) for the summary tableltot = sby.groupby("tier").agg(donors=("donors", "sum"), dollars=("dollars", "sum")).reindex(TIER_LABELS)ltot["dollar share"] = ltot["dollars"] / ltot["dollars"].sum()
Figure 3.2: Donated dollars by giving tier, by year
The small-donor base (under $100 a year) has grown sharply in recent years, while the number of households giving $1,000 or more in a year is small and uneven — its dollars, though, move the total most. The share of dollars coming from the top tiers:
2026 is year-to-date (partial year), so it is left out of the trend charts. So far in 2026, 299 donor households have given about $37,158 — the full-year figure will be higher.