- using this helper https://github.com/Turbo87/utm to transform between GPS (WSG84 / EPSG:4326) and UTM
- you expressed that POI circle/polygon radius as a distance
`x miles`

hence need to work with UTM projections to express radius as a distances
- have used UK hospitals as sample POI data. Without significant zoom levels circles will not display as they are only 1 mile radius. It will be simple to plug in any other dataframe with
**latitude** and **longitude** columns
- used a
**scatter mapbox** as sample plot, then added **layer** that are POI circles/polygons

```
import shapely.geometry
import utm
import pandas as pd
import geopandas as gpd
import requests, io, json
import plotly.express as px
# need to use UTM to express radius as a distance. UTM is zoned, so if GPS coords are very widely distributed
# distance will be incorrect. zone is estimated from first GPS coordinate
# returns geopandas dataframe re-projected to GPS co-ordinates
# radius is expressed in metres
def circles(lonlat, radius=10 ** 4):
utm_coords = utm.from_latlon(lonlat[:, 1], lonlat[:, 0])
utmcrs = gpd.GeoDataFrame(
geometry=[shapely.geometry.Point(lonlat[0, 0], lonlat[0, 1])], crs="EPSG:4326"
).estimate_utm_crs()
return gpd.GeoDataFrame(
geometry=[
shapely.geometry.Point(easting, northing).buffer(radius)
for easting, northing in zip(utm_coords[0], utm_coords[1])
],
crs=utmcrs,
).to_crs("EPSG:4326")
# get some public addressess - hospitals. data that can be scattered
dfhos = pd.read_csv(io.StringIO(requests.get("http://media.nhschoices.nhs.uk/data/foi/Hospital.csv").text),
sep="¬",engine="python",)
# generate circles of diameter 1 mile, which is 1609.34 metres
gdf = circles(dfhos.head(20).loc[:, ["Longitude", "Latitude"]].values, radius=1609.34)
fig = (
px.scatter_mapbox(
dfhos.head(20),
lat="Latitude",
lon="Longitude",
color="Sector",
hover_data=["OrganisationName", "Postcode"],
)
.update_traces(marker={"size": 10})
.update_layout(
mapbox={
"style": "open-street-map",
"zoom": 9,
"center":{"lat":gdf.loc[0,"geometry"].centroid.y, "lon":gdf.loc[0,"geometry"].centroid.x},
"layers": [
{
"source": json.loads(gdf.geometry.to_json()),
"below": "traces",
"type": "line",
"color": "purple",
"line": {"width": 1.5},
}
],
},
margin={"l": 0, "r": 0, "t": 0, "b": 0},
)
)
fig.show()
```