Select to view content in your preferred language

Updating Map Series Layout Charts with Python from IDE

355
1
Jump to solution
01-29-2025 07:55 AM
Labels (2)
BBarbs
by
Occasional Contributor

Hello Community!

I am making a thematic map series using definition queries on a single layer. The layout has a map, two charts, and some dynamic text. The script I wrote iterates through an array of distinct values, applies it to the definition query, saves and appends the layout to a .pdf file (I used this thematic map project as a base). 

 

outputFolder = rf"C:\temp\MapSeries\10_Deliverables"
pdfFileName = "SFY25_MapSeries.pdf"

# Reference project
p = arcpy.mp.ArcGISProject(rf"C:\temp\MapSeries\MapSeries.aprx")

# Reference the map and layout
m = p.listMaps("LayoutMap")[0]
lyt = p.listLayouts("MapSeriesLayout")[0]
lyr = m.listLayers("SFY25_1E")[0]

# Create a new PDF pages will be appended into. Remove the file if it already exists
if os.path.exists(os.path.join(outputFolder, pdfFileName)):
    os.remove(os.path.join(outputFolder, pdfFileName))
pdf = arcpy.mp.PDFDocumentCreate(os.path.join(outputFolder, pdfFileName))

# Loop through types and apply query
for type in selectedTypes:
    iteration = 0

    lyr.definitionQuery = rf"type = '{type}'"

    print(rf"Exporting and appending: {type}")
    lyt.exportToPDF(rf"{outputFolder}{iteration}.pdf")
    pdf.appendPages(rf"{outputFolder}{iteration}.pdf")
    os.remove(rf"{outputFolder}{iteration}.pdf")

    iteration += 1

print("Saving and closing pdf")
pdf.saveAndClose()
print("done")
os.startfile(rf"{outputFolder}\{pdfFileName}")

 

The script works great as long as I'm in ArcGIS Pro (3.3.2). It doesn't matter if I run it through the python window or a notebook, it exports and appends all .pdf files and the map/text/charts all reflect the correct definition query. However, if I run the script from an IDE such as VSCode or PyCharm, only the map and dynamic layout text update with each .pdf. The charts only reflect the data they were displaying when the project was last saved.

Can anyone think of a reason for this difference? I'm using the same python interpreter in ArcPro as my IDE.

Thank you!

0 Kudos
1 Solution

Accepted Solutions
BBarbs
by
Occasional Contributor

I found a way for this to work. It seems like the charts in the layout don't automatically refresh like the map frame does when the script is run outside of ArcGIS Pro. Since I can't find an arcpy method specifically to refresh layout elements, I manually force the charts to update by changing their associate map frame to a secondary, scratch map frame and then back to the main one. My updated script in case anyone else comes across this roadblock in the future:

selectedTypes = [ <<array of types for definition query>> ]

outputFolder = rf"C:\temp\MapSeries\10_Deliverables"
pdfFileName = "SFY25_MapSeries.pdf"

# Reference project
p = arcpy.mp.ArcGISProject(rf"C:\temp\MapSeries\MapSeries.aprx")

# Reference the map and layout
m = p.listMaps("LayoutMap")[0]
lyt = p.listLayouts("MapSeriesLayout")[0]
lyr = m.listLayers("SFY25_1E")[0]

memChart = lyt.listElements("MAPSURROUND_ELEMENT", "Member Chart")[0]
cntyChart = lyt.listElements("MAPSURROUND_ELEMENT", "County Chart")[0]

mainFrame = lyt.listElements("MAPFRAME_ELEMENT", "Map Frame")[0]
scratchFrame = lyt.listElements("MAPFRAME_ELEMENT", "Scratch Frame")[0]

# Create a new PDF pages will be appended into. Remove the file if it already exists
if os.path.exists(os.path.join(outputFolder, pdfFileName)):
    os.remove(os.path.join(outputFolder, pdfFileName))
pdf = arcpy.mp.PDFDocumentCreate(os.path.join(outputFolder, pdfFileName))

# Loop through types and apply query
for type in selectedTypes:
    iteration = 0

    lyr.definitionQuery = rf"type = '{type}'"
    
    memChart.mapFrame = scratchFrame
    memChart.mapFrame = mainFrame

    cntyChart.mapFrame = scratchFrame
    cntyChart.mapFrame = mainFrame

    print(rf"Exporting and appending: {type}")
    lyt.exportToPDF(rf"{outputFolder}{iteration}.pdf")
    pdf.appendPages(rf"{outputFolder}{iteration}.pdf")
    os.remove(rf"{outputFolder}{iteration}.pdf")

    iteration += 1

print("Saving and closing pdf")
pdf.saveAndClose()
print("done")
os.startfile(rf"{outputFolder}\{pdfFileName}")

View solution in original post

0 Kudos
1 Reply
BBarbs
by
Occasional Contributor

I found a way for this to work. It seems like the charts in the layout don't automatically refresh like the map frame does when the script is run outside of ArcGIS Pro. Since I can't find an arcpy method specifically to refresh layout elements, I manually force the charts to update by changing their associate map frame to a secondary, scratch map frame and then back to the main one. My updated script in case anyone else comes across this roadblock in the future:

selectedTypes = [ <<array of types for definition query>> ]

outputFolder = rf"C:\temp\MapSeries\10_Deliverables"
pdfFileName = "SFY25_MapSeries.pdf"

# Reference project
p = arcpy.mp.ArcGISProject(rf"C:\temp\MapSeries\MapSeries.aprx")

# Reference the map and layout
m = p.listMaps("LayoutMap")[0]
lyt = p.listLayouts("MapSeriesLayout")[0]
lyr = m.listLayers("SFY25_1E")[0]

memChart = lyt.listElements("MAPSURROUND_ELEMENT", "Member Chart")[0]
cntyChart = lyt.listElements("MAPSURROUND_ELEMENT", "County Chart")[0]

mainFrame = lyt.listElements("MAPFRAME_ELEMENT", "Map Frame")[0]
scratchFrame = lyt.listElements("MAPFRAME_ELEMENT", "Scratch Frame")[0]

# Create a new PDF pages will be appended into. Remove the file if it already exists
if os.path.exists(os.path.join(outputFolder, pdfFileName)):
    os.remove(os.path.join(outputFolder, pdfFileName))
pdf = arcpy.mp.PDFDocumentCreate(os.path.join(outputFolder, pdfFileName))

# Loop through types and apply query
for type in selectedTypes:
    iteration = 0

    lyr.definitionQuery = rf"type = '{type}'"
    
    memChart.mapFrame = scratchFrame
    memChart.mapFrame = mainFrame

    cntyChart.mapFrame = scratchFrame
    cntyChart.mapFrame = mainFrame

    print(rf"Exporting and appending: {type}")
    lyt.exportToPDF(rf"{outputFolder}{iteration}.pdf")
    pdf.appendPages(rf"{outputFolder}{iteration}.pdf")
    os.remove(rf"{outputFolder}{iteration}.pdf")

    iteration += 1

print("Saving and closing pdf")
pdf.saveAndClose()
print("done")
os.startfile(rf"{outputFolder}\{pdfFileName}")
0 Kudos