Los Angeles & the Inland Empire |
January 2025 – April 2026
Introduction
This map visualizes crowd-sourced reports of observed ICE (Immigration and Customs Enforcement)
activity across Los Angeles, Orange, Riverside, and San Bernardino Counties. It is built on data
collected by People Over Papers through our platform iceout.org, where residents,
rapid response volunteers, and community organizations submit real-time reports of observed
enforcement activity.
The tool is designed to make the geographic and temporal scope of immigration enforcement visible
at a level of detail that no government data source currently provides. It is intended as a resource
for journalists, community organizers, researchers, and elected officials seeking to understand
local enforcement patterns.
This is crowd-sourced data with meaningful limitations described below. Results should be
interpreted as indicative of patterns, not as a precise accounting of enforcement actions.
Navigating the Map
Sidebar Filters
- Date Range — restrict the data to a specific window of time
- Status (Rapid Response Only) — filter to reports from vetted rapid response network partners
- Activity Category — filter by the type of activity reported (e.g. Arrest/Transfer, Raid, Checkpoint)
Display Modes
- Points — each dot represents one report at its reported location
- Heatmap — a density surface showing concentrations of reports
Layers
- Census Tracts — neighborhood-level boundaries
- Electoral Districts — U.S. Congressional districts (statewide California data)
- Cities — municipal boundaries within the four counties
- Hex Tiles — uniform ¾-mile hexagonal grid
Detail Panel
Clicking any highlighted geometry opens a panel with: reports over time
(ignores date filter — shows full history; still reflects other filters), hour of day breakdown,
and activity category breakdown. All filters except date apply to the hour and category charts.
The Show Regional Averages button opens the same three
charts for the full filtered dataset.
Data
Source
All reports come from iceout.org, operated by People Over Papers / Pueblo Project Foundation.
The dataset covers approved reports from January 22, 2025 – April 17, 2026
across the four-county study area. Reports flagged as Confirmed come directly from
rapid response network partners and carry a higher degree of accuracy.
Congressional District Layer
The Congressional Districts layer is the only layer using statewide California data rather than
the four-county dataset. This ensures districts extending beyond the study area reflect their full
statewide report counts rather than being truncated at the county boundary.
Geographic Boundaries
- Census tracts — U.S. Census Bureau TIGER/Line files, 2023, via the
tigris R package
- Congressional districts — CA Congress Districts and Membership 2024–2026, California State Geoportal.
gis.data.ca.gov
- City boundaries — California Incorporated Cities, California State Geoportal.
gis.data.ca.gov
- County boundaries — U.S. Census Bureau via
tigris
Population Data
Population figures shown in the congressional district and city detail panels come from the
American Community Survey (ACS) 5-year estimates, 2022, accessed via the U.S. Census Bureau API
using the tidycensus R package. Variable B01003_001 (total population) is used for
both congressional districts and incorporated cities/places. Reports per capita are calculated as reports per
100,000 residents.
Hex Tile Grid
Hex tiles are generated as a uniform ¾-mile (~1,207m flat-to-flat)
hexagonal grid. Only tiles containing at least one report are displayed.
Show hex tile generation code
hex_cell_m <- 1207
counties_union_proj <- counties_union_4326 |> sf::st_transform(3310)
bbox_exp <- sf::st_bbox(counties_union_proj)
bbox_exp["xmin"] <- bbox_exp["xmin"] - hex_cell_m
bbox_exp["ymin"] <- bbox_exp["ymin"] - hex_cell_m
bbox_exp["xmax"] <- bbox_exp["xmax"] + hex_cell_m
bbox_exp["ymax"] <- bbox_exp["ymax"] + hex_cell_m
hex_grid <- sf::st_make_grid(
sf::st_as_sfc(bbox_exp),
cellsize = hex_cell_m,
square = FALSE
) |> sf::st_sf() |> sf::st_make_valid()
hex_clipped <- hex_grid[
sf::st_intersects(hex_grid, counties_union_proj, sparse = FALSE)[, 1], ] |>
sf::st_transform(4326) |>
mutate(hex_id = paste0("h", row_number()))
Methods
Data Preparation
Raw reports are loaded from a CSV export of approved iceout.org submissions.
Coordinates are extracted from WKT POINT geometry. Each report is spatially joined to its census
tract, congressional district, city, and hex tile using sf::st_within. Reports outside
the four-county boundary are excluded via spatial join against Census Bureau county polygons.
Show data preparation code
pts_in_tracts <- st_join(pts_sf, tracts_proj |> select(GEOID), join = st_within, left = TRUE)
pts_in_cd <- st_join(pts_sf_4326, cd_simple |> select(CD_GEOID = GEOID), join = st_within, left = TRUE)
pts_in_city <- st_join(pts_sf_4326, cities_simple |> select(CITY_GEOID = CENSUS_GEOID), join = st_within, left = TRUE)
Front-End Architecture
The map is a fully self-contained HTML file requiring no server. All data
is embedded at build time as JSON arrays and base64-encoded images. Interactivity is handled by
Plotly.js
(v2.32.0) with a Mapbox basemap. All filtering runs client-side with no external calls after load.
Show data embedding structure
arrays_json <- jsonlite::toJSON(list(
lat = df$latitude, lon = df$longitude,
date = df$date_str, confirmed = df$confirmed_clean,
cats = df$activity_cats_str,
geoid = df$GEOID_clean, cd_geoid = df$CD_GEOID_clean,
city_geoid = df$CITY_GEOID_clean,
hex_id = df$HEX_ID_clean, hour = df$hour
), na = "null", auto_unbox = FALSE)
Limitations
- Reporting bias — Communities with greater awareness of iceout.org are likely over-represented. This should not be understood as a uniform sample of enforcement activity.
- Temporal spikes — Increases in report volume may reflect heightened public awareness as much as an actual increase in enforcement activity.
- Location accuracy — Location data reflects where the reporter observed the incident, which may not precisely match the enforcement location. Moderators review for duplicates but cannot guarantee locational precision.
- Activity categorization — Categories are selected by the reporter and may not always accurately reflect what occurred. Multiple categories can be selected per report.
- What is not captured — Enforcement actions that were not observed, not reported, or occurred in areas with lower platform awareness are not represented. This is not a complete census of ICE operations.
Contact
For questions about the data, email us at
contact@puebloproject.com.
This tool is provided for informational and research purposes. Report counts and patterns
should be interpreted as indicative of enforcement trends, not as a precise record of
individual enforcement actions.