I have a shapefile (will be called source-file hereafter), which I need to clip by a MultiPolygon shapefile so that I can have a clipped shapefile for each polygon.

I tried the GeoPandas, though I am able to clip the source file by individually clipping it by selecting the polygons separately from the MultiPolygon shapefile, when I try to loop over the polygons to automate the clipping process I get the following error:

Error: TypeError: 'mask' should be GeoDataFrame, GeoSeries or(Multi)Polygon, got <class 'tuple'>

My code:

import geopandas as gpd

source = ('source-shapefile.shp')
mask = ('mask_shapefile.shp')
sourcefile = gpd.read_file(source)
maskfile = gpd.read_file(mask)
for row in maskfile.iterrows():
    gpd.clip(sourcefile, row)
  • Can you print(type(row)). I'm not able to test right now and shooting from the hip, I suspect that you might neet to change row, I guess is shapely to type geopandas using gpd.Geodataframe.
    – user19349
    Apr 17, 2022 at 10:45
  • @Taras both source-file and mask file (Multi-polygon) are ESRI Shapefiles. Apr 17, 2022 at 12:57
  • @user19349 print(type(row) shows tuple <class 'tuple'> Apr 17, 2022 at 12:58
  • What happens if you change gpd.clip(sourcefile, row) to gpd.clip(sourcefile, gpd.GeoDataFrame(row)) or gpd.clip(sourcefile, gpd.GeoDataFrame({geometry =row.geometry})). Sorry that I can't test it myself at this stage. Will do so later.
    – user19349
    Apr 17, 2022 at 13:30
  • I was able to run the code using exploded = maskfile.explode(index_col = 'ID') then for row in exploded['geometry']: \ clipped = gpd.clip(masked, row) however I am not able to save separate shapefiles for each polygon as it over writes the files in the output folder , I tried this line to save the files clipped.to_file('polygon'+ {int('ID'):03}+'.shp') Apr 17, 2022 at 14:05

1 Answer 1


Finally, I am now able to clip the shapefile by a MultiPolygon shapefile and save the clipped polygons separately with their respective names. The following code works:

import os, sys
import pandas as pd
import geopandas as gpd

source = ('source-shapefile.shp')
mask = ('mask_shapefile.shp')
outpath = ('/outpath')

sourcefile = gpd.read_file(source)
maskfile = gpd.read_file(mask)

clipshape = maskfile.explode()

clipshape.set_index('CATCH_NAME', inplace=True) # CATCH_NAME is attribute column name

for index, row in clipshape['geometry'].iteritems():
    clipped = gpd.clip(sourcefile, row)
    clipped.to_file(os.path.join(outpath, f'{index}.shp'))

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.