This is a transcript of a full session with Claude about the TriMet Portolan Mirror. It was done with Claude Desktop with Cowork, to demonstrate that you don't need to be a developer and use Claude Code. The Portolan Skills were installed, and Claude installed DuckDB on its own. The session does interact with some tree data and some census data, which were stored locally, but in the future would be their own Portolan catalogs. You can explore the underlying TriMet layers in the TriMet data browser.
All 3,239 Portland bus stops colored by nearby street-tree canopy.
Q2Interactive map + sortable ranked list; filter to the 367 double-jeopardy stops.
Q3Bar chart: the poorest fifth are 3.5× more likely to live near frequent service.
Q5~23,400 households with no car and no frequent service within ¼ mile.
I'd like to explore portland trimet data in a portolan catalog, at https://source.coop/cholmes/trimet I've also prepped a little catalog of data that would come from other portolan catalogs, the one here that you have access to Can you get up to speed with the data in the remote catalog? ANd then I'll ask you a series of questions about it. First one is: Portland gets pretty hot now. Which bus stops are the worst place to wait on a hot day, and is it spread evenly across the city?
Here's what the data says.
I read the shade question the way the tree dataset's own author framed it: on a 100°F day the thing that decides whether a stop is bearable is whether there's a tree canopy over it, so I measured each Portland bus stop against the City of Portland street-tree inventory. I used the TriMet route-stops layer (the only stop layer with a jurisdiction column), kept type = BUS, filtered to jurisdic = 'Portland' because tree coverage stops at the city line, and deduplicated to physical stops — 3,239 bus stops. Both catalogs are in EPSG:2913 (feet), so distances are literal feet with no reprojection.
The headline: shade is scarce and it is not spread evenly. About 23% of Portland bus stops (759) have no street tree at all within 100 ft, and 59% (1,911) have no large-canopy tree — the kind that actually throws shade at midday. The median stop has only four trees nearby, most of them small or medium.
The unevenness runs east–west. East of 82nd Avenue, 73% of stops lack a large-canopy tree and the average stop has 2.5 trees within 100 ft; west of 82nd it's 55% and 5.2 trees. The worst ZIP codes are all in outer East Portland — 97233 (Powellhurst-Gilbert) at 92% of stops with no large tree, then 97236 and 97266 (Lents / outer southeast). That flat, gridded, low-canopy east side is the genuinely heat-vulnerable part of the network — and it's the same area where the 2021 heat-dome deaths concentrated.
One important honesty check before you over-trust the "single worst stops" list. If you rank stops purely by distance to the nearest street tree, the top of the list is dominated by Southwest Portland — Boones Ferry, Taylors Ferry, the West Hills (97219, 97221, 97231). Those aren't actually treeless; they're forested hills. The inventory is street trees only, so park, forest, and private-yard canopy is invisible to it, and wooded SW reads as bare. In fact 275 of the 759 "no tree" stops sit in those SW hill ZIPs. So the literal worst-stop ranking is partly a data artifact — the robust, defensible finding is the outer-east canopy gap, not the SW hills.
I also checked whether it tracks neighborhood income (joining stops to ACS block groups). The relationship is weak and not clean — the poorest quintile has 63% of stops with no large tree versus 52% for the richest — and it's muddied by that same SW-forest effect inflating the high-income end. So this reads much more as an east/west geographic story than a straightforward rich/poor one.
Two caveats to carry forward: this is canopy shade only — it says nothing about whether a stop has a physical shelter (not in any of these layers), and nothing here is time-aware, so "worst to wait" assumes shade, not how long you'd actually stand there. The map above shows all 3,239 stops so you can see the concentration directly.
Want me to dig into any thread next — pull the real worst east-side stops by name, layer in shelters if we can find that data, or bring the no-vehicle / transit-dependence ACS variable into the equity angle?
Sources: TriMet Portolan catalog (route-stops); local demo-data-trimet catalog (pdx-street-trees, acs-block-groups).
let's bring in the no-vehicle / transit-dependence angle
This one genuinely surprised me, and it cuts against the obvious narrative.
Citywide, shade does not track transit dependence. If you sort stops by the no-vehicle share of their block group, the least-shaded quintile is actually the most car-owning one, and the most car-free neighborhoods are slightly better shaded (16% of their stops have no tree vs 28% in the most car-owning quintile; 5.2 trees per stop vs 4.6). The reason is that Portland's most carless block groups include the dense inner core and downtown, which sit under old, established canopy. So there's no smooth "people without cars get baked more" gradient across the city — measured as an average, the two things are nearly independent. Weighting confirms it: 65% of the metro's carless households are in block groups where most stops lack a large-canopy tree, versus 70% of all households — carless riders are, if anything, marginally less concentrated in low-shade areas than the general population.
The equity problem is real but it's a concentration, not a gradient — and pulling in the no-vehicle variable is what makes it legible, because it burns off the Southwest-hills false positives from last time (those wooded SW stops are high-income, high-car-ownership, so filtering to carless areas drops them automatically). What's left is a tight, trustworthy cluster in outer East Portland where very high car-free rates and zero shade land on the exact same stops:
These are the stops where someone who has no alternative to the bus is standing in full sun on a 100° day. That's the honest answer to "is it spread evenly": the deficit as a whole is concentrated in outer east, and once you overlay transit dependence, it narrows to a specific set of high-carless, zero-shade stops clustered around Gateway and the outer-southeast avenues — not a citywide rich/poor pattern.
Two caveats hold from before: still street-trees-only (no shelters), and no-vehicle share is a block-group average I've attached to each stop by point-in-polygon, so single-block-group values are noisy — the cluster is solid, any one stop's exact percentage less so.
Want me to map these double-jeopardy stops (high carless + no shade) as a highlighted layer, or rank the full list so you have every one of them, not just the top of each corridor?
Sure, give me an interactive app with a map and a ranked list
Let's move from the shade stuff, and just generally understand how equitably distributed transit is - Compare who actually lives near frequent service against neighborhood income.
That's delivered and saved to your artifact gallery as "trimet-heat-shade-risk" — reopen it anytime; click a row or dot to sync the map and list, and use the shade / no-vehicle filters to isolate the 367 double-jeopardy stops.
Now to your new question — equity of frequent service vs income. Here's the read.
Measuring who actually lives near frequent service — not just how much track there is — the distribution is strongly progressive by income. I took every frequent-service stop (TriMet's frequent flag on bus and MAX, 2,462 stops), drew a ¼-mile walkshed around them, and area-weighted each census block group's population into that walkshed, clipped to the service district. Across the district's 1.60 million residents, 36.7% live within a ¼-mile walk of frequent service.
But that average hides a steep gradient. Splitting residents into five equal-population income groups:
So the lowest-income residents are 3.5× more likely to live near frequent transit than the highest-income ones, and the drop-off is monotonic all the way down. The mechanism is density: TriMet's frequent grid follows the dense inner-Portland corridors where lower-income renters are concentrated, while wealthier households sit in the low-density West Hills and outer suburbs that the frequent network can't efficiently serve. By this measure the frequent network is equitably — even favorably — distributed relative to income.
Two things worth holding alongside that. First, it flips the shade story: the same low-income inner neighborhoods that are best served by frequent transit are also the better-shaded ones, while the outer-east stops from the last question are more often infrequent and treeless — so the people worst off on a hot day are a specific outer-east slice, not the low-income population broadly. Second, access by neighborhood racial composition tilts the same direction but much more gently — 32% near frequent service in the least-diverse fifth rising to 44% in the most — so the income signal here is far stronger than the race signal.
Caveats: "frequent" is TriMet's static designation, not live headways (nothing in this catalog is schedule-aware), and I used a straight-line ¼-mile buffer rather than actual network walking distance, which overstates access somewhat but shouldn't change the gradient.
Want me to map the served-vs-unserved areas so you can see where the unserved higher-income and unserved outer-east populations sit, or pivot to a different equity cut?
How does car ownership fit into these patterns?
Car ownership turns out to be the variable that reconciles the last two answers. Here's how it fits.
Carlessness is steeply income-driven. District-wide only about 9% of households (≈59,000 of 653,000) have no car, but that rate is almost entirely a low-income phenomenon — it runs 6× from top to bottom of the income ladder:
| Income fifth | % of households carless | Of those carless, % near frequent service |
|---|---|---|
| Poorest ($11–67k) | 19.6% | 74.1% |
| 2nd | 10.4% | 55.1% |
| Middle | 6.8% | 50.7% |
| 4th | 4.9% | 48.8% |
| Richest ($136–250k) | 3.2% | 28.7% |
So the "carless" population is mostly the same low-income inner population that the frequent grid already serves well — which is why the system looks well-aimed in aggregate. 60% of carless households live within a ¼-mile of frequent service, versus only 38% of car-owning households. TriMet is pointing frequent transit at the people who actually depend on it, and it compounds with income: three-quarters of the poorest carless households have frequent service, versus barely a quarter of the (few) wealthy carless ones.
But the gap that matters is the households that fall through: about 23,400 carless households — roughly 4 in 10 — are not within a ¼-mile of frequent service. These are people with no car and no nearby frequent bus, and they're an outer-ring phenomenon. The share of carless households who are stranded rises steadily with distance from downtown — 20% in the inner 3 miles, 33% in the 3–6 mile ring, 52% at 6–9 miles, and 63% beyond 9 miles. Density is the whole story: the frequent grid is an inner-city network, so a carless household in the low-density outer suburbs is largely on their own regardless of which direction they're in.
And that's the key correction to the east/west framing from before: stranded carless households split almost evenly east and west of 82nd (about 18,000 west, 5,000 east) at nearly identical rates (~40% each). Car-less-and-underserved is a suburban/outer condition on both sides — outer-west (Beaverton, Tigard, Lake Oswego fringes) as much as outer-east (Gresham, outer SE).
Where it becomes genuinely triple jeopardy is the narrow overlap: the outer-east carless are the ones who also sit in the low-canopy zone from the shade analysis, so they can face no car, thin frequent service, and no shade at once. The outer-west stranded carless at least tend to have more tree cover (and are somewhat wealthier). One honesty note: the tree data stops at the Portland city line, so for the far-outer suburbs I can speak to cars and transit but not shade.
So the throughline across all four questions: income drives car ownership, car ownership is what makes transit access a necessity rather than a convenience, the frequent network genuinely tracks that need in the dense core — and the real vulnerability is a specific outer, and especially outer-east, remainder that the density-driven network doesn't reach.
Want me to map those ~23,400 stranded carless households so you can see the outer-east vs outer-west split directly, or pull the specific outer-east block groups where all three disadvantages stack?
yeah, let's see those households on a map
There it is — saved as "trimet-stranded-carless" in your gallery too.
Reading the map: the darkest block groups are where the most households have no car and no frequent service within a ¼-mile — the deepest concentrations sit in outer Southeast/East Portland and Gresham on the east side, and out through Beaverton/Tigard/Aloha and the Clackamas fringe on the west. Toggle the green frequent-coverage layer off and the pattern is stark: nearly all the dark block groups sit in the white gaps between the frequent corridors, which follow the inner grid and the MAX lines. The inner core is almost entirely light — carless households there are well covered, so their stranded counts are near zero.
The second toggle (carless rate) tells the complementary story: the highest carless rates are still inner-city, but those areas aren't stranded because frequent service reaches them — so the rate view and the stranded-count view highlight almost opposite places. That's the whole equity picture in one map: carlessness concentrates in the served core, but the ~23,400 households where no-car and no-frequent-service overlap are pushed to the low-density outer ring, split fairly evenly east and west.
Want me to pull the specific outer-east block groups where this stacks with the no-shade finding — the handful carrying all three disadvantages at once — or take a different cut next?
Great, thanks. Which neighborhoods have lots of households without a car but no frequent transit service?
Confirmed — and it's a big artifact worth knowing about. TriMet's frequent flag covers only bus and MAX; the Portland Streetcar (106 stops) is never flagged frequent. So dense, carless inner neighborhoods that ride the streetcar were showing up as "stranded" when they aren't. Counting the streetcar as frequent, Northwest District drops from 2,021 stranded to 300, the Pearl from 317 to 30, South Waterfront from 495 to 146. I've discounted those in the answer below.
With that correction, here's where lots of carless households genuinely lack frequent service.
The largest raw concentrations are suburban — lower-density places with real carless populations that the bus/MAX frequent grid doesn't reach:
| Area | Stranded carless hh | Total carless hh | Median income |
|---|---|---|---|
| Beaverton | ~2,900 | 4,250 | $109k |
| Washington County (unincorp.) | ~1,950 | 2,430 | $104k |
| Clackamas County (unincorp.) | ~1,600 | 2,510 | $83k |
| Gresham | ~1,520 | 3,870 | $74k |
| Hillsboro | ~1,320 | 2,880 | $108k |
| Tigard | ~1,140 | 1,570 | $108k |
Within Portland proper, the neighborhoods that stand out — and the ones that matter most, because they combine many carless households with low incomes — are all in outer East Portland:
| Neighborhood | Stranded carless hh | Total carless hh | Median income |
|---|---|---|---|
| Hazelwood | ~370 | 2,230 | $62k |
| Powellhurst-Gilbert | ~170 | 1,560 | $68k |
| Lents | ~160 | 660 | $71k |
| Centennial | ~160 | 440 | $69k |
| Cully | ~270 | 630 | $76k |
| Wilkes | ~170 | 170 | $62k |
Hazelwood and Powellhurst-Gilbert are the clearest cases: together roughly 3,800 carless households, incomes in the low $60ks, sitting in the outer-east low-canopy zone from the earlier questions. They're partly touched by the MAX Blue/Green lines (which is why their stranded counts aren't higher), but large interior stretches are beyond a ¼-mile walk of anything frequent — so a lot of carless, lower-income residents there are on infrequent service. One genuine inner exception is Sellwood-Moreland (~580 stranded, no streetcar to explain it away) — an inner-SE bus-coverage gap.
So the short answer: by sheer numbers it's the west-side suburbs (Beaverton, Washington County, Hillsboro, Tigard) and Gresham; but the neighborhoods where "lots of carless households + weak frequent service + low income" truly stack are outer East Portland — Hazelwood and Powellhurst-Gilbert above all, with Lents, Centennial, Cully and Wilkes alongside.
Two caveats on the labels: Portland neighborhood names come from the street-tree inventory's neighborhood field (matched to each block group), and suburban "cities" are the nearest transit stop's jurisdiction — both are approximate near boundaries. And unincorporated Washington/Clackamas County counts are areas, not a single neighborhood.