test_subject
test_subject

Reputation: 57

GeoPandas map: Centering the country on the plot (and joining its split geometries at 180 degrees longitude)

I'm trying to plot Russia choropleth map with some custom shapefile and it currently looks really awkward. Is there any way to center the map on the country so it's not split into two pieces (and maybe zoom it a little bit)?

Upvotes: 2

Views: 1051

Answers (1)

swatchai
swatchai

Reputation: 18782

It is possible to manipulate the geometries of a certain country and get a better plot as you require. Here ia a runnable code and its output plot.

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, plotQ=False):
    # 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()

    return moved_geom_gdf

# take the `lowres` data for use
# you can use your own geodataframe here
world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
# select Russia only
russia = world[world['iso_a3']=="RUS"]
# shift geometry of Russia
new_rus = shift_geom(90, russia, False)
# restore the geometry to original geo-location
# ... geometry now in 1 piece
# ... option True --> make a plot
_ = shift_geom(-90, new_rus, True)

Output plot:

russia_1_piece

Upvotes: 3

Related Questions