I'd like to rotate my dataframe until a polyline fits dataframe-width wise in the layout view of a .mxd. If the lines runs north/south I would like the dataframe rotated until the line is shown east/west (the north arrow adjusts accordingly).

I can rotate the dataframe with arcpy. But how would I check that my polyline is running dataframe-width wise.

Or would I get the envelope of the feature and then do some math to figure out how much the rotation angle should be to have the data frame rotated to meet my goal?

The end result would be to capture the entire polyline in the dataframe in layout view of ArcMap (dataframe-width wise) at the smallest extent possible. Like an alignment sheet.

  • (It's a tip. It's not an answer.) Justin, relax. My mind has got tired reading a second sentence. As a person with an average brain I stuck here: "my polyline is length wise good enough"... Just be more specific. Feb 9, 2012 at 21:30

1 Answer 1


Assuming that there are no curves in your line, this function accepts a featureclass containing your single polyline (you can use an in_memory feature class constructed on the fly) to rotate the data frame to show the line east/west.

Note that I am using 10.1 right now, so there is one function in this, RemoveTableview that might not work in 10.0. I could not find it in the 10.0 documentation. If so, you can take that out, but you might have to do some cleanup to remove the reference to the in memory table from your mxd. This is not the fastest function out there, but the particular problem you have, finding the longest dimension across a polyline, is an O(n!) operation AFAIK, and so the PointDistance tool is going to be your best bet. FeatureVerticesToPoints is a pretty costly operation too, as well as freeing up the in_memory feature class at the end (but at least that is better than writing to disk).

def rotateToPolyline(fc):
    mxd = arcpy.mapping.MapDocument("CURRENT")
    df = arcpy.mapping.ListDataFrames(mxd)[0]
    vname = arcpy.CreateUniqueName("Vertices", "in_memory")
    dname = arcpy.CreateUniqueName("Distances", "in_memory")
    arcpy.FeatureVerticesToPoints_management(fc, vname)
    vertices = arcpy.Describe(vname)
    arcpy.PointDistance_analysis(vertices.name, vertices.name, dname)
    distances = arcpy.Describe(dname)
    rows = arcpy.SearchCursor(distances.name)
    max = 0
    from_id = -1
    to_id = -1
    for row in rows:
        if row.getValue("DISTANCE") > max:
            max = row.getValue("DISTANCE")
            from_id = row.getValue("INPUT_FID")
            to_id = row.getValue("NEAR_FID")
    if max > 0:
        oidfield = arcpy.AddFieldDelimiters(vertices.name, vertices.OIDFieldName)
        pt_from = arcpy.SearchCursor(vertices.name, oidfield + " = " + str(from_id))
        pt_to = arcpy.SearchCursor(vertices.name, oidfield + " = " + str(to_id))
        pt_from = pt_from.next().getValue(vertices.ShapeFieldName)
        pt_to = pt_to.next().getValue(vertices.ShapeFieldName)
        rise = pt_to.firstPoint.Y - pt_from.firstPoint.Y
        run = pt_to.firstPoint.X - pt_from.firstPoint.X
        df.rotation = -math.degrees(math.atan2(rise, run))
        df.rotation = 0
    arcpy.mapping.RemoveLayer(df, arcpy.mapping.Layer(vertices.name))
    #RemoveTableView might not work in 10.0
    arcpy.mapping.RemoveTableView(df, arcpy.mapping.TableView(distances.name))
  • Thanks blord-castillo. It worked nicely. The "in_memory" fc and table didn't work for me. I wrote the data to disc. And the describe objects name property didn't seem to work so I just referenced the table directly. Do you have any insight why the in_memory data didn't work? Maybe that would help with the searchcursor locking I'm seeing in my scripts.
    – Justin
    Feb 15, 2012 at 14:06
  • Does your original feature class have any representations, domains, or subtypes in it? Those are extended features that are not supported by the in_memory workspace. I don't think any other extended features should be able to be carried across the FeatureVerticesToPoints operation, but those three in particular might. Feb 15, 2012 at 21:29
  • Use nameString instead of name for the tableview name. That was another change between versions. Feb 15, 2012 at 21:35

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.