Jki*_*fn1 6 python mapbox plotly
Scattergeo我正在尝试在密度地图框顶部添加跟踪或叠加层white-bg,以获取通用美国各州轮廓的热图。
我使用的原因scattergeo是我想在密度地图框的顶部绘制一个星形符号,并且唯一接受的符号add_scattermapbox是一个点。如果您选择star符号,则不会添加任何符号。
mapbox_styles我还知道星号对于add_scattermapbox或 的p 是可以接受的density_scattermapbox,但目前我无法在试用金额用完后按网络负载付费。
有没有一种聪明的方法可以在图上添加星号density_mapbox?
工作分散地理
fig = go.Figure(go.Scattergeo())
fig.add_scattergeo(lat = [30, 40]
,lon = [-90, -80]
,hoverinfo = 'none'
,marker_size = 10
,marker_color = 'rgb(65, 105, 225)' # blue
,marker_symbol = 'star'
,showlegend = False
)
fig.update_geos(
visible=False, resolution=110, scope="usa",
showcountries=True, countrycolor="Black",
showsubunits=True, subunitcolor="Black"
)
fig.show()
Run Code Online (Sandbox Code Playgroud)
工作密度Mapbox
d = {'Location': ['Point A', 'Point B'], 'lat': [30, 40], 'long': [-90, -80], 'z': [100,200]}
df = pd.DataFrame(data=d)
fig = px.density_mapbox(df
,lat='lat'
,lon='long'
,z='z'
,hover_name='Location'
,center=dict(lat=38.5, lon=-96)
,range_color = [0, 200]
,zoom=2
,radius=50
,opacity=.5
,mapbox_style='open-street-map')
fig.add_scattermapbox(lat = [30, 40]
,lon = [-90, -80]
,hoverinfo = 'none'
,marker_size = 6
,marker_color = 'rgb(0, 0, 0)'
# ,marker_symbol = 'star'
,showlegend = False
)
fig.show()
Run Code Online (Sandbox Code Playgroud)
尝试#1 - 只需设置marker_symbol = 'star'
取消注释marker_symbol = 'star',这适用于 的高级样式mapbox,完全消除了分散点。
d = {'Location': ['Point A', 'Point B'], 'lat': [30, 40], 'long': [-90, -80], 'z': [100,200]}
df = pd.DataFrame(data=d)
fig = px.density_mapbox(df
,lat='lat'
,lon='long'
,z='z'
,hover_name='Location'
,center=dict(lat=38.5, lon=-96)
,range_color = [0, 200]
,zoom=2
,radius=50
,opacity=.5
,mapbox_style='open-street-map')
fig.add_scattermapbox(lat = [30, 40]
,lon = [-90, -80]
,hoverinfo = 'none'
,marker_size = 6
,marker_color = 'rgb(0, 0, 0)'
,marker_symbol = 'star'
,showlegend = False
)
fig.show()
Run Code Online (Sandbox Code Playgroud)
尝试 #2 - 在散点地理顶部添加密度地图框
density_mapbox在顶部添加scattergeo会产生相同的地理图,但仅此而已。密度图框图例在那里,但没有热图。
d = {'Location': ['Point A', 'Point B'], 'lat': [30, 40], 'long': [-90, -80], 'z': [100,200]}
df = pd.DataFrame(data=d)
fig = go.Figure(go.Scattergeo())
fig.add_scattergeo(lat = [30, 40]
,lon = [-90, -80]
,hoverinfo = 'none'
,marker_size = 10
,marker_color = 'rgb(65, 105, 225)' # blue
,marker_symbol = 'star'
,showlegend = False
)
fig.add_densitymapbox(lat=df['lat'],
lon=df['long'],
z=df['z'],
radius=50,
opacity=.5
)
fig.update_geos(
visible=False, resolution=110, scope="usa",
showcountries=True, countrycolor="Black",
showsubunits=True, subunitcolor="Black"
)
fig.show()
Run Code Online (Sandbox Code Playgroud)
平铺图和图层图不能一起使用。因此,您不能在地图盒上使用地理标记
横向思考,您可以将自己的geojson图层添加到Mapbox图上
生成几何图形。为此提供了两种选择
get_geom(df["long"], df["lat"], marker=None, size=k)get_geom(df["long"], df["lat"], marker="star", size=k)其中,marker是 MAKI 图标名称。NB 有洞的图标可以填写 - 例如注意向 Mapbox 图形布局添加图层。这被参数化以生成多个层以支持不同的缩放级别。更多层,更多开销。
import geopandas as gpd
import pandas as pd
import shapely.geometry
import math
import json
import plotly.express as px
import svgpath2mpl
import requests
import numpy as np
d = {
"Location": ["Point A", "Point B"],
"lat": [30, 40],
"long": [-90, -80],
"z": [100, 200],
}
df = pd.DataFrame(data=d)
fig = px.density_mapbox(
df,
lat="lat",
lon="long",
z="z",
hover_name="Location",
center=dict(lat=38.5, lon=-96),
range_color=[0, 200],
zoom=2,
radius=50,
opacity=0.5,
mapbox_style="open-street-map",
)
# /sf/ask/1638818191/
def polygon(sides, radius=1, rotation=0, translation=None):
one_segment = math.pi * 2 / sides
points = [(math.sin(one_segment * i + rotation) * radius,
math.cos(one_segment * i + rotation) * radius,)
for i in range(sides)]
if translation:
points = [[sum(pair) for pair in zip(point, translation)] for point in points]
return shapely.geometry.Polygon(points)
def makimarker(makiname="star", geo=(0, 0), size=0.1):
url = f"https://raw.githubusercontent.com/mapbox/maki/main/icons/{makiname}.svg"
svgpath = pd.read_xml(requests.get(url).text).loc[0, "d"]
p = svgpath2mpl.parse_path(svgpath).to_polygons()
# need centroid to adjust marked to be centred on geo location
c = shapely.affinity.scale(
shapely.geometry.Polygon(p[0]), xfact=size, yfact=size
).centroid
# centre and place marker
marker = shapely.geometry.Polygon(
[[sum(triple) for triple in zip(point, geo, (-c.x, -c.y))] for point in p[0]]
)
# finally size geometry
return shapely.affinity.scale(marker, xfact=size, yfact=size)
def get_geom(long_a: list, lat_a: list, marker=None, size=0.15) -> list:
if marker:
geo = [
makimarker(marker, geo=(long, lat), size=size)
for long, lat in zip(long_a, lat_a)
]
else:
geo = [
polygon(3, translation=(long, lat), radius=size*10)
for long, lat in zip(long_a, lat_a)
]
return json.loads(gpd.GeoDataFrame(geometry=geo).to_json())
# basing math on this https://wiki.openstreetmap.org/wiki/Zoom_levels
# dict is keyed by size with min/max zoom levels covered by this size
MINZOOM=.1
MAXZOOM=18
LAYERS=7
zoom = 512**np.linspace(math.log(MINZOOM,512), math.log(MAXZOOM, 512), LAYERS)
zoom = {
(200/(2**(np.percentile(zoom[i:i+2],25)+9))): {"minzoom":zoom[i], "maxzoom":zoom[i+1], "name":i}
for i in range(LAYERS-1)
}
# add a layers to density plot that are the markers
fig.update_layout(
mapbox={
"layers": [
{
"source": get_geom(df["long"], df["lat"], marker="star", size=k),
"type": "fill",
"color": "blue",
**zoom[k],
}
for k in zoom.keys()
]
},
margin={"t": 0, "b": 0, "l": 0, "r": 0},
)
fig
Run Code Online (Sandbox Code Playgroud)