我有一个小csv,它有来自英格兰伯明翰的6个坐标。我用pandas读取csv,然后将其转换为GeoPandas数据帧,用形状优美的点更改纬度和经度列。我现在正试图绘制我的GeoDataframe,我能看到的只是点。我怎样才能把伯明翰地图也画出来?如能提供有关GeoPandas的良好文档资料,也将不胜感激。
from shapely.geometry import Point
import geopandas as gpd
import pandas as pd
df = pd.read_csv('SiteLocation.csv')
df['Coordinates'] = list(zip(df.LONG, df.LAT))
df['Coordinates'] = df['Coordinates'].apply(Point)
# Building the GeoDataframe
geo_df = gpd.GeoDataFrame(df, geometry='Coordinates')
geo_df.plot()
试试df。一元联盟。该函数将点聚合为单个几何体。Jupyter笔记本可以绘制它
只想添加有关缩放的用例,根据新的xlim
和ylim
坐标更新底图。我提出的解决方案是:
ax
上设置回调,可以检测xlim\u changed
和ylim\u changed
绘图区域
调用ax。获取_xlim()
和ax。获取_ylim()
ax
,重新绘制底图和任何其他数据显示首都的世界地图示例。当您放大地图的分辨率时,您会注意到正在更新。
import geopandas as gpd
import matplotlib.pyplot as plt
import contextily as ctx
figsize = (12, 10)
osm_url = 'http://tile.stamen.com/terrain/{z}/{x}/{y}.png'
EPSG_OSM = 3857
EPSG_WGS84 = 4326
class MapTools:
def __init__(self):
self.cities = gpd.read_file(
gpd.datasets.get_path('naturalearth_cities'))
self.cities.crs = EPSG_WGS84
self.cities = self.convert_to_osm(self.cities)
self.fig, self.ax = plt.subplots(nrows=1, ncols=1, figsize=figsize)
self.callbacks_connect()
# get extent of the map for all cities
self.cities.plot(ax=self.ax)
self.plot_area = self.ax.axis()
def convert_to_osm(self, df):
return df.to_crs(epsg=EPSG_OSM)
def callbacks_connect(self):
self.zoomcallx = self.ax.callbacks.connect(
'xlim_changed', self.on_limx_change)
self.zoomcally = self.ax.callbacks.connect(
'ylim_changed', self.on_limy_change)
self.x_called = False
self.y_called = False
def callbacks_disconnect(self):
self.ax.callbacks.disconnect(self.zoomcallx)
self.ax.callbacks.disconnect(self.zoomcally)
def on_limx_change(self, _):
self.x_called = True
if self.y_called:
self.on_lim_change()
def on_limy_change(self, _):
self.y_called = True
if self.x_called:
self.on_lim_change()
def on_lim_change(self):
xlim = self.ax.get_xlim()
ylim = self.ax.get_ylim()
self.plot_area = (*xlim, *ylim)
self.blit_map()
def add_base_map_osm(self):
if abs(self.plot_area[1] - self.plot_area[0]) < 100:
zoom = 13
else:
zoom = 'auto'
try:
basemap, extent = ctx.bounds2img(
self.plot_area[0], self.plot_area[2],
self.plot_area[1], self.plot_area[3],
zoom=zoom,
url=osm_url,)
self.ax.imshow(basemap, extent=extent, interpolation='bilinear')
except Exception as e:
print(f'unable to load map: {e}')
def blit_map(self):
self.ax.cla()
self.callbacks_disconnect()
cities = self.cities.cx[
self.plot_area[0]:self.plot_area[1],
self.plot_area[2]:self.plot_area[3]]
cities.plot(ax=self.ax, color='red', markersize=3)
print('*'*80)
print(self.plot_area)
print(f'{len(cities)} cities in plot area')
self.add_base_map_osm()
self.callbacks_connect()
@staticmethod
def show():
plt.show()
def main():
map_tools = MapTools()
map_tools.show()
if __name__ == '__main__':
main()
在Python3.8Linux上运行,具有以下pip安装
affine==2.3.0
attrs==19.3.0
autopep8==1.4.4
Cartopy==0.17.0
certifi==2019.11.28
chardet==3.0.4
Click==7.0
click-plugins==1.1.1
cligj==0.5.0
contextily==1.0rc2
cycler==0.10.0
descartes==1.1.0
Fiona==1.8.11
geographiclib==1.50
geopandas==0.6.2
geopy==1.20.0
idna==2.8
joblib==0.14.0
kiwisolver==1.1.0
matplotlib==3.1.2
mercantile==1.1.2
more-itertools==8.0.0
munch==2.5.0
numpy==1.17.4
packaging==19.2
pandas==0.25.3
Pillow==6.2.1
pluggy==0.13.1
py==1.8.0
pycodestyle==2.5.0
pyparsing==2.4.5
pyproj==2.4.1
pyshp==2.1.0
pytest==5.3.1
python-dateutil==2.8.1
pytz==2019.3
rasterio==1.1.1
requests==2.22.0
Rtree==0.9.1
Shapely==1.6.4.post2
six==1.13.0
snuggs==1.4.7
urllib3==1.25.7
wcwidth==0.1.7
特别注意contextly==1.0rc2的要求
在windows上,我使用Conda(P3.7.3),不要忘记设置用户变量:
GDAL c:\Users\
PROJLIB c:\用户\
GeoPandas文档包含一个关于如何向地图添加背景的示例(https://geopandas.readthedocs.io/en/latest/gallery/plotting_basemap_background.html),下文将对此进行更详细的解释。
您必须处理tile,即通过
http://.../Z/X/Y.png
,其中Z表示缩放级别,X和Y表示平铺
geopandas的文档展示了如何将图块设置为情节的背景,获取正确的图块,并完成所有其他困难的空间同步工作,等等...
假设已经安装了GeoPandas,则还需要上下文
包。如果您使用的是windows,您可能想看看如何在上下文中安装?
用例
创建一个python脚本并定义上下文辅助函数
import contextily as ctx
def add_basemap(ax, zoom, url='http://tile.stamen.com/terrain/tileZ/tileX/tileY.png'):
xmin, xmax, ymin, ymax = ax.axis()
basemap, extent = ctx.bounds2img(xmin, ymin, xmax, ymax, zoom=zoom, url=url)
ax.imshow(basemap, extent=extent, interpolation='bilinear')
# restore original x/y limits
ax.axis((xmin, xmax, ymin, ymax))
然后玩
import matplotlib.pyplot as plt
from shapely.geometry import Point
import geopandas as gpd
import pandas as pd
# Let's define our raw data, whose epsg is 4326
df = pd.DataFrame({
'LAT' :[-22.266415, -20.684157],
'LONG' :[166.452764, 164.956089],
})
df['coords'] = list(zip(df.LONG, df.LAT))
# ... turn them into geodataframe, and convert our
# epsg into 3857, since web map tiles are typically
# provided as such.
geo_df = gpd.GeoDataFrame(
df, crs ={'init': 'epsg:4326'},
geometry = df['coords'].apply(Point)
).to_crs(epsg=3857)
# ... and make the plot
ax = geo_df.plot(
figsize= (5, 5),
alpha = 1
)
add_basemap(ax, zoom=10)
ax.set_axis_off()
plt.title('Kaledonia : From Hienghène to Nouméa')
plt.show()
...这些决议含蓄地要求改变x/y限制。
我正试图在纽约地图上画一些“车站”坐标。我使用Geopandas(gpd)创建一个地理数据框,并从gpd.datasets创建一个EPSG为4326的纽约地图。 此外,我想在Geopandas教程之后向地图添加背景图像(https://geopandas.org/gallery/plotting_basemap_background.html). 然而,这对3857的EPSG有效。有没有办法维护信
多亏了这个问题的答案,我可以用不同的投影画出地球仪世界地图上的大陆和海洋。 现在我想补充几点,例如geopandas中包含的城市 不幸的是,这些城市被充满的大陆所覆盖。有没有办法让这些城市在地图的前面或上面? 我当前的代码如下: 结果如下所示:
我正在寻找一种漂亮的方法来打印地图。 <代码>贴图。toString()给我:
我创建了一个带有整数类型键的映射,值是字符串集。我已经用一些测试数据填充了映射,现在需要编写一个方法来打印映射的内容,例如“key: value, value, value” 我假设迭代映射,并将键分配给int变量并打印出来是如何开始的,但是我该如何打印字符串集中的值呢?
问题内容: 我正在寻找一种漂亮地打印的好方法。 给我: 我希望地图输入值具有更大的自由度,并且正在寻找更多类似这样的东西: 我写了这段代码: 但是我敢肯定,有一种更优雅,更简洁的方法可以做到这一点。 问题答案: 或将您的逻辑放在一个整洁的小班上。 用法: 注意:您也可以将该逻辑放入实用程序方法中。
我使用的默认贴图如下: 我可以从另一个GeoDataFrame(这里称为sample_gdf)成功地将标签注释到此地图,下面是循环示例: 这就是epsg=4326时的样子当我想改变地图的投影时,问题就开始了。上面变量world的默认CRS是epsg: 4326。一旦我像这样改变投影: 专注于欧洲,我的标签不再出现在正确的位置。一周来,我一直在寻找解决这个问题的建议,但目前找不到任何解决方案。谢谢你