Search code examples
pythonmatplotlibseaborngeopandas

Why is the figure size (y-axis) fluctuating in this example?


I've got a map of the world on which I am iteratively plotting drought areas in a for-loop.

For reproducibility, data is here: https://data.humdata.org/dataset/global-droughts-events-1980-2001

import pandas as pd
import geopandas as gpd

import matplotlib.pyplot as plt
import seaborn as sns

from IPython.display import clear_output
sns.set_theme(style='whitegrid')

dr_geometry = gpd.read_file('data/dr_events.shp')
world_geometry = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))

for y in dr_geometry.year.unique():
    clear_output(wait=True)
    fig, ax = plt.subplots(1, 1, figsize=(15, 15))
    world_geometry.plot(ax=ax)
    dr_geometry[dr_geometry.year == y].plot(ax=ax, color='red', edgecolor='black', linewidth=0.1)
    plt.show();
    

This is working fine, except that the y-axis shrinks or expands on each iteration by a small but very noticeable amount, resulting in a choppy animation. How can I eliminate this behavior?

Note: Setting the ylim explicitly does not change this. Also I have tried moving the subplots instantiation outside of the for-loop, but this results in empty outputs.

An iteration output:

enter image description here


Solution

  • ax.set_aspect('equal') prevents the shifting on my end:

    for y in dr_geometry.year.unique():
        clear_output(wait=True)
        fig, ax = plt.subplots(1, 1, figsize=(15, 15))
        world_geometry.plot(ax=ax)
        dr_geometry[dr_geometry.year == y].plot(ax=ax, color='red', edgecolor='black', linewidth=0.1)
        
        # set aspect ratio explicitly
        ax.set_aspect('equal')
        
        plt.show();
    

    Thanks to @martinfleis for pointing out the reason for the shifting:

    .plot() now automatically determines whether GeoSeries (or GeoDataFrame) is in geographic or projected CRS and calculates aspect for geographic using 1/cos(s_y * pi/180) with s_y as the y coordinate of the mean of y-bounds of GeoSeries. This leads to better representation of the actual shapes than current hard-coded 'equal' aspect.