Skip to content

Commit 8d3c8ea

Browse files
author
Nathaniel Henry
committed
Add a mark argument to close_map() for marking a point with an X.
1 parent b046caf commit 8d3c8ea

3 files changed

Lines changed: 28 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
data, shows every attribute on hover, defaults to the ColorBrewer `YlGnBu`
1010
scale (blue = most accessible), and takes a `boundary` outline and
1111
semi-transparent `background` layers (e.g. a city boundary, commute isochrones,
12-
or a walkshed under its POIs).
12+
or a walkshed under its POIs). A `mark` argument drops an X on a point of
13+
interest (e.g. a starting point).
1314

1415
## 1.3.0
1516

src/closecity/map.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ def close_map(
109109
background=None,
110110
background_color: Any = "#3b6fb0",
111111
background_opacity: float = 0.3,
112+
mark=None,
112113
buffer: float = 0.15,
113114
):
114115
"""Draw a :class:`geopandas.GeoDataFrame` from a client method as an
@@ -130,7 +131,8 @@ def close_map(
130131
(e.g. a city boundary from ``place_boundary``). ``background`` is one polygon
131132
GeoDataFrame, or a list of them, drawn as semi-transparent fills underneath
132133
(e.g. commute isochrones or a walkshed); ``background_color`` recycles across
133-
them. Returns a plotly ``Figure``.
134+
them. ``mark`` draws an "✕" on top at a ``(lon, lat)`` pair or a point
135+
GeoDataFrame (e.g. a starting point). Returns a plotly ``Figure``.
134136
"""
135137
try:
136138
import plotly.graph_objects as go
@@ -237,6 +239,22 @@ def close_map(
237239
traces.append(go.Choroplethmapbox(
238240
z=z, colorscale=colorscale, showscale=False, **common))
239241

242+
# A point marked with an "✕", drawn last so it sits on top of everything.
243+
if mark is not None:
244+
import geopandas as gpd
245+
246+
if isinstance(mark, (gpd.GeoDataFrame, gpd.GeoSeries)):
247+
geom = (mark.geometry if isinstance(mark, gpd.GeoDataFrame) else mark)
248+
geom = geom.to_crs(4326)
249+
mlon, mlat = list(geom.x), list(geom.y)
250+
else:
251+
mlon, mlat = [mark[0]], [mark[1]]
252+
bounds.append([min(mlon), min(mlat), max(mlon), max(mlat)])
253+
traces.append(go.Scattermapbox(
254+
lon=mlon, lat=mlat, mode="text", text=["✕"] * len(mlon),
255+
textfont={"size": 22, "color": "#111111"},
256+
hoverinfo="skip", showlegend=False))
257+
240258
center, zoom = _center_zoom(bounds, buffer)
241259
fig = go.Figure(traces)
242260
fig.update_layout(

tests/test_map.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ def test_close_map_shades_by_fill():
4747
assert isinstance(fig, go.Figure)
4848

4949

50+
def test_close_map_mark():
51+
import plotly.graph_objects as go
52+
fig = close_map(_points(), mark = (-71.41, 41.82))
53+
assert isinstance(fig, go.Figure)
54+
assert fig.data[-1].mode == "text"
55+
56+
5057
def test_close_map_boundary_and_background_layers():
5158
import plotly.graph_objects as go
5259
polys = _polys()

0 commit comments

Comments
 (0)