I am unable to set the data frame extents to the extents of one layer.
mxd = arcpy.mapping.MapDocument(r'C:\Projects\G25\MXD\G10001_Aspect.mxd') df = arcpy.mapping.ListDataFrames(mxd, 'Layers')[0] print 'df Extent before:', df.extent for lyr in arcpy.mapping.ListLayers(mxd, 'Outline'): lyr_extent = lyr.getExtent() print 'Layer Extent:', lyr_extent df.extent = lyr_extent print 'df Extent after:', df.extent mxd.save() del mxd The mxd df extent is not changed (extents printed below)
df Extent before: -48.7679994656522 -31.5306864013717 48.4338994650919 37.1648864006445 NaN NaN NaN NaN
Layer Extent: -10.5550864009008 -31.5306864013717 10.2209864003405 37.1648864006445 -0.86019999999553 0.806700000001001 NaN NaN
df Extent after: -48.7679994656522 -31.5306864013717 48.4338994650919 37.1648864006445 NaN NaN NaN NaN
Solved! Go to Solution.
I tested this with 10.4.1 in an ArcMap session and it seems to work for me. Note my df extent after is larger because it used the current shape of my map canvas.
mxd = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(mxd, 'Layers')[0]
print 'df Extent before:', df.extent
for lyr in arcpy.mapping.ListLayers(mxd, 'Karst Sinks'):
lyr_extent = lyr.getExtent()
print 'Layer Extent:', lyr_extent
df.extent = lyr_extent
print 'df Extent after:', df.extent
df Extent before: -3607551.13680627 -690838.010041055 4092265.56918456 3504270.88658365 NaN NaN NaN NaN
Layer Extent: 590797.865849879 1360681.84220262 1483863.57306459 1981094.45295359 NaN NaN NaN NaN
df Extent after: 467969.648912527 1360681.84220262 1606691.79000194 1981094.45295359 NaN NaN NaN NaN
refreshing the active view might make a difference, however, I suspect it only works with 'Current' as the document
Refreshing the Active view solved my issue (df.panToExtent wasn't working). Oddly though, I had put a mxd.save() after changing the projection of my dataframe before I then updated the extent. Having that save there lead to the panToExtent NOT working....so I guess there was some interference in process there?
The DataFrame documentation has an important note in the extent property explanation:
Note: The properties of the Extent object are by default read-only in the help system. A special exception was made for the arcpy.mapping scripting environment to enable changing extents during a map automation process.
df = arcpy.mapping.ListDataFrames(mxd)[0] newExtent = df.extent newExtent.XMin, newExtent.YMin = -180.0, -90.0 newExtent.XMax, newExtent.YMax = 180.0, 90.0 df.extent = newExtent
Although not clear, the code example provides the clue you need. You need to get/set the property, not just set. If you mimic the code example, you should get it to work.
I tested this with 10.4.1 in an ArcMap session and it seems to work for me. Note my df extent after is larger because it used the current shape of my map canvas.
mxd = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(mxd, 'Layers')[0]
print 'df Extent before:', df.extent
for lyr in arcpy.mapping.ListLayers(mxd, 'Karst Sinks'):
lyr_extent = lyr.getExtent()
print 'Layer Extent:', lyr_extent
df.extent = lyr_extent
print 'df Extent after:', df.extent
df Extent before: -3607551.13680627 -690838.010041055 4092265.56918456 3504270.88658365 NaN NaN NaN NaN
Layer Extent: 590797.865849879 1360681.84220262 1483863.57306459 1981094.45295359 NaN NaN NaN NaN
df Extent after: 467969.648912527 1360681.84220262 1606691.79000194 1981094.45295359 NaN NaN NaN NaN
Curtis Price, you are correct, i.e., the OP's original syntax should work. I will have to update my comment to clarify that get/set applies to properties of the default extent and not the default extent itself. Basically, you can't modify the default extent properties in place, you need to modify an extent object and then pass it back to the default extent property to have the updates stick.
The following will not generate an error, but it doesn't update the default extent:
df = arcpy.mapping.ListDataFrames(mxd)[0]
df.extent.XMin, df.extent.YMin = -180.0, -90.0
df.extent.XMax, df.extent.YMax = 180.0, 90.0
Curtis is correct, the original code does function correctly. The problem was with my test mxd which was already zoomed to the desired extent, so no change was reflected in the test. Zooming out on the test mxd, then running the code, zoomed the data frame to the extents of the 'Outline' layer correctly. Thanks to all. To zoom the data frame to the extents of layer 'Outline' the code would be:
for lyr in arcpy.mapping.ListLayers(mxd, 'Outline'): lyr_extent = lyr.getExtent() df.extent = lyr_extent