set_xlim() does not work with text labels

373 Views Asked by At

I am trying to zoom in on geopandas map with labels using set_xlim() in with matplotlib. I basically adapted this SO question to add labels to a map.

However, set_xlim() does not seem to work and did not zoom in on the given extent. (By the way, I've also tried to use text() instead of annotate(), to no avail.)

What I did was the following:

I used the same US county data as in the question linked above, extracted the files, and then executed the following in Jupyter notebook:

import geopandas as gpd
import matplotlib.pyplot as plt
%matplotlib inline

shpfile='shp/cb_2015_us_county_20m.shp'
gdf=gpd.read_file(shpfile)
gdf.plot()

, which gives a map of all US counties as expected:

enter image description here

Adding labels as with one of the answers also works:

ax = gdf.plot()
gdf.apply(lambda x: ax.annotate(s=x.NAME, xy=x.geometry.centroid.coords[0], ha='center'),axis=1);

enter image description here

However, when trying to zoom in to a particular geographic extent with set_xlim() and set_ylim() as follows:

ax = gdf.plot()
gdf.apply(lambda x: ax.annotate(s=x.NAME, xy=x.geometry.centroid.coords[0], ha='center'),axis=1);
ax.set_xlim(-84.2, -83.4)
ax.set_ylim(42, 42.55)

, the two functions do not seem to work. Instead of zooming in, they just trimmed everything outside of the given extent.

enter image description here

If the labeling code is dropped out (gdf.apply(lambda x: ax.annotate(s=x.NAME, xy=x.geometry.centroid.coords[0], ha='center'),axis=1);, the set_xlim() works as expected:

enter image description here

My question is:

What is the correct way to zoom in to an area when labels are present in a plot?

2

There are 2 best solutions below

0
On

You need some coordinate transformation.

import cartopy.crs as ccrs
# relevant code follows

# set numbers in degrees of longitude
ax.set_xlim(-84.2, -83.4, ccrs.PlateCarree())

# set numbers in degrees of latitude
ax.set_ylim(42, 42.55, ccrs.PlateCarree())
plt.show()

with the option ccrs.PlateCarree(), the input values are transformed to proper data coordinates.

0
On

When I try it, I can't draw on matplotlib with the axes restricted. So it's possible to extract the data.

import geopandas as gpd
import matplotlib.pyplot as plt
%matplotlib inline
fig,ax = plt.subplots(1,1, figsize=(4,4), dpi=144)

shpfile = './cb_2015_us_county_20m/cb_2015_us_county_20m.shp'

gdf = gpd.read_file(shpfile)
# gdf = gdf.loc[gdf['STATEFP'] == '27']
gdf['coords'] = gdf['geometry'].apply(lambda x: x.representative_point().coords[:])
gdf['coords'] = [coords[0] for coords in gdf['coords']]
gdf = (gdf[(gdf['coords'].str[0] >= -84.2) & (gdf['coords'].str[0] <= -83.4)
          & (gdf['coords'].str[1] >= 42) & (gdf['coords'].str[1] <= 42.55)])

gdf.plot(ax=ax)
gdf.apply(lambda x: ax.annotate(text=x.NAME, xy=x.geometry.centroid.coords[0], ha='center'),axis=1)

enter image description here