Summary
The LegendElement object provides access to properties and methods that enable its repositioning and resizing on the page layout as well as modifying its title and legend items.
Discussion
Like a MapsurroundElement, the LegendElement object has an association with a single parent data frame. In addition, the LegendElement also has methods and properties for managing the contents within the legend. These are useful for controlling how new items get added to the legend, sizing the legend, updating legend item properties using a style item, and also for specifying the number of columns in a legend.
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 LegendElements, use the LEGEND_ELEMENT constant for the element_type parameter. A wildcard can also be used to further refine the search based on the element name.
Legend elements in a layout have a property in the ArcMap user interface called Add a new item to the legend when a new layer is added to the map which allows the legend to automatically update when layers are added or removed from a map. The autoAdd property toggles this behavior on/off so you can control whether or not a newly added layer should appear in the legend. For example, you may want to add orthophotography, but you don't want it to appear in the legend. Prior to using the AddLayer function, you would want to set the autoAdd property to False.
Legend elements in the ArcMap user interface also have a property called Fixed Frame. When this property is toggled on and too many legend items get added, there may not be enough room for all items to fit within the fixed area specified. When this happens, the legend elements that don't fit are replaced by a small icon that indicates the legend is overflowing. The isOverflowing property allows you to check for this, then resize the legend element or modify the legend items appropriately by providing a legend item style item that uses smaller fonts, for example.
The removeItem and updateItem properties serve a basic arcpy.mapping requirement: to provide the ability to remove legend items or modify their style items with custom settings. In the user interface, when you add a new layer to the table of contents and that feature gets automatically added to the legend, a default style is applied. The arcpy.mapping module allows you to update the individual legend item style items in a LegendElement on a page layout. This can be accomplished using the following workflow.
- Author a custom legend item style item using the Style Manager.
- Reference the custom legend item style item using the ListStyleItems function.
- Reference the legend element using the ListLayoutElements function.
- Update a specific legend item style item in the legend using the updateItem method on the LegendElement class.
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.
Properties
Property | Explanation | Data Type |
autoAdd (Read and Write) | Controls whether a layer should be automatically added to the legend when using the AddLayer or AddLayerToGroup functions. This property mimics the Map Connection check box option labeled Add a new item to legend when a new layer is added to the map, found via the Legend Properties dialog box's Item tab. | Boolean |
elementHeight (Read and Write) | The height of the element in page units. The units assigned or reported are in page units. | Double |
elementPositionX (Read and Write) | The x location of the data frame element's anchor position. The units assigned or reported are in page units. | Double |
elementPositionY (Read and Write) | The y location of the data frame element's anchor position. The units assigned or reported are in page units. | Double |
elementWidth (Read and Write) | The width of the element in page units. The units assigned or reported are in page units. | Double |
isOverflowing (Read Only) | Returns True if the legend items can't fit when the Fixed Frame option is set within legend properties. | Boolean |
items (Read Only) | Returns a list of strings that represents the individual legend item names. | String |
name (Read and Write) | The name of the element. | String |
parentDataFrameName (Read Only) | A string that represents the name of the data frame for the associated element. | String |
title (Read and Write) | The text string that represents the legend's title. | String |
type (Read Only) | Returns the element type for any given page layout element.
| String |
Method Overview
Method | Explanation |
adjustColumnCount (column_count) | Provides a mechanism to set the number of columns in a legend. |
listLegendItemLayers () | Returns a list of Layer object references for every legend item in a legend. |
removeItem (legend_item_layer, {index}) | The removeItem method allows you to remove a legend item from a legend on a layout. |
updateItem (legend_item_layer, {legend_item_style_item}, {preserve_item_sizes}, {use_visible_extent}, {show_feature_count}, {use_ddp_extent}, {index}) | The updateItem method allows you to update a number of individual properties for a legend item within a legend on a layout. |
Methods
adjustColumnCount (column_count)
Parameter | Explanation | Data Type |
column_count | An integer that represents the desired number of columns. (The default value is 1) | Integer |
There are plenty of cases where there is not enough space on a layout to fit all legend items in a single column. A legend can be interrogated using its elementHeight or elementWidth properties to determine the needed space on the page. Another method would be to count the number of items in a legend. Whichever method is used, adjustColumnCount can then be used to establish the number of desired columns in a legend.
listLegendItemLayers ()
Return Value
Data Type | Explanation |
Layer | A Python list of Layer objects. Each legend item references a layer. |
The listLegendItemLayers method is useful for determining the different layers and the number of times they are being used in a legend. A Layer object is returned for each legend item found in a legend. It is possible that a layer can appear in the table of contents only once but exist in the legend multiple times. By evaluating the returned list of Layer objects (one for each legend item), you can determine if the layer exists multiple times. If you want to remove or modify each of those instances, you will need to provide an index parameter value for both the removeItem and updateItem methods.
removeItem (legend_item_layer, {index})
Parameter | Explanation | Data Type |
legend_item_layer | A reference to a layer that is used in a legend. | Layer |
index | A single layer can be added into the same legend multiple times. The index value provides a way to reference a specific legend item. If you have more than one item and you want to remove all instances, then the removeItem will need to be called multiple times. By default the first legend item for a layer is removed. (The default value is 0) | Long |
There may be times when you want to remove an item from the legend. For example, a legend item for orthophotography doesn't really make sense to have in a legend. The removeItem method allows you to remove an individual legend item from the legend on a layout after it has been automatically added. Another option is to use set the autoAdd property on a legend to control whether or not a newly added layer will get automatically added to the legend.
updateItem (legend_item_layer, {legend_item_style_item}, {preserve_item_sizes}, {use_visible_extent}, {show_feature_count}, {use_ddp_extent}, {index})
Parameter | Explanation | Data Type |
legend_item_layer | A reference to a layer that is used in a legend. | Layer |
legend_item_style_item | A reference to a legend item style item that is returned from the ListStyleItems function. This item must come from the style folder name Legend Items. (The default value is None) | Object |
preserve_item_sizes | A Boolean that controls whether or not the symbol sizes can change if the size of the legend is changed. If set to True, the sizes authored in the style item will remain unchanged. (The default value is False) | Boolean |
use_visible_extent | A Boolean that controls if only the features in the data frame's visible extent will be displayed in the legend. (The default value is False) | Boolean |
show_feature_count | A Boolean that controls if feature counts will be displayed in the legend. (The default value is False) | Boolean |
use_ddp_extent | A Boolean that controls if only the features within the Data Driven Pages index layer feature will be displayed in the legend. Data Driven Pages must be enabled. (The default value is False) | Boolean |
index | A single layer can be added into the same legend multiple times. The index value provides a way to reference a specific legend item. If you have more than one item and you want to remove all instances, then the updateItem method will need to be called multiple times. By default the first legend item for a layer is updated. (The default value is 0) | Long |
The updateItem method serves a basic arcpy.mapping requirement to provide the ability to update legend items with custom settings. In the user interface, when you add a new layer to the table to contents, and that feature is automatically added to the legend, a default style is applied. The arcpy.mapping module allows you to update the individual legend items in a LegendElement on a page layout.
Code Sample
LegendElement example 1
The following script will add layers to a new data frame within a map document that includes an inserted legend element named Legend. The layers will automatically get added to the legend except for the orthophoto. This is controlled using the autoAdd property. Finally, after the layers are added, the number of columns are adjusted to two.
import arcpy
mxd = arcpy.mapping.MapDocument(r"C:\Project\Project.mxd")
df = arcpy.mapping.ListDataFrames(mxd, "New Data Frame")[0]
lyr1 = arcpy.mapping.Layer(r"C:\Project\Data\Parcels.lyr")
lyr2 = arcpy.mapping.Layer(r"C:\Project\Data\MapIndex.lyr")
lyr3 = arcpy.mapping.Layer(r"C:\Project\Data\Orthophoto.lyr")
legend = arcpy.mapping.ListLayoutElements(mxd, "LEGEND_ELEMENT", "Legend")[0]
legend.autoAdd = True
arcpy.mapping.AddLayer(df, lyr1, "BOTTOM")
arcpy.mapping.AddLayer(df, lyr2, "BOTTOM")
legend.autoAdd = False
arcpy.mapping.AddLayer(df, lyr3, "BOTTOM")
legend.adjustColumnCount(2)
mxd.save()
del mxd
LegendElement example 2
The following script works with a legend element with Fixed Frame toggled on. If the legend items are overflowing, the script will increase the height of the legend by 0.1 inch until all items fully display.
import arcpy
mxd = arcpy.mapping.MapDocument(r"C:\Project\Project.mxd")
legendElm = arcpy.mapping.ListLayoutElements(mxd, "LEGEND_ELEMENT", "Legend")[0]
while legendElm.isOverflowing:
legendElm.elementHeight = legendElm.elementHeight + 0.1
del mxd
LegendElement example 3
The following script uses the workflow outlined above and updates a given legend item. A layer is added to the first data frame in the map document and the legend item will be updated with a custom legend item style item called NewDefaultLegendStyle. The custom .style file is saved in the user's profile location. Next, the script checks to see if the legend is overflowing, and if it does, it removes an unnecessary layer from the legend to make additional room.
import arcpy
mxd = arcpy.mapping.MapDocument(r"C:\Project\Project.mxd")
df = arcpy.mapping.ListDataFrames(mxd)[0]
lyrFile = arcpy.mapping.Layer(r"C:\Project\Data\Rivers.lyr")
arcpy.mapping.AddLayer(df, lyrFile, "TOP")
lyr = arcpy.mapping.ListLayers(mxd, 'Rivers', df)[0]
styleItem = arcpy.mapping.ListStyleItems("USER_STYLE", "Legend Items", "NewDefaultLegendStyle")[0]
legend = arcpy.mapping.ListLayoutElements(mxd, "LEGEND_ELEMENT")[0]
legend.updateItem(lyr, styleItem)
if legend.isOverFlowing:
removeLyr = arcpy.mapping.ListLayers(mxd, "County Boundary")[0]
legend.removeItem(removeLyr)
del mxd
LegendElement example 4
The following script updates all layers in the legend to use a custom legend item style item called MyNewStyle.
import arcpy
mxd = arcpy.mapping.MapDocument(r"C:\Project\Project.mxd")
legend = arcpy.mapping.ListLayoutElements(mxd,"LEGEND_ELEMENT")[0]
styleItem = arcpy.mapping.ListStyleItems("USER_STYLE",
"Legend Items",
"MyNewStyle")[0]
for lyr in legend.listLegendItemLayers():
legend.updateItem(lyr, styleItem)
del mxd