set dataframe extents not working in arcpy

2938
6
Jump to solution
05-07-2017 02:20 PM
DanielBean
New Contributor II

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

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
curtvprice
MVP Esteemed Contributor

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‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

View solution in original post

6 Replies
DanPatterson_Retired
MVP Emeritus

 refreshing the active view might make a difference, however, I suspect it only works with 'Current' as the document

TimBarnes
Occasional Contributor III

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?

JoshuaBixby
MVP Esteemed Contributor

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.

curtvprice
MVP Esteemed Contributor

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‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
JoshuaBixby
MVP Esteemed Contributor

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
DanielBean
New Contributor II

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