matplotlib Set centre of ChelandasMap

9wbgstp7  于 2023-10-24  发布在  其他
关注(0)|答案(3)|浏览(92)

我可以绘制一张世界Map,其中有:

world = geopandas.read_file(geopandas.datasets.get_path('naturalearth_lowres'))
fig, ax = plt.subplots()
world.plot(ax=ax, color=(0.8,0.5,0.5))

它工作正常,但我想把Map的中心放在本初子午线以外的经度上。我该怎么做?

mwkjh3gx

mwkjh3gx1#

这是你可以做到的:

from shapely.geometry import LineString
from shapely.ops import split
from shapely.affinity import translate
import geopandas

world = geopandas.read_file(geopandas.datasets.get_path('naturalearth_lowres'))

def shift_map(shift):
    shift -= 180
    moved_map = []
    splitted_map = []
    border = LineString([(shift,90),(shift,-90)])
    for row in world["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})
    fig, ax = plt.subplots()
    gdf.plot(ax=ax)
    plt.show()

在第一步中,你创建了你的世界,并在你预先定义的边界上分割它。然后你得到所有元素的边界,并检查边界是否符合你想要的位移。然后你将每个大于边界的元素平移到Map的左侧,并将所有其他元素移动到右侧,这样它们就可以以+180°的Angular 对齐。
例如:

Map移动了120°

368yc8dk

368yc8dk2#


就像在这个问题中,我需要重置Map的中心,但我也需要移动散点图网络节点的位置,其中绑定到(长,纬度)坐标太。我希望保存一些人的时间,因为它可能不是很明显,最初解决这个问题,你将不得不争论一些不熟悉的类型。
下面是一个移动底层Map和一些附加点的方法:

import geopandas
world = 
    geopandas.read_file(geopandas.datasets.get_path('naturalearth_lowres'))
import matplotlib.pyplot as plt
import geopandas as gpd
from shapely.geometry import LineString
from shapely.ops import split
from shapely.affinity import translate

def shift_geom(shift, gdataframe,pos_all, plotQ=True):
    # this code is adapted from answer found in SO
    # will be credited here: ???
    shift -= 180
    moved_geom = []
    splitted_geom = []
    border = LineString([(shift,90),(shift,-90)])

    for row in gdataframe["geometry"]:
        splitted_geom.append(split(row, border))
    for element in splitted_geom:
        items = list(element)
        for item in items:
            minx, miny, maxx, maxy = item.bounds
            if minx >= shift:
                moved_geom.append(translate(item, xoff=-180-shift))
            else:
                moved_geom.append(translate(item, xoff=180-shift))

    # got `moved_geom` as the moved geometry            
    moved_geom_gdf = gpd.GeoDataFrame({"geometry": moved_geom})

    # can change crs here
    if plotQ:
        fig1, ax1 = plt.subplots(figsize=[8,6])
        moved_geom_gdf.plot(ax=ax1)
        plt.show()
        
    df = pd.DataFrame({'Latitude': [xy[1] for xy in pos_all.values()],
    'Longitude': [xy[0] for xy in pos_all.values()]})
    gdf = geopandas.GeoDataFrame(df, geometry=geopandas.points_from_xy(df.Longitude, df.Latitude))
    border2 = LineString([(shift,90),(shift,-90)])
    geom = gdf.geometry.values    
    moved_map_points = []
    moved_map_dict = {}

    for element,key in zip(geom,list(pos_all.keys())):
        if float(element.x) >= shift:        
            moved_map_points.append(translate(element, xoff=-180-shift))
        else:
            moved_map_points.append(translate(element, xoff=180-shift))
        moved_map_dict[key] = (moved_map_points[-1].x,moved_map_points[-1].y)

    return moved_geom_gdf,moved_map_dict

在此上下文中,pos_all是由[(lat,long)]组成的networkx节点位置

shifted_world,moved_map_points = shift_geom(300, world,pos_all,plotQ= False)
00jrzges

00jrzges3#

Shapely >= 2.0的答案J.P.必须适应:你必须用list(element.geoms)替换list(element):

from shapely.geometry import LineString
from shapely.ops import split
from shapely.affinity import translate
from shapely.geometry import GeometryCollection

def shift_map(mymap, shift):
    shift -= 180
    moved_map = []
    splitted_map = []
    border = LineString([(shift,90),(shift,-90)])
    for row in mymap["geometry"]:
        splitted_map.append(split(row, border))
    for element in splitted_map:
        items = list(element.geoms)
        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))
    mymap = gpd.GeoDataFrame({"geometry":moved_map})
    return mymap

相关问题