Change background map for contextily

Sin*_*mer 6 python python-3.x geopandas contextily

I have this code:

import pandas as pd
import numpy as np
from geopandas import GeoDataFrame
import geopandas
from shapely.geometry import LineString, Point
import matplotlib.pyplot as plt
import contextily

''' Do Something'''

df = start_stop_df.drop('track', axis=1)
crs = {'init': 'epsg:4326'}
gdf = GeoDataFrame(df, crs=crs, geometry=geometry)

ax = gdf.plot()
contextily.add_basemap(ax)
ax.set_axis_off()
plt.show()
Run Code Online (Sandbox Code Playgroud)

Basically, this generates a background map that is in Singapore. However, when I run it, I get the following error: HTTPError: Tile URL resulted in a 404 error. Double-check your tile url:http://tile.stamen.com/terrain/29/268436843/268435436.png However, it still produces this image: 代码输出

How can I change the Tile URL? I would still like to have the map of Singapore as the base layer.

EDIT:
Also tried including this argument to add_basemap:
url ='https://www.openstreetmap.org/#map=12/1.3332/103.7987'
Which produced this error:
OSError: cannot identify image file <_io.BytesIO object at 0x000001CC3CC4BC50>

Mar*_*erc 10

首先确保您的 GeoDataframe 处于 Web 墨卡托投影 ( epsg=3857) 中。一旦您的 Geodataframe 被正确地理参考,您可以通过 Geopandas 重新投影来实现这一点:

df = df.to_crs(epsg=3857)
Run Code Online (Sandbox Code Playgroud)

完成此操作后,您可以轻松选择任何受支持的地图样式。contextily.sources在撰写本文时,可以在模块中找到完整列表:

### Tile provider sources ###

ST_TONER = 'http://tile.stamen.com/toner/tileZ/tileX/tileY.png'
ST_TONER_HYBRID = 'http://tile.stamen.com/toner-hybrid/tileZ/tileX/tileY.png'
ST_TONER_LABELS = 'http://tile.stamen.com/toner-labels/tileZ/tileX/tileY.png'
ST_TONER_LINES = 'http://tile.stamen.com/toner-lines/tileZ/tileX/tileY.png'
ST_TONER_BACKGROUND = 'http://tile.stamen.com/toner-background/tileZ/tileX/tileY.png'
ST_TONER_LITE = 'http://tile.stamen.com/toner-lite/tileZ/tileX/tileY.png'

ST_TERRAIN = 'http://tile.stamen.com/terrain/tileZ/tileX/tileY.png'
ST_TERRAIN_LABELS = 'http://tile.stamen.com/terrain-labels/tileZ/tileX/tileY.png'
ST_TERRAIN_LINES = 'http://tile.stamen.com/terrain-lines/tileZ/tileX/tileY.png'
ST_TERRAIN_BACKGROUND = 'http://tile.stamen.com/terrain-background/tileZ/tileX/tileY.png'

ST_WATERCOLOR = 'http://tile.stamen.com/watercolor/tileZ/tileX/tileY.png'

# OpenStreetMap as an alternative
OSM_A = 'http://a.tile.openstreetmap.org/tileZ/tileX/tileY.png'
OSM_B = 'http://b.tile.openstreetmap.org/tileZ/tileX/tileY.png'
OSM_C = 'http://c.tile.openstreetmap.org/tileZ/tileX/tileY.png'
Run Code Online (Sandbox Code Playgroud)

请记住,您不应在磁贴 URL 中添加实际的 x、y、z 磁贴编号(就像您在“编辑”示例中所做的那样)。ctx 会处理这一切。

您可以在GeoPandas 文档中找到一个有效的可复制粘贴示例和更多信息。

import contextily as ctx

# Dataframe you want to plot
gdf = GeoDataFrame(df, crs= {"init": "epsg:4326"}) # Create a georeferenced dataframe  
gdf = gdf.to_crs(epsg=3857) # reproject it in Web mercator
ax = gdf.plot()

# choose any of the supported maps from ctx.sources
ctx.add_basemap(ax, url=ctx.sources.ST_TERRAIN)
ax.set_axis_off()
plt.show()
Run Code Online (Sandbox Code Playgroud)


Sub*_*sad 6

Contextily 的默认crs 是 epsg:3857。但是,您的数据帧位于不同的 CRS 中。使用以下内容,请参阅此处的手册:

ctx.add_basemap(ax, crs='epsg:4326', source=ctx.providers.Stamen.TonerLite)
Run Code Online (Sandbox Code Playgroud)

请参阅此链接以了解如何使用不同的来源Stamen.Toner,例如Stamen.Terrain等(Stamen.Terrain默认使用)。

此外,您可以使用 将数据帧转换为 EPSG:3857 df.to_crs()。在这种情况下,您应该跳过函数crs内的参数ctx.add_basemap()