Select to view content in your preferred language

Symbolizing Polygon and Point Outputs from Python Script Tool

335
5
Monday
AveryDurham1
Emerging Contributor

I have a python script tool that outputs points and polygons. I want to symbolize them based on a field but I'm having a hard time doing that in my code rather than manually. When I run ApplySymbologyFromLayer in the python window, the symbology applies just fine. However, when I try to do something similar at the end of my script tool, I get no errors but the symbology is unchanged. What am I missing to make this work?

Here is the code for adding the polygons. It is essentially the same for the points. I got some advice from ChatGPT while looking for a solution so I'm open to anything that needs to be remedied from that too.

    polygonLayerTemplate = r"J:\User\Coding\PolygonsTemplate.lyrx" 
    polygonLayerName = "Polygons"
    
    for lyr in activeMap.listLayers():
        if lyr.name == polygonLayerName:
            activeMap.removeLayer(lyr)  # remove old version to avoid duplicates
    polygonLayer = activeMap.addDataFromPath(polygonsFeatureClass)
    Layer = activeMap.listLayers(polygonLayerName)[0]
    arcpy.management.ApplySymbologyFromLayer(
        in_layer=Layer,
        in_symbology_layer=polygonLayerTemplate,
        symbology_fields="VALUE_FIELD Name Name",
        update_symbology="UPDATE"
    )

 

0 Kudos
5 Replies
DavidPike
MVP Notable Contributor

possibly BUG-000155515 for ArcGIS Pro
Solved: Cannot Apply Symbology From Layer Using Python Scr... - Esri Community - details setting the symbology as an output parameter instead.

I've also seen it set as 'layer.symbology' as an alternative.

0 Kudos
HaydenWelch
MVP Regular Contributor

I've had inconsistent behavior with ApplySymbology before as well. You can sometimes coax it to work by setting the environment or saving the active project. If all else fails, You can dig into CIM and apply the symbology as a CIM update. lyrx files are just JSON definitions of CIM objects, so you can load it in and apply it like any other CIM update.

from arcpy.cim.CIMDocument import CIMLayerDocument
from arcpy.cim.cimloader.jsontocim import GetJSONTypeOBJ

from arcpy.mp import ArcGISProject
from arcpy.management import ApplySymbologyFromLayer
from arcpy import EnvManager
from arcpy.mp import Map, Layer

import json
from pathlib import Path

def lyrx_to_cim(lyrx: str) -> CIMLayerDocument:
    _json = json.load(Path(lyrx).open('rt', encoding='utf-8'))    
    return GetJSONTypeOBJ(_json)

def get_layers(map: Map, name: str):
    return (l for l in map.listLayers() if l.name == name)

def main() -> None:
    data_path = r'<path>'
    lyr_path = r'J:\User\Coding\PolygonsTemplate.lyrx'
    lyr_cim = lyrx_to_cim(lyr_path)
    lyr_name = 'Polygons'
    prj = ArcGISProject('CURRENT')
    
    for lyr in get_layers(prj.activeMap, lyr_name):
        prj.activeMap.removeLayer(lyr)
    prj.activeMap.addDataFromPath(data_path)
    
    for lyr in get_layers(prj.activeMap, lyr_name):
        break
    else:
        print(f'[ERROR] Failed to find {lyr_name}')
        return
    
    # Using a workspace Environment (with the project location as the workspace)
    with EnvManager(workspace=prj.homeFolder):
        ApplySymbologyFromLayer(
            in_layer=lyr,
            in_symbology_layer=lyr_path,
            symbology_fields='VALUE_FIELD Name Name',
            update_symbology='UPDATE'
        )
        prj.save()
    
    # Set with CIM
    lyr.setDefinition(lyr_cim)
    
if __name__ == '__main__':
    main()

 

0 Kudos
TylerT
by
Frequent Contributor

One thing you might check is your symbology_fields argument.  The docs show this as a list of lists vice a string.  

Tyler

0 Kudos
HaydenWelch
MVP Regular Contributor

Docs are sometimes inconsistent on that. There's some pretty aggressive parameter conversion that goes on with the direct API functions.

 

E.g. Any function that has 2 literal flags can either take a flag or a Boolean (True/False == "INVERT"/"NOT-INVERT")

 

If you ever get the chance, check out the fixargs decorator that wraps every function and you'll see what I mean.

TylerT
by
Frequent Contributor

@HaydenWelch, Good to know.  Thank you.