3

I have two GeoDataFrames. The first one have the administrative boundaries of the 25 regions of a country. The second one, the urban fabric of the same country.

regions.head()

    COD    NAMEREG      ID  geometry
0   06     CAJAMARCA    6   MULTIPOLYGON (((175543.152 9154323.287, 175542...
1   14     LAMBAYEQUE   14  MULTIPOLYGON (((148.362 9224534.960, 85.995 92...
2   15     LIMA         15  MULTIPOLYGON (((395740.367 8562514.992, 395702...
3   02     ANCASH       2   MULTIPOLYGON (((261823.737 8840350.284, 261826...
4   04     AREQUIPA     4   MULTIPOLYGON (((891245.832 8110391.639, 891267...

urbfab.head()

    Area        geometry
0   124196.0    MULTIPOLYGON (((1714054.886 9088365.957, 17143...
1   124196.0    MULTIPOLYGON (((1835848.391 9084645.865, 18361...
2   62098.0     MULTIPOLYGON (((1712843.236 9087713.270, 17131...
3   124196.0    MULTIPOLYGON (((1835363.081 9083054.193, 18356...
4   124196.0    MULTIPOLYGON (((1756044.734 9085140.825, 17563...

So, to plot both of them I use this code:

import pandas as pd
import geopandas as gpd
import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(16, 16))

regions.plot(ax=ax, color='#ffffff', edgecolor='#6a6a6a', linewidth=2)
urbfab.plot(ax=ax, color='#000000', edgecolor='#000000')

_=ax.axis('off')

Which results in this image, which for basic purposes is OK: enter image description here

But I want to know if is it possible to get an image like this, where any region is shown separately. enter image description here

(Of course, this is for example purposes only, that is why I plotted only 3 regions. It was produced in QGIS)

2 Answers 2

7

I usually plot multiple maps as following.

import pandas as pd
import geopandas as gpd
import matplotlib.pyplot as plt


fig, axs = plt.subplots(5, 5, figsize=(25, 25))
axs = axs.flatten()

for idx in range(len(regions)):
    regions.iloc[[idx]].plot(ax=axs[idx], color='#ffffff', edgecolor='#6a6a6a', linewidth=2)
    urbfab.iloc[[idx]].plot(ax=axs[idx], color='#000000', edgecolor='#000000')
    axs[idx].set_title(f"{regions.iloc[idx]['NAMEREG']} #{idx}")
    axs[idx].axis('off')
plot.show()
5
  • I get this mesage: TypeError: no numeric data to plot. Commented Jul 24, 2021 at 21:09
  • 1
    [[idx]] instead of [idx]. I updated the above. Commented Jul 24, 2021 at 21:32
  • I have a problem with this line: axs[idx].set_title(f'{regions.iloc[idx]['NAMEREG']} #{idx}'). I get this message: SyntaxError: f-string: unmatched '[' Commented Jul 24, 2021 at 23:15
  • 1
    @JoseRojas Try f"{regions.iloc[idx]['NAMEREG']} #{idx}", this way the quotation marks no longer collide. Commented Jul 25, 2021 at 11:28
  • I tried it but I still have a problem. I described it in this question Commented Jul 26, 2021 at 23:19
0

Spatial join the region names to the second df. Groupby region and plot

import geopandas as gpd
import matplotlib.pyplot as plt

#Read two shapefiles as geodataframes
regions = gpd.read_file(r'D:/gisdata/regions.shp')
buildings = gpd.read_file(r'D:/gisdata/buildings.shp')

region_name_column = "KOMMUNNAMN" #The column name identifying each region in the region df

#Spatial join region attribute to the buildings
buildings = buildings.sjoin(regions[[region_name_column, "geometry"]], how="inner", predicate="intersects")


#Create a plot with 3 rows and 3 columns
fig, axes = plt.subplots(nrows=3, ncols=3, figsize=(20,20))
axes = axes.flatten() #From 2D array with shape 3,3 to 1D array with shape 9. Easier to iterate over
[ax.set_axis_off() for ax in axes] #Hide all axes


#For each region, plot it and the buildings in it
for ax, (region_name, region_subframe) in zip(axes, regions.groupby(region_name_column)):
    region_subframe.plot(ax=ax, zorder=1, facecolor="None", edgecolor="red", linewidth=4)
    
    #Select buildings by the joined region attribute column1
    buildings_subframe = buildings.loc[buildings[region_name_column]==region_name]
    buildings_subframe.plot(ax=ax, zorder=2, facecolor="black", edgecolor="black")
    
    ax.set_title(region_name, fontsize=20)

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.