-1

I work on several maps- each map has different number of data frames (several maps had only 1 or 2 data frames). with this code i try to remove layer "frame" from the third data frame only. I want that the first \ second\ forth... data frames will stay as they are:

import arcpy
from arcpy import env

env.workspace = r"G:\desktop\Project"
for mxdname in arcpy.ListFiles("*.mxd"):
    print mxdname 
    mxd = arcpy.mapping.MapDocument(r"G:\desktop\Project\\" + mxdname)
    df = arcpy.mapping.ListDataFrames(mxd, "Layers")[3]
    for lyr in arcpy.mapping.ListLayers(mxd, "", df):
        if lyr.isGroupLayer == True: continue
        if lyr.name == "frame":
            arcpy.mapping.RemoveLayer(df, lyr)
            print 'remove'             
mxd.save()
del mxd

but i get this error:

Traceback (most recent call last):
File "G:\desktop\y\test.py", line 10, in <module>
df = arcpy.mapping.ListDataFrames(mxd, "Layers")[3]
IndexError: list index out of range

enter image description here

those are the table of contents:

mxd1:

enter image description here

mxd2:

enter image description here

mxd3:

enter image description here

mxd4:

enter image description here

  • I predict that the code you have presented will give the IndexError on mxd1, mxd2 and mxd3 (which have less than four data frames named Layers) but not on mxd4 (if the code were to get to it, because it has four or more data frames named Layers). – PolyGeo Oct 8 '18 at 9:57
  • yes that's right – newGIS Oct 8 '18 at 11:42
  • My answer explains why. – PolyGeo Oct 8 '18 at 11:44
1

I suspect that you get this error message because the mxdname that you are processing at the time does not have four or more data frames named "Layers".

The line:

df = arcpy.mapping.ListDataFrames(mxd, "Layers")[3]

effectively says, create a DataFrame object named df by listing all the data frames named "Layers" in the Map object named mxd and grab the fourth one using the index value of 3. If you have three or less data frames in that mxd then you will get an IndexError because you are using an index number greater than the number of data frames that ListDataFrames has written to its list.

I suspect you actually want to grab the first one so using this instead may well work:

df = arcpy.mapping.ListDataFrames(mxd, "Layers")[0]

or if you want to grab the third data frame named "Layers" you would use an index of 2:

df = arcpy.mapping.ListDataFrames(mxd, "Layers")[2]

or if you want to grab the third data frame irrespective of the data frame names you would use an index of 2 and no wildcard:

df = arcpy.mapping.ListDataFrames(mxd, "")[2]

To learn more about debugging IndexError messages coming from ArcPy we have a self-assembling FAQ on IndexError and ArcPy.

To check whether an mxd may have a "Layers" data frame with leading/trailing blanks messing up your wildcard search try including a block like this:

for dframe in arcpy.mapping.ListDataFrames(mxd, ""): print "#{0}#".format(lyr.name)

If you see a data frame name printed as # Layers# or #Layers # instead of #Layers# then you'll know that this is something you need to fix in your mxd(s) or code around.

To avoid seeing the IndexError when there are two or less data frames found in an MXD you could change:

df = arcpy.mapping.ListDataFrames(mxd, "Layers")[2]
for lyr in arcpy.mapping.ListLayers(mxd, "", df):
    if lyr.isGroupLayer == True: continue
    if lyr.name == "frame":
        arcpy.mapping.RemoveLayer(df, lyr)
        print 'remove'  

to:

if len(arcpy.mapping.ListDataFrames(mxd, "Layers")) > 2:    
    df = arcpy.mapping.ListDataFrames(mxd, "Layers")[2]
    for lyr in arcpy.mapping.ListLayers(mxd, "", df):
        if lyr.isGroupLayer == True: continue
        if lyr.name == "frame":
            arcpy.mapping.RemoveLayer(df, lyr)
            print 'remove'  
  • with your answer the layer has been removed from the first data frame- this isn't the my goal. i want to remove the layer from the third data frame only – newGIS Oct 8 '18 at 7:20
  • still the same error after i changed into [2] with your comments – newGIS Oct 8 '18 at 7:35
  • Please include a screenshot of the Table of Contents (with the data frames collapsed so that we can see there names) from the MXD that throws this error. Also verify that any data frames in that MXD named Layers do not have leading or trailing spaces in their names. – PolyGeo Oct 8 '18 at 7:37
  • i tried your line for dframe in arcpy.mapping.ListDataFrames(mxd, ""): print "#{0}#".format(lyr.name) it printed #frame# for all the dataframe. what can i do now? That mean there no leading/trailing blanks – newGIS Oct 8 '18 at 11:46
  • Try using the len function to make sure that the length of the data frame list is 3 or greater before trying to use an index of 2 on it. – PolyGeo Oct 8 '18 at 12:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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