Looping Dataframe in Python doesn't Return Expected Results

968
3
09-10-2012 12:07 PM
MikeMacRae
Occasional Contributor III
I'm creating a python addin script to be used on some mxd's I have created as templates. Each map contains 2 dataframes. I need to loop through each dataframe and do some processing on each. I set my loop as follows:

for df in arcpy.mapping.ListDataFrames(mxd, "DFMAIN"):
                        for lyr in arcpy.mapping.ListLayers(mxd, "", df):
                               # do some processing here
for df in arcpy.mapping.ListDataFrames(mxd, "DFINSET"):
                        for lyr in arcpy.mapping.ListLayers(mxd, "", df):
                               # do some processing here



In this scenario, if the second dataframe is the 'active' dataframe, it gets chosen first and then some weird stuff happens. I get layers from my first dataframe copied into the second which baffles me and I am not even using any functionality that would copy layers (i.e. arcpy.mapping.AddLayer or anything similar) I just update some definition queries.

If I change the template so that the first dataframe is the active one, then everything works fine.

I tried indexing the dataframe loops:

for df in arcpy.mapping.ListDataFrames(mxd, "DFMAIN")[0]:


but I get the same weirdness if the second dataframe is active.

I guess the easy answer is, make sure the template has the first dataframe as the active one and save it that way, but I have users who may change this unknowingly. I want the geoprocessing to take care of the active dataframe issue. I can't seen anything in the help menu to set the dataframe as the active one.
Tags (2)
0 Kudos
3 Replies
JeffBarrette
Esri Regular Contributor
We'll need more specifics in order to evalute this issue.  Its the "# do some processing here" part that I'd like to see.  Is there any way you can provide more of the script?  Also, what version of the software are you using.

Thanks,
Jeff
0 Kudos
ChristopherThompson
Occasional Contributor III
for df in arcpy.mapping.ListDataFrames(mxd, "DFMAIN"):
                        for lyr in arcpy.mapping.ListLayers(mxd, "", df):
                               # do some processing here
for df in arcpy.mapping.ListDataFrames(mxd, "DFINSET"):
                        for lyr in arcpy.mapping.ListLayers(mxd, "", df):
                               # do some processing here

Some how this just doesn't seem right, you're getting a list of exactly one df and then 'looping' through it.  Are you doing different things in the 'do some processing here' part for each dataframe?

I think i'd be more tempted to approach this this way:
df_list = arcpy.mapping.ListDataFrames(mxd)
for df in df_list:
    if df == "DFMAIN":
        for lyr in arcpy.mapping.ListLayers(mxd, "", df):
            # do some processing here
    else: #since there are only two layers you don't need to test here for which df this is
        for lyr in arcpy.mapping.ListLayers(mxd, "", df):
            # do some processing here


I know its niggling but I think it gets away from the problem you are experiencing with the active dataframe being the first one that is selected.
0 Kudos
TimTeaford
New Contributor
Mike,

Here is an example of how to set the active dataframe regardless of which one was active in the first place:

# Set a reference to the MXD file...
#
mxd = arcpy.mapping.MapDocument(mxdfile)
#
# Create an array of all of the dataframes that are in this MXD file...
#
alldf = arcpy.mapping.ListDataFrames(mxd, "")
#
# Loop through the dataframes array...
#
for dataframe in alldf:
    print 'Dataframe = ' + dataframe.name
    #
    # Set the active view to the current dataframe...
    #
    mxd.activeView = dataframe
    #
    # Create an array of all of the layers in the current dataframe...
    #
    alllayers = arcpy.mapping.ListLayers(mxd, "", dataframe)
    #
    # Loop through the layers array...
    #
    for layer in alllayers:
        print 'Layer = ' + layer.name


I hope this helps.

Tim
0 Kudos