|
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
|
349
|
|
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
|
670
|
|
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
|
772
|
|
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
|
562
|
|
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
|
430
|
|
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
|
1706
|
|
IDEA
|
We understand that this idea was submitted many years ago against ArcMap, but we would like to update the community with how ArcGIS Pro's arcpy.mp module addresses the requests. Here are solutions to the original 3 bullets provided. All of these items were addressed as far back as ArcGIS Pro 2x. 1. Changing fill (solid, patterned) stroke (solid, dashed etc), colour (rgb and cmyk input values), size, font properties of single symbol - The Symbol class addresses nearly all of this: https://pro.arcgis.com/en/pro-app/latest/arcpy/mapping/symbol-class.htm - The TextElement class has members to deal with font and size: https://pro.arcgis.com/en/pro-app/latest/arcpy/mapping/textelement-class.htm - Modifying symbol additional properties on label classes would require CIM access. https://pro.arcgis.com/en/pro-app/latest/arcpy/mapping/python-cim-access.htm 2. Changing unique values, many fields symbology by selecting the field inputs, and symbology properties for each. Also include colour ramp symbology. - The UniqueValueRenderer class does all this: https://pro.arcgis.com/en/pro-app/latest/arcpy/mapping/uniquevaluerenderer-class.htm - It even supports multiple fields AND colorramps (along with other renderers/colorizers) - The “symbology properties for each” part can be done via the symbol class, or the CIM, or possibly #3 below. 3. MOST IMPORTANT!! Match symbols to a style!!!! Enable Value Field to be defined as well as .sty file location. - This was provided as part of core arcpy: https://pro.arcgis.com/en/pro-app/latest/tool-reference/data-management/match-layer-symbology-to-a-style.htm We hope that sharing these details helps users implement layer symbology modifications with arcpy.mp. If you find that there is functionality that could be added that would facilitate your current workflows in ArcGIS Pro, please submit a new idea. Jeff - arcpy.mp team
... View more
04-14-2025
01:23 PM
|
0
|
0
|
804
|
|
IDEA
|
Thanks @matt_g_g . If you write your script to work out of process along with a reference to a "blank.aprx", for example, it all would happen in memory and the application would not even be opened. To work with a mapx or a pagx file, you need the application (internal logic) to read the files in order for them to be modified. Even if you wanted to use Python CIM access to modify the JSON structure, you still need the application. Those X files are text files but I would never recommend modifying those in a text editor. If you have specific issues with import/export x-files, I'd like to know the limitations. Jeff - arcpy.mp and Layout SDK teams
... View more
03-17-2025
10:27 AM
|
0
|
0
|
880
|
|
POST
|
@DougBrowning I've taken a look at this and I'm also bringing this to the attention of the raster team. A few things. 1) With Python, I'm able to standardize symbology across multiple rasters BUT only if I set the lowerBound of the raster. This property was made available on GraduatedColorsRenderer, GraduatedSymbolsRenderer and RasterClassifyColorizer at Pro 3.4. #Standardize multiple RasterClassifyColorizer elevation datasets p = arcpy.mp.ArcGISProject('current') m = p.listMaps('Yosemite Elevation')[0] for l in m.listLayers('*dem'): if l.isRasterLayer: lBound = 0 uBound = 300 sym = l.symbology sym.colorizer.colorRamp = p.listColorRamps('Elevation #1')[0] sym.colorizer.breakCount = 10 #final range: 0-3000 sym.colorizer.lowerBound = 0 for brk in sym.colorizer.classBreaks: brk.upperBound = uBound brk.label = f"{lBound} - {uBound} meters" lBound += 300 uBound += 300 l.symbology = sym 2) It appears I can't do this in the UI. The UI does not let me create ranges below the minimum value. It lets me create ranges for upper values that don't exist with no issue. If I try to set the lower bound via the Histogram tab but changing it to Zero has no effect on the colorizer (Unlike the GraduatedColors/symbols renderers). Even if I successfully set symbology via arcpy.mp like above, when I view the symbology pane, I get a warning. 3) There is a bug you may run into concerning labels. During Pro 3.4 development, auto apply labels behavior was added to the UI behavior and it causes arcpy.mp class label modifications to get reset. We have a fix for this at Pro 3.5 and hope to port it to a patch for 3.4. The bug is BUG-000174482. I hope this helps, Jeff - arcpy.mp and Layout (SDK) teams
... View more
03-15-2025
07:19 PM
|
1
|
0
|
1066
|
|
IDEA
|
Hi @BrettFrahm, Look at sample script #2 (at the bottom) in https://pro.arcgis.com/en/pro-app/latest/arcpy/mapping/mapseries-class.htm You just need to change the PNG to one of your formats. Let me know if this helps. Jeff
... View more
02-04-2025
09:11 AM
|
0
|
0
|
630
|
|
POST
|
@jeremywiles1981 is this a different issue? I.e., are selected features not being exported or are you talking about something else. Can you reproduce in the UI and/or SDK? Jeff - Layout (SDK) and arcpy.mp teams
... View more
01-28-2025
11:40 AM
|
0
|
1
|
695
|
|
POST
|
Hello, I can't identify the issue from the picture that is attached. What is "repeating itself"? Jeff - arcpy.mp team
... View more
01-24-2025
09:09 AM
|
0
|
1
|
781
|
|
POST
|
Thanks for reporting this. We recently added a new, non-map series option on the export pane called "Show selection symbology". This should work with mapviews, non-mapseries layouts and mapseries layouts. As a result we plan to deprecate the option on the map series. BUT the following should work and it does not. We are investigating it and hope to address it immediately. async protected override void OnClick()
{
var layoutItem = Project.Current.GetItems<LayoutProjectItem>().FirstOrDefault(item => item.Name.Equals("Layout_MS"));
await QueuedTask.Run(() =>
{
Layout layout = layoutItem.GetLayout();
layout.Export(
new PDFFormat
{
OutputFileName = @"c:\temp\selected_features_MS.pdf",
DoShowSelectionSymbology = true
}
);
}); Jeff - Layout (SDK) and arcpy.mp teams
... View more
01-24-2025
08:37 AM
|
0
|
1
|
724
|
|
POST
|
@jlgprime I can NOT reproduce this issue on released versions of the software. Could you please provide a coordinate system and perhaps a couple of screen shots so I can try to reproduce your issue. Jeff - arcpy.mp team Preview
... View more
01-15-2025
01:26 PM
|
0
|
1
|
725
|
|
IDEA
|
@asmith_tssw - I need a reproducible case and it is so difficult to know what your script is doing and how it is interacting within the application. For example, are you running script tool within the application or are you running a stand-alone script outside of the application? Even if you could provide a bulleted list of the order of operations, that could be helpful.
Jeff
... View more
11-15-2024
01:45 PM
|
0
|
0
|
1767
|
| 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 |
a week ago
|