Add Choropleth and ChoroplethMap trace types#2
Open
jqnatividad wants to merge 10 commits into
Open
Conversation
Adds choropleth (filled-region) map support, mirroring the existing geo trace pattern: - Choropleth<Loc, Z> on the geo subplot (LayoutGeo), with a LocationMode enum (ISO-3 / USA-states / country names / geojson-id), a dedicated choropleth::Marker (boundary line + opacity), Selection, and the shared colorscale/colorbar machinery. geojson accepts a URL string or an inline GeoJSON object (serde_json::Value). - ChoroplethMap<Loc, Z> on the MapLibre `map` subplot (GeoJSON-only). - New LayoutMap / MapStyle / MapBounds for the `map` subplot, wired into Layout (mirrors the existing mapbox subplot). Registers both PlotType variants and top-level/sub-module re-exports, adds serialization + doc tests, runnable examples (examples/maps), and a "Maps / Choropleth Maps" book recipe page. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The `map` subplot (MapLibre) does not support the legacy Stamen mapbox styles. Replace the Stamen* variants with the bundled plotly.js map styles from the v3.6.0 schema: add carto-voyager and the carto-*-nolabels variants. Update the serialization test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Include the generated inline HTML for the choropleth and choropleth_map examples in the Choropleth Maps recipe page, and add `maps` to the book's BOOK_EXAMPLES so the inline output is generated during the book build. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The maps example is now part of the book build. scatter_geo fetched a remote CSV with unwrap(), which would panic (and fail the book CI) if the URL were unreachable. Handle fetch/HTTP errors gracefully: warn and skip the example so the remaining maps examples still generate. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extend the fail-safe path beyond the fetch: handle CSV header and record parse errors with warn-and-return, and resolve the lat/lon column indices up front (warn-and-return if a column is missing), defaulting missing cells to NaN. Malformed or schema-changed upstream data can no longer panic the book build. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Expose Plotly's `geo.fitbounds` attribute on `LayoutGeo` via a typed `GeoFitBounds` enum (`Locations` / `GeoJson`), serialized as the strings `"locations"` / `"geojson"`. Setting `fitbounds = "locations"` frames a geo subplot to the union of a choropleth trace's filled region geometries, so callers can fit the view to whole countries/states rather than to the source point extent (which clips the regions at the edges). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a GeoFitBounds::False variant with a custom Serialize impl that emits the boolean `false` (the schema allows [false, "locations", "geojson"]), so callers can explicitly override/clear a non-default fitbounds value. Also add the missing `#[serde_with::skip_serializing_none]` to LayoutGeo, which was serializing `null` for every unset field; this fixes the fitbounds test and the pre-existing serialize_layout_geo test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Expose Plotly.js `geo.resolution` via a type-safe `GeoResolution` enum (`OneOverOneHundredTenMillion` -> 110, the default; `OneOverFiftyMillion` -> 50) serialized as the numeric scale denominator. 50 selects the higher-detail 1:50,000,000 base layers (coastlines, land, borders). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Demonstrate `LayoutGeo::resolution(GeoResolution::OneOverFiftyMillion)` for higher-detail base layers in the choropleth example. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Expose plotly.js's `layout.geo.bgcolor` attribute on the typed `LayoutGeo` builder. It was already honored by plotly.js (settable via relayout) but had no Rust setter, so the geo subplot background — the area outside land/ocean polygons (e.g. the corners around a non-rectangular projection) — couldn't be themed from Rust. Mirrors the existing land/ocean/lake color fields (FieldSetter-generated `.bgcolor(impl Color)`, serde key `bgcolor`). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds Choropleth map support (addresses plotly#408).
What's added
Trace types
Choropleth<Loc, Z>— classic choropleth on the existinggeosubplot (LayoutGeo). Includes aLocationModeenum (ISO-3/USA-states/country names/geojson-id), a dedicatedchoropleth::Marker(region-boundaryline+opacity),Selection/SelectionMarker, z-bounds, and the sharedColorScale/ColorBarmachinery.geojsonaccepts a URL string or an inline GeoJSON object (serde_json::Value).ChoroplethMap<Loc, Z>— the modern plotly.js 3.xchoroplethmaptrace on the MapLibremapsubplot (GeoJSON-only).Layout
LayoutMap+MapStyle+MapBounds— the MapLibremapsubplot, which the crate did not have before (onlymapbox). Mirrors the existingMapboxsubplot and is wired intoLayout.LayoutGeoenhancements for the classicgeosubplot:fitbounds(GeoFitBounds:false/locations/geojson) — auto-frames the subplot to the plotted data, overridingcenter/lonaxis/lataxiswhen set.resolution(GeoResolution:OneOverOneHundredTenMillion→110default,OneOverFiftyMillion→50) — selects base-layer detail. Per plotly.js, the value is the scale denominator (110= 1:110,000,000), so50gives higher-detail coastlines/land/borders. Pairs naturally with the UN geodata that became the plotly.js v3.1.0 default (we bundle 3.6.0).Plumbing, tests, docs
PlotType::Choropleth/PlotType::ChoroplethMapvariants and top-level + sub-module re-exports.examples/maps(choropleth+choropleth_map), and a new Maps → Choropleth Maps book recipe page.Verification
cargo build --features all+plotly_embed_js; native + wasmclippyclean;cargo +nightly fmt.examples/mapsbuilds and lints clean.Notes
plot-schema.json(traces.choropleth,traces.choroplethmap,layout.map).mapsis intentionally not added to the automated book-example build because itsmain()performs a network fetch (scatter_geo) and isn't part of CI'sBOOK_EXAMPLES.PlotTypevariants + new layout/trace fields generate newRestyle*/Relayout*enum variants), so this targets the next breaking release (0.15.0), consistent with the other in-flight work.🤖 Generated with Claude Code