我有一个 shapefile,我将其读取为 geopandas 数据框
import geopandas as gpd
gdf = gpd.read_file('myfile.shp')
gdf.plot()
其中
gdf.crs
<Projected CRS: ESRI:54009>
Name: World_Mollweide
Axis Info [cartesian]:
- E[east]: Easting (metre)
- N[north]: Northing (metre)
Area of Use:
- name: World.
- bounds: (-180.0, -90.0, 180.0, 90.0)
Coordinate Operation:
- name: World_Mollweide
- method: Mollweide
Datum: World Geodetic System 1984
- Ellipsoid: WGS 84
- Prime Meridian: Greenwich
和
gdf.total_bounds
array([-17561329.90352868, -6732161.66088735, 17840887.22672861,
8750122.26961274])
我想使用
basemap
在其顶部绘制经纬度网格。这就是我正在做的
from mpl_toolkits.basemap import Basemap
# Create a Basemap instance with the same projection as the GeoDataFrame
map = Basemap(projection='moll', lon_0=-0, lat_0=-0, resolution='c')
# Create a figure and axis
fig, ax = plt.subplots(figsize=(10, 6))
# Plot the basemap
map.drawcoastlines()
map.drawcountries()
map.drawparallels(range(-90, 91, 30), labels=[1,0,0,0], fontsize=10)
map.drawmeridians(range(-180, 181, 60), labels=[0,0,0,1], fontsize=10)
# Plot the GeoDataFrame on top of the basemap
gdf.plot(ax=ax, color='red', markersize=5)
但这就是我得到的
问题在于,正在将 geopandas(在不同的坐标系中工作)与 basemap(有自己的坐标系处理方式)混合使用。为了使两者一起工作,需要使用 basemap 将 geopandas 数据框的坐标转换为相应的坐标。
以下是如何操作:
import geopandas as gpd
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
# 读取 shapefile
gdf = gpd.read_file('myfile.shp')
# 创建与 GeoDataFrame 投影相同的 Basemap 实例
map = Basemap(projection='moll', lon_0=0, lat_0=0, resolution='c')
# 创建图形和坐标轴
fig, ax = plt.subplots(figsize=(10, 6))
# 绘制底图
map.drawcoastlines()
map.drawcountries()
map.drawparallels(range(-90, 91, 30), labels=[1,0,0,0], fontsize=10)
map.drawmeridians(range(-180, 181, 60), labels=[0,0,0,1], fontsize=10)
# 将 GeoDataFrame 的几何图形转换为底图坐标
gdf['geometry'] = gdf['geometry'].to_crs(epsg=4326) # 首先转换为经纬度
gdf['geometry'] = gdf['geometry'].apply(lambda x: map(x.x, x.y))
# 现在在底图上绘制 GeoDataFrame
gdf.plot(ax=ax, color='red', markersize=5)
plt.show()
这将在底图的顶部正确绘制 shapefile。
说明:
-
将 GeoDataFrame 转换为经纬度:
我们首先使用
gdf['geometry'].to_crs(epsg=4326)
将 GeoDataFrame 的坐标参考系 (CRS) 转换为经纬度 (EPSG:4326)。这是因为 basemap 使用经纬度作为其坐标系。 -
将经纬度转换为底图坐标:
然后,我们使用
map(x.x, x.y)
将经纬度坐标转换为 basemap 坐标。map
函数是 basemap 实例的一部分,它接受经度和纬度作为输入并返回相应的底图坐标。 -
在底图上绘制:
现在,
gdf.plot()
将使用正确的坐标在底图上绘制 shapefile。
通过这些更改,的 shapefile 应该正确地叠加在底图上,而不会出现任何对齐问题。
标签:python,matplotlib,geopandas,shapefile,matplotlib-basemap From: 78305720