Summary
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.
Discussion
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, point, line, and 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 listElements method on the Layout object 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. It is important that each page layout element be given a unique name so that it can be easily isolated using ArcPy scripting.
The listElements method returns a flattened list of elements. For example, listElements on a graphic element that represents a group of three text elements returns 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.
All grouped elements are treated as graphic elements. Grouped graphic elements cannot be cloned because they may include more than just graphic or text elements. They can 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 trying to clone it.
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 layout 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 positioning 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.
The elementPositionX and elementPositionY values are based on the element's anchor position, which is set on the Format tab for the selected element.
Properties
Property | Explanation | Data Type |
elementHeight (Read and Write) | The height of the element in page units. | Double |
elementPositionX (Read and Write) | The x-location of the element's anchor position. The units assigned or reported are in page units. | Double |
elementPositionY (Read and Write) | The y-location of the element's anchor position. The units assigned or reported are in page units. | Double |
elementRotation (Read and Write) | The element's rotation angle in degrees. Positive values rotate clockwise and negative values rotate counterclockwise. | Double |
elementWidth (Read and Write) | The width of the element in page units. | Double |
isGroup (Read Only) | Returns True if the layout element is a group element. It is not possible to clone or delete group elements. | Boolean |
name (Read and Write) | The name of the element. It is important that all elements have a unique name so they can be easily referenced. | String |
type (Read Only) | Returns a value of GRAPHIC_ELEMENT. | String |
visible (Read and Write) | Returns True if the element is visible on the layout. Instead of moving unwanted objects off the page before printing or exporting, you can toggle the element's visibility. | Boolean |
Method Overview
Method | Explanation |
clone ({suffix}) | Provides a mechanism to clone an existing graphic element on a page layout. |
delete () | Provides a mechanism to delete an existing graphic element on a page layout. |
Methods
clone ({suffix})
Parameter | Explanation | Data Type |
suffix | 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 along with a numeric sequencer. For example, if the parent element name is Line and the suffix value is _copy, the newly cloned elements are named Line_copy, Line_copy_1, Line_copy_2, and so on. If a suffix is not provided, the results resemble Line_1, Line_2, Line_3, and so on. | String |
Grouped text elements can't be cloned. All grouped elements are graphic element types. Verify if a graphic element is grouped by using the isGroup property on the GraphicElement object.
delete ()
It may be necessary to delete existing or cloned graphic elements. Cloned elements, when created, can be given a custom suffix so they can be easy to find when using the wildcard parameter for the listElements method on the Layout object.
Code sample
The following script moves a group element named Title Block to a new location on the page layout and saves the changes.
import arcpy
aprx = arcpy.mp.ArcGISProject(r"C:\Projects\YosemiteNP\Yosemite.aprx")
lyt = aprx.listLayouts("Main attractions*")[0]
elm = lyt.listElements("GRAPHIC_ELEMENT", "Title Block")
elm.elementPositionX = 4.75
elm.elementPositionY = 10.5
aprx.save()
del aprx
The following script constructs a graphic table based on data values from a table in a map. The layout was authored with a vertical line named vertLine, a horizontal line named horzLine, and a text element named cellText. Each of the elements were authored with the appropriate symbology and text 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
aprx = arcpy.mp.ArcGISProject(r"C:\Projects\YosemiteNP\Yosemite.aprx")
#Reference items in the project
m = aprx.listMaps("Yosemite National Park")[0]
lyr = m.listLayers("Valley_Pts")[0]
lyt = aprx.listLayouts("Points of Interest")[0]
horzLine = lyt.listElements("GRAPHIC_ELEMENT", "horzLine")[0]
vertLine = lyt.listElements("GRAPHIC_ELEMENT", "vertLine")[0]
tableText = lyt.listElements("TEXT_ELEMENT", "cellText")[0]
#Get/set information about the table
numRows = int(arcpy.GetCount_management(lyr).getOutput(0))
rowHeight = 0.2
fieldNames = ["COMPLEXID", "NAME"]
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[0]
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
lyt.exportToPDF(r"C:\Temp\test.pdf")
for elm in lyt.listElements(wildcard="_clone"):
elm.delete()
del aprx