python-3.x - 用 Geopandas 绘制以日本为中心的世界地图
问题描述
在阅读我的问题之前,我的英语水平很差,所以请给我反馈或用简单的话给我建议。谢谢你。
我想做的事:
我想用python 3.x上的geopandas库绘制一个以日本为中心的世界地图。
我的环境:
- Windows10(64位)
- Python v3.9.4
- geopandas v0.9.0
我的代码:
import geopandas
world = geopandas.read_file(geopandas.datasets.get_path("naturalearth_lowres"))
world.boundary.plot(figsize=(15,8))
获得的图像
问题:
获得的世界地图的中心在非洲周围。我想绘制以日本为中心的图像。我阅读了官方文档:Mapping and Plotting Tools,但我找不到如何实现它。请告诉我建议!
解决方案
我发现使用geopandas
(+pyproj
作为它的依赖项)来获得移位的地图太困难了。在我下面的代码中,geopandas
用于提供世界的地理数据框以进行操作和绘图。Cartopy
用于提供geoaxis
适当的地理空间参考。并shapely
用于进行各种操作以转换几何图形以绘制重新居中的世界图以满足问题中的要求。
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from shapely.geometry import LineString, MultiPolygon, Polygon
from shapely.ops import split
from shapely.affinity import translate
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
import geopandas
def shift_map(world_gdf, shift, ax):
# world_gdf: world geodataframe to shift
# shift: longitude shift
# ax: geoaxis to plot the map
shift -= 180
moved_map = []
splitted_map = []
border = LineString([(shift,90),(shift,-90)])
for row in world_gdf["geometry"]:
splitted_map.append(split(row, border))
for element in splitted_map:
items = list(element)
for item in items:
minx, miny, maxx, maxy = item.bounds
if minx >= shift:
moved_map.append(translate(item, xoff=-180-shift))
else:
moved_map.append(translate(item, xoff=180-shift))
gdf = geopandas.GeoDataFrame({"geometry": moved_map})
gdf.boundary.plot(ax=ax, linewidth=1, color='gray')
# can also use: gdf.plot() to plot the geometries as polygons
# define CRS's
crs0 = ccrs.PlateCarree(central_longitude=0) # standard CRS
lon_0 = 138 # Japan at center
# crsJapan = ccrs.PlateCarree(central_longitude=lon_0) # japan's centered; not in-use
# a special CRS for use with ax1.gridlines() to get correct longitude's labels plot
crsGridLines = ccrs.PlateCarree(central_longitude=-lon_0)
# create figure, axis
# use cartopy ccrs to get some niceties
fig, ax1 = plt.subplots(figsize=(8, 4.5), subplot_kw={"projection": crs0})
# load world geodataframe
world = geopandas.read_file(geopandas.datasets.get_path("naturalearth_lowres"))
# Plot the shifted map
shift_map(world, lon_0, ax1)
# Plot graticule/grid; only work with geoaxis
gl = ax1.gridlines(crs=crsGridLines, draw_labels=True, linewidth=1, color='gray', linestyle='--')
gl.xformatter = LONGITUDE_FORMATTER
gl.yformatter = LATITUDE_FORMATTER
gl.xlabel_style = {'size': 10, 'color': 'black'}
gl.ylabel_style = {'size': 10, 'color': 'black'}
plt.show()
推荐阅读
- hybris - 使用 Hybris hotfolder 时预处理 csv 文件以将键值转换为小写
- javascript - 从对象数组中获取唯一值及其数量
- php - sql server 2014 中发生数据库错误时,自动增量值正在更改
- sql-server - 如何从 SQL Server 中的日期获取日期时间
- python - IndexError: 列表索引超出范围
- javascript - 获取未定义为函数输出
- python - 如何在pywinauto中通过正则表达式标题搜索孩子/后代?
- react-native - 反应本机 mapDispatchToProps 不起作用
- python - 停止 Jupyter 自动缩进新行大量的非整数制表符?
- quantum-computing - 使用哈密顿量实现 CNOT 门