TaxFlow Stack is an open-source visualization framework that models and visualizes how every dollar of Cook County property tax flows across taxing districts, with a focus on TIF (Tax Increment Financing) exposure. It transforms raw Treasurer and Assessor datasets into stacked time-series visualizations that reveal how the tax burden shifts over time, by category, and by parcel (PIN).
The system brings transparency to complex fiscal mechanisms while providing value for public analysts, journalists, and institutional investors evaluating tax exposure and redevelopment risk.
Built for:
∙ Transparency in Cook County tax allocation
∙ Historical TIF trend visualization
∙ Comparative fiscal analysis across townships and parcels
∙ Integration into larger systems like PTAX-SIM for simulation and forecasting
TaxFlow Stack helps you see where the money flows and how much of it gets captured before it reaches the classroom, park, or fire district.
Stacked area charts of Cook County property tax bills, six levy years (by default) broken out by category for any PIN. Each chart also includes a table that shows the composite rate, total tax, non-TIF dollars, and TIF dollars per year.
What this shows
Levy math only. It decomposes the tax bill into where dollars are allocated at that year’s composite rate. Late penalties, refunds, and installment timing from the Treasurer are intentionally not part of the calculation here.
- A PNG like Tax Bill Composition by Year with legend entries:
- TIF — increment share
- COOK — countywide lines (Cook County, Forest Preserve)
- MUNI — municipal lines (city, library, SSA, school building, etc.)
- COMM COLL — community college district
- SECONDARY — K-12 school district (Board of Education in Chicago)
- MISC — regional and special districts (MWRD, Park District) and select bond items
- A table under the plot for each year: composite Rate, Total bill, Non-TIF dollars, TIF dollars.
- R 4.2+ (RStudio optional)
- R packages:
ptaxsim,dplyr,tidyr,ggplot2,scales,gridExtra,grid,gtable,DBI,RSQLite - Cook County SQLite database:
ptaxsim-2023.0.0.db(not included in the repo; place your copy underdata/)
Large data/DB files are intentionally not tracked by git. Only code and lightweight CSVs are versioned.
-
Put the DB in place
Copy your Cook County SQLite file into:
data/ptaxsim-2023.0.0.db -
Install packages and render a chart
Open R (or RStudio) in the repo folder and run:
# packages pkgs <- c("dplyr","tidyr","ggplot2","scales","gridExtra","grid","gtable","DBI","RSQLite") need <- setdiff(pkgs, rownames(installed.packages())) if (length(need)) install.packages(need, repos = "https://cloud.r-project.org") # ptaxsim (use whichever works in your environment) # install.packages("ptaxsim", repos = "https://cloud.r-project.org") # remotes::install_github("jbm999s/ptaxsim-master") # source the renderer source("R/save_tax_stack_1080x1350.R") # DB sanity check stopifnot(file.exists("data/ptaxsim-2023.0.0.db")) con <- DBI::dbConnect(RSQLite::SQLite(), "data/ptaxsim-2023.0.0.db", flags = RSQLite::SQLITE_RO) stopifnot(nrow(DBI::dbGetQuery(con, "SELECT name FROM sqlite_master WHERE type='table' AND name='pin';")) == 1) DBI::dbDisconnect(con) # make a chart (change PIN/township as desired) dir.create("output", showWarnings = FALSE) save_tax_stack_1080x1350( pin = "20114120540000", years = 2018:2023, county = "Cook County", township = "Hyde Park Township", out_path = "output/tax_stack_20114120540000_1080x1350.png", width_px = 1080, height_px = 1350, dpi = 150 )
-
Open
output/…png— that’s your stacked chart plus table.
- TIF vs non-TIF: There is no special TIF rate. The composite rate applies to two pieces of value — base (non-TIF) and increment (TIF).
- Why totals can differ from Treasurer “paid” totals: Treasurer reports include installment timing, penalties, and refunds. This tool uses the certified levy math only.
- Years: Default is
2018:2023. If your DB includes 2024 later, update theyearsargument.
Error: no such table: pin→ wrong DB file/path. Confirmdata/ptaxsim-2023.0.0.dbis present and non-zero in size.- TIF band is zero → parcel isn’t in a TIF. That’s expected.
- Plot/table won’t fit → increase
plot_height_fractionor image height insave_tax_stack_1080x1350().
The repo includes helpers to pull all PINs for a township prefix and render images in chunks. See R/township_helpers.R (if included) or adapt from the examples in issues/discussions.
- Cook County Clerk, Assessor, Board of Review, Treasurer public datasets consolidated into the
ptaxsimSQLite. - Category mapping mirrors agency types: COOK, MUNI, SECONDARY, COMM COLL, MISC, and TIF.
MIT (or your choice — update the LICENSE file accordingly).
Justin McClelland
Learn more about my work