Skip To Content



The TextElement object provides access to properties that enable its repositioning on the page layout as well as modifying the text string and font size.


The TextElement object represents inserted text within a page layout. This includes items such as inserted text, callouts, rectangle text, titles, and so on. It also includes text strings grouped into a group element. It does not include text strings that are part of a legend or inserted table. 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 TextElements only, use the TEXT_ELEMENT constant for the elementType 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 TextElement is unique from most other page elements in that it has a text property. It is with this property that strings can be modified.

Existing text elements can be cloned and deleted. This capability was initially added to support the creation of dynamic graphic tables. To accomplish this, a layout must be preauthored with a unique set of text elements, each having the appropriate symbology. For example, if column field names have different text property settings than the cell values, then two text elements need to be authored, one for each text style. As the information is read from a table, the text element can be cloned using the clone method and positioned appropriately on the layout using other text 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 listElements function with a wildcard and the same suffix value. The returned list of elements can be further modified or deleted using the delete method.

The elementPositionX and elementPositionY values are based on the element's anchor position, which is set on the FORMAT tab.

It is important to undertand the difference between elementRotation and textAngle. The easiest example is with inserted rectangle text. The elementRotation properties control the rotation of the rectangle whereas the textAngle properties control the angle of the text within the rectangle. For point text, both values are synchronized regardless of which property is set.


PropertyExplanationData Type
(Read and Write)

The height of the element in page units.

(Read and Write)

The x-location of the element's anchor position. The units assigned or reported are in page units.

(Read and Write)

The y-location of the element's anchor position. The units assigned or reported are in page units.

(Read and Write)

The element's rotation angle in degrees. Positive values rotate clockwise and negative values rotate counterclockwise.

(Read and Write)

The width of the element in page units.

(Read and Write)

The name of the element. It is important that all elements have a unique name so they can be easily referenced.

(Read and Write)

The text string associated with the element.

(Read and Write)

The angle in degrees the text string is rotated. Positive values rotate clockwise and negative values rotate counterclockwise.

(Read and Write)

The element text size in points.

(Read Only)

Returns a value of TEXT_ELEMENT.

(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.


Method Overview

clone ({suffix})

Provides a mechanism to clone an existing text element on a page layout.

delete ()

Provides a mechanism to delete an existing text element on a page layout.


clone ({suffix})
ParameterExplanationData Type

An optional string that is used to tag each newly created text element. The new element gets the same element name as the parent text element, plus the suffix value, plus a numeric sequencer. For example, if the parent element name is FieldLabel and the suffix value is _copy, the newly cloned elements are named FieldLabel_copy, FieldLabel_copy_1, FieldLabel_copy_2, and so on. If a suffix is not provided, the results resemble FieldLabel_1, FieldLabel_2, FieldLabel_3, and so on.


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

TextElement example 1

The following script replaces all occurrences of the year 2013 with the year 2014.

import arcpy
aprx ="C:\Projects\YosemiteNP\Yosemite.aprx")
for lyt in aprx.listLayouts():
    for elm in lyt.listElements("TEXT_ELEMENT"):
        if elm.text == "2013":
            elm.text = "2014"
del aprx
TextElement example 2

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 upper left.

import arcpy
aprx ="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
    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
    print("Invalid value assignment")

#Export to PDF and delete cloned elements

for elm in lyt.listElements(wildcard="_clone"):
del aprx