Reputation: 8100
If I modify one of the Plotly examples ("Lines on Mapbox maps using Scattermapbox traces") to use a different marker, these markers no longer appear on the map.
How do I get other kinds of supported markers to display?
import plotly.graph_objects as go
# Circles appear
fig = go.Figure(go.Scattermapbox(
mode = "markers+lines",
lon = [10, 20, 30],
lat = [10, 20,30],
marker = {'size': 10, 'symbol':'circle'}))
# Markers do not
fig.add_trace(go.Scattermapbox(
mode = "markers+lines",
lon = [-50, -60,40],
lat = [30, 10, -20],
marker = {'size': 10, 'symbol':'marker'}))
fig.update_layout(
margin ={'l':0,'t':0,'b':0,'r':0},
mapbox = {
'center': {'lon': 10, 'lat': 10},
'style': "stamen-terrain",
'center': {'lon': -20, 'lat': -20},
'zoom': 1})
fig.show()
The example code posted by empet in this forum does not render for me at all (other than the title)
Upvotes: 2
Views: 2260
Reputation: 122
I had the same issue as expained in the topic:
The example code posted by empet in this forum does not render for me at all (other than the title)
By looking at the browser console logs, I saw these error messages:
ERROR: Uses Mapbox map style, but did not set an access token.
ERROR: Missing Mapbox access token.
Mapbox trace type require a Mapbox access token to be registered.
For example:
Plotly.newPlot(gd, data, layout, { mapboxAccessToken: 'my-access-token' });
More info here: https://www.mapbox.com/help/define-access-token/
If you add an access token the example from the forum will render.
Moreover, according to plotly documentation, setting the symbol attribute will only work for Mapbox provided styles, so it won't work for stamen-terrain
.
Despite this, I still encounter weird issues for specific map-style/marker-symbol combinations.
Upvotes: 0
Reputation: 31226
import requests
import svgpath2mpl, shapely.geometry, shapely.affinity
from pathlib import Path
from zipfile import ZipFile
import pandas as pd
import geopandas as gpd
import json
import numpy as np
# download maki icons
# https://github.com/mapbox/maki/tree/main/icons
f = Path.cwd().joinpath("maki")
if not f.is_dir():
f.mkdir()
f = f.joinpath("maki.zip")
if not f.exists():
r = requests.get("https://github.com/mapbox/maki/zipball/main")
with open(f, "wb") as f:
for chunk in r.iter_content(chunk_size=128):
f.write(chunk)
fz = ZipFile(f)
fz.extractall(f.parent)
def to_shapely(mpl, simplify=0):
p = shapely.geometry.MultiPolygon([shapely.geometry.Polygon(a).simplify(simplify) for a in mpl])
p = shapely.affinity.affine_transform(p,[1, 0, 0, -1, 0, 0],)
p = shapely.affinity.affine_transform(p,[1, 0, 0, 1, -p.centroid.x, -p.centroid.y],)
return p
# convert SVG icons to matplolib geometries and then into shapely geometries
# keep icons in dataframe for further access...
SIMPLIFY=.1
dfi = pd.concat(
[
pd.read_xml(sf).assign(
name=sf.stem,
mpl=lambda d: d["d"].apply(
lambda p: svgpath2mpl.parse_path(p).to_polygons()
),
shapely=lambda d: d["mpl"].apply(lambda p: to_shapely(p, simplify=SIMPLIFY)),
)
for sf in f.parent.glob("**/*.svg")
]
).set_index("name")
# build a geojson layer that can be used in plotly mapbox figure layout
def marker(df, marker="marker", size=1, color="green", lat=51.379997, lon=-0.406042):
m = df.loc[marker, "shapely"]
if isinstance(lat, float):
gs = gpd.GeoSeries(
[shapely.affinity.affine_transform(m, [size, 0, 0, size, lon, lat])]
)
elif isinstance(lat, (list, pd.Series, np.ndarray)):
gs = gpd.GeoSeries(
[
shapely.affinity.affine_transform(m, [size, 0, 0, size, lonm, latm])
for latm, lonm in zip(lat, lon)
]
)
return {"source":json.loads(gs.to_json()), "type":"fill", "color":color}
# display all icons to make sure they look ok...
gpd.GeoSeries(
[
shapely.affinity.affine_transform(
s, [1, 0, 0, 1, (i % 20) * 20, (i // 20) * 20]
)
for i, s in enumerate(dfi["shapely"])
]
).plot()
dfi.loc["karaoke", "shapely"]
import plotly.graph_objects as go
# Circles appear
fig = go.Figure(
go.Scattermapbox(
mode="markers+lines",
lon=[10, 20, 30],
lat=[10, 20, 30],
marker={"size": 10, "symbol": "circle"},
)
)
# Markers do not
fig.add_trace(
go.Scattermapbox(
mode="markers+lines",
lon=[-50, -60, 40],
lat=[30, 10, -20],
marker={"size": 10, "symbol": "circle"},
)
)
fig.update_layout(
margin={"l": 0, "t": 0, "b": 0, "r": 0},
mapbox={
"center": {"lon": 10, "lat": 10},
"style": "stamen-terrain",
"center": {"lon": -20, "lat": -20},
"zoom": 1,
},
)
fig.update_layout(
mapbox={
"layers": [
marker(
dfi, "soccer", size=.5, color="blue", lon=[10, 20, 30], lat=[10, 20, 30]
),
marker(
dfi, "star", size=.5, color="red", lon=[-50, -60, 40], lat=[30, 10, -20]
),
]
}
)
Upvotes: 2