Is there a way to make the title of a layout dynamic with a feature class? I know there is dynamic text with the Map Frame, Project Name, Metadata, and many other things. From the research I have done it seems like it might have been possible in ArcMap, but I have been unable to find anything in ArcGIS Pro that would allow for the layout title to be dynamic with a feature class.
To expand a little further. I have a large arcpy script where 80 layouts are created (from 1 template layout) and exported into a PDF, but right now each layout has the same generic title so sometime it is hard to know what data is being shown in the layout. This problem could be solved if the layout's title was Dynamic with the feature class that is being portrayed in the layout.
I considered using the following code, which uses the TextElement, but it looks to me like I would have to specify each individual title for every layout. And if I have 80+ layouts, that could take a long time.
p = arcpy.mp.ArcGISProject("Current")
for lyt in p.listLayouts():
for elm in lyt.listElements("TEXT_ELEMENT"):
if elm.name == "title": # this is the element name set via text properties
# add layout feature class check logic
elm.text = "New Title" # changing title name
Am I reading this right?
Is there a better way?
Solved! Go to Solution.
The final code I used to get the results I was looking for is:
import arcpy
from arcpy import env
import sys
import os
import datetime
elm_name = "My Dynamic Title" # the name you assign to the title (TEXT) element
p = arcpy.mp.ArcGISProject(r"C:\arcGIS_Shared\Python\CenterHeatMaps.aprx")
for lyt in p.listLayouts("Layout_King"): # get the element
for elm in lyt.listElements("TEXT_ELEMENT"):
if elm.name == elm_name:
text_elm = elm
break
for m in p.listMaps(): # loop through your layer / layouts / maps
for lyr in m.listLayers("BCBS*"):
new_title=lyr.name # do your logic with the layer
elm.text=new_title
lyt.exportToPDF(r"C:\arcGIS_Shared\Exports" + "\\BCBS_" + elm.name[13:] + ".pdf") # export the map
print(elm.name[13:])
Thank you everyone for your help and input!
Have you considered using a TextElement—ArcPy | ArcGIS Desktop and updating the text property?
I updated my question in response to your TextElement suggestion
You could read out the layer used fro a layout, determine the name in the layout and use that as the text in the text element. Do you have all the 80 layouts in a single ArcGIS Pro project? How are the map frames defined for each layout?
I forgot to specify that it is really just one layout that is being used as a template. So the 80 PDFs are really just different versions of the same layout
So what do you change in the process to create the 80 maps?
I'll just list the steps that the script goes through.
1) Geocode Addresses
2) Summarize Within Loop based on locations (80 locations) - so 80 feature classes
3) Apply Symbology to 80 feature classes
4) Export PDFs after referencing Bookmarks (80 bookmarks based on the previous locations)
So each layout is based on a different Bookmark and depicts the corresponding feature class also
For each map you generate, I suppose you have access to the layer it is based on. The name property will provide you the name which could be used for the title. In Pro you will have to add a text element and give it a name:
This name can be used to "find" the element and change the title. Something along the lines of this (untested) code:
elm_name = "My Dynamic Title" # the name you assign to the title (TEXT) element
aprx = arcpy.mp.ArcGISProject("Current")
# get the element
for lyt in aprx.listLayouts():
for elm in lyt.listElements("TEXT_ELEMENT"):
if elm.name == elm_name:
text_elm = elm
break
# loop through your layer / layouts / maps
for m in aprx.listMaps():
for lyr in m.listLayers():
# do your logic with the layer
new_title = lyr.name
elm.text = new_title
# export the map
Xander, thanks for all your help with my question. I realize that the code you are suggesting is untested, so I have been experimenting with it the best I can. Here is my updated version of your code:
import arcpy
from arcpy import env
import sys
import os
import datetime
elm_name = "My Dynamic Title"
p = arcpy.mp.ArcGISProject(r"C:\arcGIS_Shared\Python\CenterHeatMaps.aprx")
for lyt in p.listLayouts("Layout_King") [0]:
for elm in lyt.listElements("TEXT_ELEMENT"):
if elm.name==elm_name:
text_elm=elm
break
for m in p.listMaps():
for lyr in m.listLayers("BCBS*"):
new_title=lyr.name
elm.text=new_title
lyt.exportToPDF(r"C:\arcGIS_Shared\Exports" + "\\BCBS" + elm.name[13:] + ".pdf")
print(elm.name[13:])
But when I try and run it it gives me the following error:
Traceback (most recent call last):
File "<string>", line 8, in <module>
TypeError: 'Layout' object is not iterable
Do you know what I'm doing wrong? Also, does it look like I'm at least on the right track?
When you sliced the list of layouts to get the first element, it is no longer a list, hence it isn't iterable. Xander's example didn't do the slicing as you will notice, so his code gets a list of layouts, not a single layout. If there were only one layout, it would be contained in a list. So, you could try dumping the slice ( aka [0] ) if you are sure there is only one layout with that name.
for lyt in p.listLayouts("Layout_King")[0]: