The GraphicElement object provides access to properties that enables its repositioning on the page layout as well as methods that allow for duplicating and deleting existing graphic elements.
The GraphicElement is a catch-all element type for most generic elements added to a page layout. It includes items such as groups of elements, inserted tables, graphs, neatlines, markers, lines, area shapes, and so on, that are added to a page layout. The most common operations on a graphic element are to get or set its page layout position and size. The ListLayoutElements function returns a Python list of page layout element objects. It is necessary to then iterate through each item in the list or specify an index number to reference a specific page element object. To return a list of only GraphicElements, use the GRAPHIC_ELEMENT constant for the element_type parameter. A wildcard can also be used to further refine the search based on the element name.
Existing graphic elements can be cloned and deleted. This capability was initially added to support the creation of dynamic graphic tables on a page layout where each cell in the table can be outlined using line graphics. To accomplish this, a map document must be authored with at least two graphic line elements: a vertical line and a horizontal line. As the information is read from a table, the lines can be cloned using the clone method and sized and positioned appropriately using other graphic element properties. When cloning an element it is very useful to provide a suffix value so that cloned elements can be easily identified while using the ListLayoutElements function with a wildcard and the same suffix value. The returned list of elements can be further modified or deleted using the delete method. There is a complete code sample for building a dynamic graphic table at the bottom of this topic.
Grouped graphic elements cannot be cloned. That is because grouped elements may include more than just graphic elements; they could also include items like north arrows, scale bars and so on. Use the isGroup property to determine if a graphic element is a group element before tyring to clone it.
ListLayoutElements will return a flattened list of elements. For example, ListLayoutElements on a graphic element that represents a group of three text elements will return a total of four elements: the group element and each individual text element. The GraphicElement can be used to reposition all items at the same time or the text element text values can be managed individually.
It is recommended that each page layout element be given a unique name so that it can be easily isolated using arcpy scripting. This is set via the Size and Position tab on the Properties dialog box in ArcMap.
X and Y element positions are based on the element's anchor position which is also set via the Size and Position tab on the Properties dialog box in ArcMap.
Page units can only be changed in ArcMap via Customize > ArcMap Options > Layout View Tab.
(Read and Write)
The height of the element in page units. The units assigned or reported are in page units.
(Read and Write)
The x location of the data frame element's anchor position. The units assigned or reported are in page units.
(Read and Write)
The y location of the data frame element's anchor position. The units assigned or reported are in page units.
(Read and Write)
The width of the element in page units. The units assigned or reported are in page units.
Returns True if the layout element is a group element. It is not possible to clone or delete group elements.
(Read and Write)
The name of the element.
Returns the element type for any given page layout element.
Provides a mechanism to clone an existing graphic element on a page layout.
Provides a mechanism to delete an existing graphic element on a page layout.
An optional string that is used to tag each newly created graphic element. The new element will get the same element name as the parent graphic plus the suffix value plus a numeric sequencer. For example, if the parent element name is Line and the suffix value is _copy, the newly cloned elements would be named Line_copy, Line_copy_1, Line_copy_2, and so on. If a suffix is not provided, then the results would look like Line_1, Line_2, Line_3, and so on.
Grouped graphic elements can't be cloned. First check to see if a graphic element is grouped by using the isGroup property.
It may be necessary to delete cloned elements. Cloned elements, when created, can be given a custom suffix so they can be easy to find when using the wildcard parameter on the ListLayoutElements function.
GraphicElement example 1
The following script will move a group element named Title Block to a new location on the page layout, then save the changes.
import arcpy mxd = arcpy.mapping.MapDocument(r"C:\Project\Project.mxd") for elm in arcpy.mapping.ListLayoutElements(mxd, "GRAPHIC_ELEMENT"): if elm.name == "Title Block": elm.elementPositionX = 4.75 elm.elementPositionY = 10.5 mxd.save() del mxd
GraphicElement example 2
The following script will construct a graphic table based on data values from a table in the map document. The map document was authored with a vertical line named vertLine, a horizontal line named horzLine, and a text element named TableText. Each of the elements were authored with the appropriate symbology properties. The element's anchors were also set to the upper left position and the text element's vertical and horizontal justification were set to top left.
import arcpy mxd = arcpy.mapping.MapDocument(r"C:\Project\Project.mxd") #Reference items in the map document lyr = arcpy.mapping.ListLayers(mxd, "Accidents") horzLine = arcpy.mapping.ListLayoutElements(mxd, "GRAPHIC_ELEMENT", "horzLine") vertLine = arcpy.mapping.ListLayoutElements(mxd, "GRAPHIC_ELEMENT", "vertLine") tableText = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "TableText") #Get/set information about the table numRows = int(arcpy.GetCount_management(lyr).getOutput(0)) rowHeight = 0.2 fieldNames = ["X", "Y", "Accidents"] numColumns = len(fieldNames) colWidth = 1.5 #Build graphic table lines based on upper left coordinate # set the proper size of the original, parent line, then clone it and position appropriately upperX = 1.0 upperY = 5.0 #Vertical lines vertLine.elementPositionX = upperX vertLine.elementPositionY = upperY vertLine.elementHeight = (rowHeight * numRows) + rowHeight #extra line for column names x = upperX for vert in range(1, numColumns+1): x = x + colWidth vert_clone = vertLine.clone("_clone") vert_clone.elementPositionX = x #Horizontal lines horzLine.elementPositionX = upperX horzLine.elementPositionY = upperY horzLine.elementWidth = numColumns * colWidth y = upperY - rowHeight for horz in range(1, numRows +2 ): #need to accommodate the extra line for field names temp_horz = horzLine.clone("_clone") temp_horz.elementPositionY = y y = y - rowHeight #Place text column names tableText.elementPositionX = upperX + 0.05 #slight offset tableText.elementPositionY = upperY tableText.text = fieldNames accumWidth = colWidth for field in range(1, numColumns): newFieldTxt = tableText.clone("_clone") newFieldTxt.text = fieldNames[field] newFieldTxt.elementPositionX = newFieldTxt.elementPositionX + accumWidth accumWidth = accumWidth + colWidth #Create text elements based on values from the table table = arcpy.SearchCursor(lyr.dataSource) y = upperY - rowHeight for row in table: x = upperX + 0.05 #slight offset try: for field in fieldNames: newCellTxt = tableText.clone("_clone") newCellTxt.text = row.getValue(field) newCellTxt.elementPositionX = x newCellTxt.elementPositionY = y accumWidth = accumWidth + colWidth x = x + colWidth y = y - rowHeight except: print"Invalid value assignment" #Export to PDF and delete cloned elements arcpy.mapping.ExportToPDF(mxd, r"C:\Temp\test.pdf") for elm in arcpy.mapping.ListLayoutElements(mxd, wildcard="_clone"): elm.delete() del mxd