【发布时间】:2022-04-28 20:21:14
【问题描述】:
我正在使用 plotly 的 Scattermapbox 用由 datashader 的阴影功能(基于 https://plotly.com/python/datashader/)创建的多边形的阴影图像覆盖地图,但投影似乎没有对齐,见下图。有什么建议我可以使用 plotly 的 Scattermapbox 和 datashader 解决这个问题吗?
可重现的例子:
import geopandas as gpd
import plotly.graph_objects as go
import spatialpandas as spd
import datashader as ds
from colorcet import fire
import datashader.transfer_functions as tf
# load data
world = gpd.read_file(
gpd.datasets.get_path('naturalearth_lowres')
)
# world = world.to_crs(epsg=3857)
# create spatialpandas DataFrame
df_world = spd.GeoDataFrame(world)
# create datashader canvas and aggregate
cvs = ds.Canvas(plot_width=1000, plot_height=1000)
agg = cvs.polygons(df_world, geometry='geometry', agg=ds.mean('pop_est'))
# create shaded image
tf.shade(agg, cmap=fire)
# create shaded image and convert to Python image
img = tf.shade(agg, cmap=fire)[::-1].to_pil()
coords_lat, coords_lon = agg.coords["y"].values, agg.coords["x"].values
# Corners of the image, which need to be passed to mapbox
coordinates = [
[coords_lon[0], coords_lat[0]],
[coords_lon[-1], coords_lat[0]],
[coords_lon[-1], coords_lat[-1]],
[coords_lon[0], coords_lat[-1]],
]
fig = go.Figure(go.Scattermapbox())
fig.update_layout(
mapbox_style="open-street-map",
mapbox_layers=[
{
"sourcetype": "image",
"source": img,
"coordinates": coordinates,
}
]
)
fig.show()
我读到 Scattermapbox 仅支持墨卡托投影,我发现这很令人困惑,因为 plotly 文档中的示例似乎是 long/lat 格式,但我尝试将 GeoDataFrame 的坐标转换为 epsg 3857,请参阅
# world = world.to_crs(epsg=3857)
结果是阴影图像变得不可见。任何帮助将不胜感激。
【问题讨论】:
-
很有趣
-
我已经查看了这方面的多个方面......我怀疑坐标是错误的,但微调没有什么区别。我认为 Datashader 创建的 xarray 是错误的 - 但是,如果我重新创建 pandas 数据框并执行密度映射框,那就没问题了。所以在死胡同...
-
我建议在 dash.plotly.com/holoviews 处使用基于 HoloViews 的说明来使用 Datashader 和 plotly,但由于这些说明不涵盖多边形,或者如果您只想手动执行,您可以使用datashader.utils.lnglat_to_meters 函数转换原始坐标(见stackoverflow.com/a/51385389/5909839)。
-
@JamesA.Bednar 感谢您的建议。我想使用 plotly 图形对象库中的 Scattermapbox 的原因是能够在“update_layout”调用中使用选项“'below':'water'”添加图层。我没有使用 holoviews 找到类似的东西。
-
标签: python-3.x plotly mapbox projection datashader