如何使用Python Plotly导出OSM地图/绘图为矢量图形
问题
执行以下Plotly代码导出PDF后,地图及标记点都是嵌入的栅格图形,而非完整的矢量图形:
import pandas as pd us_cities = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/us-cities-top-1k.csv") import plotly.express as px fig = px.scatter_mapbox(us_cities, lat="lat", lon="lon", hover_name="City", hover_data=["State", "Population"], color_discrete_sequence=["fuchsia"], zoom=3, height=300) fig.update_layout(mapbox_style="open-street-map") fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0}) fig.write_image('/tmp/so.pdf')
导出的栅格效果如下:
请问怎么把OpenStreetMap绘图导出成完整的矢量图形?
解决方案
核心原因
你用的open-street-map是栅格瓦片服务,它提供的地图本身就是位图格式,所以导出PDF时只能嵌入栅格图。要得到矢量地图,必须换成矢量瓦片源或者用矢量形式的地图组件。
方法一:用Mapbox官方矢量瓦片(需要API密钥)
Mapbox有自带的矢量地图样式,导出PDF时能保留矢量属性,步骤如下:
- 去Mapbox官网注册账号,免费获取API密钥;
- 修改代码,指定矢量样式并配置密钥:
import pandas as pd import plotly.express as px us_cities = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/us-cities-top-1k.csv") # 替换成你自己的Mapbox API密钥 mapbox_token = "你的Mapbox API密钥" fig = px.scatter_mapbox(us_cities, lat="lat", lon="lon", hover_name="City", hover_data=["State", "Population"], color_discrete_sequence=["fuchsia"], zoom=3, height=300) # 选用Mapbox矢量样式,比如streets、light、dark等 fig.update_layout(mapbox_style="streets", mapbox_access_token=mapbox_token) fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0}) fig.write_image('/tmp/so_vector.pdf')
方法二:改用Plotly Geo矢量图表
如果不想依赖第三方服务,可以用Plotly的scatter_geo,它基于矢量地理轮廓数据,导出的PDF里地图和点都是矢量:
import pandas as pd import plotly.express as px us_cities = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/us-cities-top-1k.csv") fig = px.scatter_geo(us_cities, lat="lat", lon="lon", hover_name="City", hover_data=["State", "Population"], color_discrete_sequence=["fuchsia"], projection="albers usa") fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0}) fig.write_image('/tmp/so_geo_vector.pdf')
注意:这个方法的地图是简化的地理轮廓,没有OpenStreetMap那样的街道等细节,胜在完全矢量且不需要额外密钥。
方法三:用开源矢量瓦片服务
可以自己配置开源的矢量瓦片源(比如OpenMapTiles),通过mapbox.layers添加矢量图层,示例代码框架如下:
import pandas as pd import plotly.express as px us_cities = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/us-cities-top-1k.csv") fig = px.scatter_mapbox(us_cities, lat="lat", lon="lon", hover_name="City", hover_data=["State", "Population"], color_discrete_sequence=["fuchsia"], zoom=3, height=300) fig.update_layout( mapbox={ "style": "white-bg", "layers": [ { "source": {"type": "vector", "url": "你的矢量瓦片服务地址"}, "below": "traces", "type": "fill", "paint": {"fill-color": "#f0f0f0"} # 需根据矢量瓦片的图层属性调整样式配置 } ] }, margin={"r":0,"t":0,"l":0,"b":0} ) fig.write_image('/tmp/so_custom_vector.pdf')
内容的提问来源于stack exchange,提问作者Suuuehgi
相关产品推荐
相关产品推荐

