[GIS] Using Python Add-In to delete/remove ArcMap layers that are turned off

arcgis-desktoparcpylayerspythonpython-addin

I have made a python addin button which removes layers that are turned off in an MXD. The strange thing is that I get different results depending on whether I run the python commands in the python window vs my actual addin button.

In my addin class, the code looks like this:

def onClick(self):
        mxd = arcpy.mapping.MapDocument("CURRENT")
        layerList = arcpy.mapping.ListLayers(mxd)
        for layer in layerList:
            if layer.visible == False:
                arcpy.Delete_management(layer)
        arcpy.RefreshTOC()

So, this works fine in the python window but doesn't do anything in the button. I assume because it's trying to delete a layer object instead of the name. I have made a workaround which changes the following line:

arcpy.Delete_management(layer.name)

Now this actually works. But there is a caveat, if I have multiple layers with the same name but different visibility settings, it may delete the one that is visible. My second workaround is to change the layer name before I delete it.

My final code looks like this:

def onClick(self):
        mxd = arcpy.mapping.MapDocument("CURRENT")
        layerList = arcpy.mapping.ListLayers(mxd)
        for layer in layerList:
            if layer.visible == False:
                layer.name += '_'
                arcpy.Delete_management(layer.name)
        arcpy.RefreshTOC() 

By changing the name of the layer, I'm ensuring that I only delete invisible layers. But I'm wondering if this is the best way to go about doing this.

My question is, is there a better way to remove layers that are not visible from an MXD? Especially when they have the same name?

Best Answer

It would be better to remove the layer using arcpy.mapping.RemoveLayer. The parameters are the data frame to remove the layer from (possibly a group layer if you are trying to remove from a group) and the layer itself, this alleviates any chance of confusion:

def onClick(self):
        mxd = arcpy.mapping.MapDocument("CURRENT")
        df = arcpy.mapping.ListDataFrames(mxd)[0] # assume only one data frame
        layerList = arcpy.mapping.ListLayers(mxd)
        for layer in layerList:
            if layer.visible == False:
                arcpy.mapping.RemoveLayer(df,layer)
        arcpy.RefreshTOC()
Related Question