|
POST
|
@BinhLe2 could you provide a little more detail, screenshots, and perhaps more of your script? There are probably a number of ways to approach this, but the summary doesn't provide enough context. A map series page order is based on an internal index number based on the sort field. If you export a map series (with or without Python) the pages should follow that order. Are you exporting to a single file, multiple files? Again, having more context will help us identify if there is a bug. Jeff - arcpy.mp team
... View more
11-14-2025
10:24 AM
|
0
|
0
|
345
|
|
IDEA
|
Hello @JamesPoeschel , As a stop gap prior to this idea being considered by the layout team, you could use a simple Python script to automate the process. Paste the following in the Python window (be sure to edit the layout name): p = arcpy.mp.ArcGISProject('current')
lyt = p.listLayouts('LAYOUT NAME GOES HERE')[0]
for txt in lyt.listElements('text_element'):
txt.name = txt.text Note, this would need to be tested very thoroughly with your own layouts. A few problematic situations that immediately come to mind are 1) long paragraph text elements, 2) dynamic text elements, and 3) text elements that have identical strings will still be forced to have unique names etc. Jeff - arcpy.mp team
... View more
10-16-2025
12:36 PM
|
0
|
0
|
729
|
|
IDEA
|
Based on the responses in the thread and knowing that we are not able to close a specific active view for reasons described above, we are going to close this idea until we get a well defined use case. Jeff - arcpy.mp team
... View more
08-25-2025
01:24 PM
|
0
|
0
|
1357
|
|
IDEA
|
@wtfineberg I believe there is a misunderstanding between changing a Map's default Extent property vs changing the extent of an active MapView. Map.defaultCamera - Modifying the defaultCamera will not affect an existing view. This property is only applied when a new MapView is opened or a new MapFrame is inserted into a layout. You can change the extent of an active MapView using the Camera object, not the defaultCamera property. I've modified the code above slightly to change the active MapView's extent. aprx = arcpy.mp.ArcGISProject('current')
map_view = aprx.activeView
layer = map_view.map.listLayers('GreatLakes')[0]
arcpy.management.SelectLayerByAttribute(layer, "NEW_SELECTION", f"NAME = 'Lake Superior'")
map_view.camera.setExtent(map_view.getLayerExtent(layer, True)) Notice, I'm using activeView, NOT activeMap. ActiveView returns a MapView object whereas activeMap returns a Map object. It is from the active view that I get the associated map and then reference a layer. If I were to then type: m = aprx.listMaps('Map')[0]
m.defaultCamera = map_view.camera The next time I go to open a new map view for the 'Map', it will be zoomed to Lake Superior. Jeff
... View more
08-25-2025
01:09 PM
|
0
|
0
|
1331
|
|
IDEA
|
I marked this as Already Offered in that there is an arcpy.mp sample that accomplishes this and this is unlikely to go into the core product due to how specialized and custom the requirement is. Below is a link to a sample. It extends map series and includes layout element into the same table that drives the map series. The placement of layout elements are simply placed in fields in a table. https://www.arcgis.com/home/item.html?id=82b99b5593e54e57b740e3898fb14c5f Please review and I hope it helps. Jeff - arcpy.mp and Layout SDK teams
... View more
06-27-2025
08:02 AM
|
0
|
0
|
687
|
|
POST
|
@JasonBennett I'm glad it worked. Comparing the before and after is super useful especially if you minimize the changes to the absolute necessary steps between saves. Sometime you might see new objects are introduced and that is when you would might need to use CreateCIMObjectFromClassName. It is covered in this topic: https://pro.arcgis.com/en/pro-app/latest/arcpy/mapping/python-cim-access.htm Jeff
... View more
06-05-2025
11:20 AM
|
1
|
0
|
1522
|
|
POST
|
Hello @JasonBennett , I just tried the following and it works for me. I find the best approach to learning where stuff is persisted in the CIM is to create a before and after result that can be compared using an application that shows differences (e.g. WinMerge). So what I did first was export my Best Fit map series to a PAGX file. Then I changed my options to use Center and Maintain Scale and exported to a PAGX again with a different name. I use WinMerge to compare the two text files (tip, if you rename the *.pagx to *.json, the formatting may look cleaner). When I compare the differences, I see that the map series CIM has a "extentOptions" property and I changed it from "BestFit" to the "ExtentCenter" enum. Then I updated the map series mapframe camera scale property. Here is the code I used to make the changed to my map series. #Reference project and layout
p = arcpy.mp.ArcGISProject('current')
lyt = p.listLayouts('*_MS')[0]
#First, change the map series extent option
ms = lyt.mapSeries
ms_cim = ms.getDefinition('V3')
ms_cim.extentOptions = 'ExtentCenter' #Center and Maintain Scale
ms.setDefinition(ms_cim)
#Now change the scale of the map frame (via the camera object)
mf = lyt.listElements('mapframe_element', 'Map Frame')[0]
cam = mf.camera.scale
cam.scale = 5000000 I hope this was helpful, Jeff - arcpy.mp team
... View more
06-05-2025
09:21 AM
|
3
|
1
|
1530
|
|
POST
|
@StephanieStedman have you tried the following ArcGISProject members added at Pro 3.3. - listToolboxes - updateToolboxes() https://pro.arcgis.com/en/pro-app/latest/arcpy/mapping/arcgisproject-class.htm Adding folder connections and databases work the same. Code Sample 4 in the link above. A very simplified for adding a single toolbox is: p = arcpy.mp.ArcGISProject('current')
tbxs = p.toolboxes
tbxs.append({'toolboxPath': r"C:\Temp\MyToolbox.atbx, 'isDefaultToolbox': False})
p.updateToolboxes(tbxs)
You could even start with an empty toolbox dictionary but be sure to make one (and only one) of them the default toolbox. Jeff - arcpy.mp team
... View more
05-14-2025
01:19 PM
|
1
|
1
|
1554
|
|
POST
|
Please refer to the solution provided under the following idea: https://community.esri.com/t5/arcgis-pro-ideas/vary-symbology-by-rotation-accessible-by-arcpy/idi-p/939228 Jeff - arcpy.mp and Layout (SDK) teams
... View more
05-08-2025
10:37 AM
|
0
|
0
|
762
|
|
IDEA
|
We know this is a long time coming. We want to add helper functions to our API but the priority is lower than many other capabilities so we hope this serves as a solution. It uses Python CIM Access. Sample 1: Vary Symbology using Rotation The following script will rotate each feature in a point feature class using VarySymbology By Attribute based on an attribute that controls ROTATION. If the visual variable already exists, it toggles the rotation type each time the script is run. # Create / Modify point layer symbol to Vary Symbology by Attribute using Rotation
# The script will effectively change the symbology each time it runs:
# First, if visual variables don't exist, it create a one using rotation.
# Second, if it does exist, it reverses the rotation type each time.
p = arcpy.mp.ArcGISProject('current')
m = p.listMaps('VarySymByAttr - Rotation')[0]
l = m.listLayers('Cities - No Rotation')[0]
l_cim = l.getDefinition('V3')
if len(l_cim.renderer.visualVariables) == 0:
print('Visual Variable DOES NOT exist ... creating with default values')
XYvvInfo = arcpy.cim.CreateCIMObjectFromClassName('CIMVisualVariableInfo', 'V3')
XYvvInfo.randomMax = 360
XYvvInfo.visualVariableInfoType = None
ZexpInfo = arcpy.cim.CreateCIMObjectFromClassName('CIMExpressionInfo', 'V3')
ZexpInfo.title = "Custom"
ZexpInfo.expression = "$feature.HAWN_PI"
ZexpInfo.returnType = "Default"
ZvvInfo = arcpy.cim.CreateCIMObjectFromClassName('CIMVisualVariableInfo', 'V3')
ZvvInfo.randomMax = 360
ZvvInfo.visualVariableInfoType = "Expression"
ZvvInfo.valueExpressionInfo = ZexpInfo
rvv = arcpy.cim.CreateCIMObjectFromClassName('CIMRotationVisualVariable', 'V3')
rvv.visualVariableInfoX = XYvvInfo
rvv.visualVariableInfoY = XYvvInfo
rvv.visualVariableInfoZ = ZvvInfo
rvv.rotationTypeZ = "Arithmetic"
l_cim.renderer.visualVariables = [rvv]
l.setDefinition(l_cim)
else:
print('Visual Variable already DOES exist ... modifying rotation type')
for vv in l_cim.renderer.visualVariables:
if isinstance(vv, arcpy.cim.CIMSymbolizers.CIMRotationVisualVariable):
if vv.rotationTypeZ == "Arithmetic":
vv.rotationTypeZ = 'Geographic'
else:
vv.rotationTypeZ = 'Arithmetic'
l.setDefinition(l_cim) Sample 2: Vary Symbology using Transparency The following script will modify the transparency for each feature in a polygon feature class using VarySymbology By Attribute based on an attribute that controls TRANSPARENCY. If the visual variable already exists, it changes the transparency values. #Create / Modify polygon layer symbol to Vary Symbology by Attribute using Transparency
# The script will effectively change the symbology 3 times:
# First, if visualvariables don't exist,
# Second, if the transparency values are default, change
# Third, if they are not default change to something else.
p = arcpy.mp.ArcGISProject('current')
m = p.listMaps('VarySymByAttr - Transparency')[0]
l = m.listLayers('States*')[0]
l_cim = l.getDefinition('V3')
#Get min/max values of renderer
minValue = l.symbology.renderer.lowerBound
maxValue = l.symbology.renderer.classBreaks[-1].upperBound
if len(l_cim.renderer.visualVariables) == 0:
print('Visual Variable DOES NOT exist ... creating with default values')
ai = arcpy.cim.CreateCIMObjectFromClassName('CIMVisualVariableAuthoringInfo', 'V3')
ai.minSliderValue = minValue
ai.maxSliderValue = maxValue
ai.heading = 'POP2000'
tvv = arcpy.cim.CreateCIMObjectFromClassName('CIMTransparencyVisualVariable', 'V3')
tvv.authoringInfo = ai
tvv.field = 'POP2000'
tvv.transparencyValues = [70, 30]
tvv.dataValues = [minValue, maxValue]
tvv.normalizationType = "Nothing"
tvv.valueExpressionInfo = None
l_cim.renderer.visualVariables = [tvv]
l.setDefinition(l_cim)
else:
print('Visual Variable already DOES exist ... modifying transparencyValues')
if l_cim.renderer.visualVariables[0].transparencyValues == [70, 30]:
l_cim.renderer.visualVariables[0].transparencyValues = [80, 0]
else:
l_cim.renderer.visualVariables[0].transparencyValues = [50, 0]
l.setDefinition(l_cim) Jeff - arcpy.mp and Layout (SDK) teams
... View more
05-08-2025
10:35 AM
|
0
|
0
|
714
|
|
POST
|
@MollyMoore is it possible that the field properties were never modified? In other words, if you add a new data source as a layer and try to use Python CIM Access to modified the field properties, it won't work. The reason is that because NO properties were previously altered. The layer JSON only persists changes. If no changes are made, then you won't see the properties. All you have to do is modify one property for one layer, save, and then you will see everything. Here is a basic example that checks to see if the field descriptions properties exist in the CIM. If not, it uses a temporary makeFeatureLayer work around to force those properties into the CIM. def updateCIMFields(l, cimLyr):
fList = ["SQKM", "POP2001", "Shape_Length", "Shape_Area"]
for fd in cimLyr.featureTable.fieldDescriptions:
if fd.fieldName in fList:
fd.numberFormat.roundingOption = "esriRoundNumberOfDecimals"
fd.numberFormat.roundingValue = 0
fd.numberFormat.zeroPad = True
l.setDefinition(cimLyr)
return cimLyr
p = arcpy.mp.ArcGISProject('current')
m = p.listMaps()[0]
lyr = m.listLayers('Provinces')[0]
lyr_cim = lyr.getDefinition('V3')
if len(lyr_cim.featureTable.fieldDescriptions) == 0: #NO CIM field info present
print('No CIM Field Info')
mkLyr = arcpy.management.MakeFeatureLayer(lyr)[0]
mkLyr_cim = mkLyr.getDefinition('V3')
mkLyr_cim = updateCIMFields(mkLyr, mkLyr_cim)
#Paste CIM information and remove temporary layer
lyr.pasteProperties(mkLyr, 'FIELD_PROPERTIES')
m.removeLayer(mkLyr)
else: #CIM field info present
print('CIM Field Info Pre-Exists')
lyr_cim = updateCIMFields(lyr, lyr_cim)
lyr.setDefinition(lyr_cim) Jeff - arcpy.mp team
... View more
04-30-2025
12:24 PM
|
0
|
0
|
1125
|
|
POST
|
An Esri Idea was just added for this. Please review and consider the code samples as a possible solution. https://community.esri.com/t5/arcgis-pro-ideas/arcpy-mp-support-for-thematic-map-series/idi-p/1609908 Jeff - arcpy.mp team
... View more
04-29-2025
07:25 AM
|
0
|
0
|
1446
|
|
IDEA
|
Thank you for your feedback. Thematic map series has been possible with arpcy.mp well before it was available in the UI. Its simply a matter of turning layers on and off. We made a sample available: https://www.arcgis.com/home/item.html?id=eba53351ceb84b58b505dec5272e526c - Note the sample needs to be updated because the web layers were taken offline but the toolboxes, code and readme are still good. The UI uses a very similar technique where layers are organized into groups and groups are simply toggled to control layer visibility. We do hope to support a thematic map series but it is not in the immediate future. Your kudos will help us prioritize. Jeff - arcpy.mp team
... View more
04-29-2025
07:23 AM
|
0
|
0
|
1074
|
|
POST
|
@-_- Pro 3.5 is soon to be released but we will also patch Pro 3.4. The next patch will be Pro 3.4.4. Jeff - arcpy.mp team
... View more
04-25-2025
06:57 AM
|
0
|
0
|
644
|
|
POST
|
@-_- This is indeed a regression we discovered and fixed during 3.5 and will patch 3.4 with the next available patch. What happened was new behavior was added into the the software called "alwaysUpdateClassLabels". When you simply use the arcpy.mp API to update a class label, it got overwritten due to this new behavior. aprx = arcpy.mp.ArcGISProject('CURRENT')
active_map = aprx.activeMap
lyr = active_map.listLayers()[0]
sym = lyr.symbology
sym.renderer.classBreaks[0].label = "Testing 123" #RESETS TO ORIG
lyr.symbology = sym But as you discovered, if the labels are modified via the CIM, it bypasses internal behavior and works. aprx = arcpy.mp.ArcGISProject('CURRENT')
active_map = aprx.activeMap
lyr = active_map.listLayers()[0]
lyr_cim = lyr.getDefinition('V3')
lyr_cim.renderer.breaks[0].label = "Testing 123" #This works
lyr.setDefinition(lyr_cim) This applies to all renderers and colorizers with class breaks. Our apologies for the breaking change. Jeff - arcpy.mp team
... View more
04-24-2025
07:54 AM
|
2
|
1
|
2878
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 06-05-2025 11:20 AM | |
| 3 | 06-05-2025 09:21 AM | |
| 1 | 05-14-2025 01:19 PM | |
| 2 | 04-24-2025 07:54 AM | |
| 1 | 03-15-2025 07:19 PM |
| Online Status |
Offline
|
| Date Last Visited |
2 weeks ago
|