Skip to content

Commit 3c5593d

Browse files
author
Nathaniel Henry
committed
Add a fill argument to close_map() for graduated point and polygon maps.
1 parent 00f4993 commit 3c5593d

1 file changed

Lines changed: 35 additions & 17 deletions

File tree

src/closecity/map.py

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ def close_map(
1616
*,
1717
color: str = "#e8590c",
1818
highlight: Any = None,
19+
fill: Any = None,
20+
palette: str = "Viridis",
21+
reverse: bool = True,
1922
label: str = "name",
2023
size: int = 9,
2124
zoom: float = 10,
@@ -29,8 +32,10 @@ def close_map(
2932
``highlight`` so the ones that matter stand out.
3033
3134
``highlight`` is either a boolean sequence (length ``len(gdf)``) or the name
32-
of a boolean/0-1 column. ``label`` names the hover column. Returns a plotly
33-
``Figure``.
35+
of a boolean/0-1 column. ``fill`` is the name of a numeric column to shade
36+
features by, on a continuous scale with a legend (use it OR ``highlight``);
37+
``palette`` and ``reverse`` control that scale. ``label`` names the hover
38+
column. Returns a plotly ``Figure``.
3439
"""
3540
try:
3641
import plotly.graph_objects as go
@@ -44,40 +49,53 @@ def close_map(
4449
if highlight is not None:
4550
col = g[highlight] if isinstance(highlight, str) else highlight
4651
hl = [bool(v) for v in col]
52+
fv = None
53+
if fill is not None and isinstance(fill, str) and fill in g.columns:
54+
fv = g[fill].astype(float).tolist()
4755

4856
minx, miny, maxx, maxy = g.total_bounds
4957
center = {"lon": (minx + maxx) / 2, "lat": (miny + maxy) / 2}
5058
hover = g[label].astype(str).tolist() if label in g.columns else None
5159
geom_type = g.geom_type.iloc[0] if len(g) else "Point"
5260

5361
if "Point" in geom_type:
54-
marker_color = color if hl is None else [
55-
color if h else "#888888" for h in hl
56-
]
62+
if fv is not None:
63+
marker = dict(size = size, color = fv, colorscale = palette,
64+
reversescale = reverse, showscale = True,
65+
colorbar = dict(title = fill))
66+
else:
67+
marker_color = color if hl is None else [
68+
color if h else "#888888" for h in hl
69+
]
70+
marker = dict(size = size, color = marker_color)
5771
fig = go.Figure(go.Scattermapbox(
5872
lat = g.geometry.y.tolist(), lon = g.geometry.x.tolist(),
59-
mode = "markers",
60-
marker = dict(size = size, color = marker_color),
73+
mode = "markers", marker = marker,
6174
text = hover, hoverinfo = "text" if hover else "none",
6275
))
6376
else:
6477
import json
6578

6679
g = g.reset_index(drop = True)
6780
g["_id"] = [str(i) for i in range(len(g))]
68-
z = [1] * len(g) if hl is None else [int(h) for h in hl]
6981
geojson = json.loads(g[["_id", "geometry"]].to_json())
70-
colorscale = (
71-
[[0, color], [1, color]] if hl is None
72-
else [[0, "#888888"], [1, color]]
73-
)
74-
fig = go.Figure(go.Choroplethmapbox(
75-
geojson = geojson, locations = g["_id"].tolist(), z = z,
76-
featureidkey = "properties._id", colorscale = colorscale,
77-
showscale = False,
82+
common = dict(
83+
geojson = geojson, locations = g["_id"].tolist(),
84+
featureidkey = "properties._id",
7885
marker = dict(opacity = opacity, line = dict(width = 0)),
7986
text = hover, hoverinfo = "text" if hover else "none",
80-
))
87+
)
88+
if fv is not None:
89+
trace = go.Choroplethmapbox(
90+
z = fv, colorscale = palette, reversescale = reverse,
91+
showscale = True, colorbar = dict(title = fill), **common)
92+
else:
93+
z = [1] * len(g) if hl is None else [int(h) for h in hl]
94+
colorscale = ([[0, color], [1, color]] if hl is None
95+
else [[0, "#888888"], [1, color]])
96+
trace = go.Choroplethmapbox(
97+
z = z, colorscale = colorscale, showscale = False, **common)
98+
fig = go.Figure(trace)
8199

82100
fig.update_layout(
83101
mapbox = dict(style = "carto-positron", zoom = zoom, center = center),

0 commit comments

Comments
 (0)