UniqueValueRenderer not coloring polygons

776
9
Jump to solution
04-21-2023 08:19 AM
nsidaniel
New Contributor III

I'm trying to do what seems really simple via arcpy: color a layer's 4 classes! I cannot see where my code is wrong. I based it on esri: https://pro.arcgis.com/en/pro-app/latest/arcpy/mapping/uniquevaluerenderer-class.htm. Any help would be appreciated!

Maybe my issue is that I'm ignoring that the attribute table was generated via domains' drop-down lists? Maybe I need to bite the bullet and use CIM access.

# Color and setup features 2
import arcpy, os, sys
relpath = os.path.dirname(sys.argv[0])
p = arcpy.mp.ArcGISProject(os.path.join(relpath+"CURRENT"))
m = p.listMaps('Map')[0]
l = m.listLayers(TWP + "_RIGHTS")[0]
sym = l.symbology
        
sym.updateRenderer('UniqueValueRenderer')
sym.renderer.fields = ['RightsType']
for grp in sym.renderer.groups:
    for itm in grp.items:
        
        value = itm.values[0]
        if value == "Choose":
            itm.renderer.symbol.color = {"RGB": [0, 0, 0, 50]}      
            itm.renderer.symbol.outlineColor = {"RGB": [255, 255, 255, 100]}
            itm.renderer.symbol.outlineWidth = 0.75  
            itm.renderer.symbol.size = 1
            itm.renderer.label = str(value)
        
        if value == "Easement":
            itm.renderer.symbol.color = {"RGB": [0, 112, 255, 50]}      
            itm.renderer.symbol.outlineColor = {"RGB": [255, 255, 255, 100]}
            itm.renderer.symbol.outlineWidth = 0.75  
            itm.renderer.symbol.size = 1
            itm.renderer.symbol.label = str(value)
                                              
        if value == "Fee":
            itm.renderer.symbol.color = {"RGB": [56, 168, 0, 50]}
            itm.renderer.symbol.outlineColor = {"RGB": [255, 255, 255, 100]}
            itm.renderer.symbol.outlineWidth = 0.75
            itm.renderer.symbol.size = 1
            itm.renderer.symbol.label = str(value)
                                                   
        if value == "License":
            itm.renderer.symbol.color = {"RGB": [0, 0, 255, 50]}
            itm.renderer.symbol.outlineColor = {"RGB": [255, 255, 255, 100]}
            itm.renderer.symbol.outlineWidth = 0.75
            itm.renderer.symbol.size = 1
            itm.renderer.symbol.label = str(value)
                    
l.symbology = sym
p.saveACopy(os.path.join(relpath+"CURRENT"))     
        
print("Completed"+" "+time.strftime("%x" +" "+ "(%a)" +" "+ "at"+" "+"%I:%M"))
0 Kudos
1 Solution

Accepted Solutions
nsidaniel
New Contributor III

@Mahdi_Ch, after feeling it was over, the code correctly colors everything ... but doesn't actually write anything to the map! (I took your suggestions to clean things up, thank you!!)

Any ideas why it isn't actually writing to the map? I tried refreshing the map of course, but that didn't do anything. The attribute table definitely contains information.

import arcpy, sys
print(TWP)

aprx = arcpy.mp.ArcGISProject("CURRENT")
m = aprx.listMaps("Map")[0]
l = m.listLayers(TWP + "_RIGHTS")[0]
sym = l.symbology

sym.updateRenderer('UniqueValueRenderer')
sym.renderer.fields = ['RightsType']

for grp in sym.renderer.groups:
    for itm in grp.items:

        if itm.label == "Choose":
            label = itm.label
            itm.symbol.color = {"RGB": [0, 0, 0, 50]}      
            itm.symbol.outlineColor = {"RGB": [255, 255, 255, 100]}
            itm.symbol.outlineWidth = 0.75
            itm.label = str(label)

        if itm.label == "Easement":
            label = itm.label
            itm.symbol.color = {"RGB": [0, 112, 255, 50]}      
            itm.symbol.outlineColor = {"RGB": [255, 255, 255, 100]}
            itm.symbol.outlineWidth = 0.75  
            itm.label = str(label)

        if itm.label == "Fee":
            label = itm.label
            itm.symbol.color = {"RGB": [56, 168, 0, 50]}
            itm.symbol.outlineColor = {"RGB": [255, 255, 255, 100]}
            itm.symbol.outlineWidth = 0.75
            itm.label = str(label)

        if itm.label == "License":
            label = itm.label
            itm.symbol.color = {"RGB": [255, 0, 0, 50]}
            itm.symbol.outlineColor = {"RGB": [255, 255, 255, 100]}
            itm.symbol.outlineWidth = 0.75
            itm.label = str(label)
        print(label)
            
        l.symbology = sym
aprx.save() 
print("Completed"+" "+time.strftime("%x" +" "+ "(%a)" +" "+ "at"+" "+"%I:%M"))

 

View solution in original post

0 Kudos
9 Replies
Mahdi_Ch
New Contributor III

I guess it help better if you include the error.(or maybe no error just runs without applying?) But the first thing that I noticed is this line: 

 

p = arcpy.mp.ArcGISProject(os.path.join(relpath+"CURRENT"))

 

I believe you cannot combine the path and "CURRENT", if you are not using the current project, you can put the project name there though. sth like:  relpath+"\\projectname.aprx"

Although, it might work out of luck if relpath is empty.

0 Kudos
nsidaniel
New Contributor III

Thanks, @Mahdi_Ch: it runs without applying! And it is the current project. I'll add in the actual project and see how it does, but I imagine that won't change anything.

0 Kudos
Mahdi_Ch
New Contributor III

Yeah, if it runs without errors that shouldn't change anything! That means if you check the value for relpath it should be an empty string so you can simply delete that to be like ArcGISProject("CURRENT").

Something else that I noticed is TWP is not defined in your code here, I assume that shouldn't be the case in the actual code that you run. 

Have you tried putting some print statements for value to see if it is among those values you are checking against? ("Choose",  "Easement",...) maybe it is not what you think and never falls into any of those ifs? 

nsidaniel
New Contributor III

If I align print(value) with each "if" statement, it prints the below.

 

import arcpy, os, sys
p = arcpy.mp.ArcGISProject("CURRENT")
m = p.listMaps('Map')[0]
l = m.listLayers(TWP + "_RIGHTS")[0]
sym = l.symbology
        
sym.updateRenderer('UniqueValueRenderer')
sym.renderer.fields = ['RightsType']
for grp in sym.renderer.groups:
    for itm in grp.items:
       
        value = itm.values[0]
        if value == "Choose":
            itm.renderer.symbol.color = {"RGB": [0, 0, 0, 50]}      
            itm.renderer.symbol.outlineColor = {"RGB": [255, 255, 255, 100]}
            itm.renderer.symbol.outlineWidth = 0.75  
            itm.renderer.symbol.size = 1
            itm.renderer.label = str(value)
        print(value)
        
        if value == "Easement":
            itm.renderer.symbol.color = {"RGB": [0, 112, 255, 50]}      
            itm.renderer.symbol.outlineColor = {"RGB": [255, 255, 255, 100]}
            itm.renderer.symbol.outlineWidth = 0.75  
            itm.renderer.symbol.size = 1
            itm.renderer.symbol.label = str(value)
        print(value)
                                              
        if value == "Fee":
            itm.renderer.symbol.color = {"RGB": [56, 168, 0, 50]}
            itm.renderer.symbol.outlineColor = {"RGB": [255, 255, 255, 100]}
            itm.renderer.symbol.outlineWidth = 0.75
            itm.renderer.symbol.size = 1
            itm.renderer.symbol.label = str(value)
        print(value)
                                                   
        if value == "License":
            itm.renderer.symbol.color = {"RGB": [0, 0, 255, 50]}
            itm.renderer.symbol.outlineColor = {"RGB": [255, 255, 255, 100]}
            itm.renderer.symbol.outlineWidth = 0.75
            itm.renderer.symbol.size = 1
            itm.renderer.symbol.label = str(value)
        print(value)
                    
l.symbology = sym
p.saveACopy("CURRENT")      
print("Completed"+" "+time.strftime("%x" +" "+ "(%a)" +" "+ "at"+" "+"%I:%M"))

['0']
['0']
['0']
['0']
['1']
['1']
['1']
['1']
['2']
['2']
['2']
['2']
['3']
['3']
['3']
['3']
Completed 4/21/2023 (Fri) at 12:34

 

 

If I align print(value) with each itm.renderer.symbol statement it prints nothing. Leads me to believe that "value" stores nothing (value has no value)!

 

        if value == "License":
            itm.renderer.symbol.color = {"RGB": [0, 0, 255, 50]}
            itm.renderer.symbol.outlineColor = {"RGB": [255, 255, 255, 100]}
            itm.renderer.symbol.outlineWidth = 0.75
            itm.renderer.symbol.size = 1
            itm.renderer.symbol.label = str(value)
            print(value)

 

 

0 Kudos
Mahdi_Ch
New Contributor III

value is already a list of list, to get the actual value you should change the line to the following:

value = itm.values[0][0]
# or alternatively, you can get it from label:
value = itm.label

 The issue is you are looking for the content of "RightsType" field/column. And apparently that is not what you are looking for (you want "Choose", "Easement",... but the actual values there are "0", "1", "2",...

Looking at the first if statement, since the value ['0'] is not equal to "Choose" it never enters the if statement to do the rest, and jumps to the next one, and the same logic applies for other if statements and basically nothing gets changed (formatting-wise).

Another general tip is since you set the value at line 12 and it never changes, you don't need to repeat the print(value) after each if statement. 

nsidaniel
New Contributor III

I solved it by adding if itm.label == . Thanks for your help @Mahdi_Ch! You guided me in the right direction.

 

import arcpy, os, sys

p = arcpy.mp.ArcGISProject("CURRENT")
m = p.listMaps('Map')[0]
l = m.listLayers(TWP + "_RIGHTS")[0]
sym = l.symbology
        
sym.updateRenderer('UniqueValueRenderer')
sym.renderer.fields = ['RightsType']
for grp in sym.renderer.groups:
    for itm in grp.items:

        if itm.label == "Choose":
            label = "Choose"
            itm.symbol.color = {"RGB": [0, 0, 0, 50]}      
            itm.symbol.outlineColor = {"RGB": [255, 255, 255, 100]}
            itm.symbol.outlineWidth = 0.75
            itm.label = str(label)
            print(label)

        if itm.label == "Easement":
            label = "Easement"
            itm.values[0][0]
            itm.symbol.color = {"RGB": [0, 112, 255, 50]}      
            itm.symbol.outlineColor = {"RGB": [255, 255, 255, 100]}
            itm.symbol.outlineWidth = 0.75  
            itm.label = str(label)
            print(label)
                                              
        if itm.label == "Fee":
            label = "Fee"
            itm.symbol.color = {"RGB": [56, 168, 0, 50]}
            itm.symbol.outlineColor = {"RGB": [255, 255, 255, 100]}
            itm.symbol.outlineWidth = 0.75
            itm.label = str(label)
            print(label)
                                                   
        if itm.label == "License":
            label = "License"
            itm.symbol.color = {"RGB": [255, 0, 0, 50]}
            itm.symbol.outlineColor = {"RGB": [255, 255, 255, 100]}
            itm.symbol.outlineWidth = 0.75
            itm.label = str(label)
            print(label)

        l.symbology = sym
aprx.save()     
print("Completed"+" "+time.strftime("%x" +" "+ "(%a)" +" "+ "at"+" "+"%I:%M"))

 

nsidaniel
New Contributor III

@Mahdi_Ch, after feeling it was over, the code correctly colors everything ... but doesn't actually write anything to the map! (I took your suggestions to clean things up, thank you!!)

Any ideas why it isn't actually writing to the map? I tried refreshing the map of course, but that didn't do anything. The attribute table definitely contains information.

import arcpy, sys
print(TWP)

aprx = arcpy.mp.ArcGISProject("CURRENT")
m = aprx.listMaps("Map")[0]
l = m.listLayers(TWP + "_RIGHTS")[0]
sym = l.symbology

sym.updateRenderer('UniqueValueRenderer')
sym.renderer.fields = ['RightsType']

for grp in sym.renderer.groups:
    for itm in grp.items:

        if itm.label == "Choose":
            label = itm.label
            itm.symbol.color = {"RGB": [0, 0, 0, 50]}      
            itm.symbol.outlineColor = {"RGB": [255, 255, 255, 100]}
            itm.symbol.outlineWidth = 0.75
            itm.label = str(label)

        if itm.label == "Easement":
            label = itm.label
            itm.symbol.color = {"RGB": [0, 112, 255, 50]}      
            itm.symbol.outlineColor = {"RGB": [255, 255, 255, 100]}
            itm.symbol.outlineWidth = 0.75  
            itm.label = str(label)

        if itm.label == "Fee":
            label = itm.label
            itm.symbol.color = {"RGB": [56, 168, 0, 50]}
            itm.symbol.outlineColor = {"RGB": [255, 255, 255, 100]}
            itm.symbol.outlineWidth = 0.75
            itm.label = str(label)

        if itm.label == "License":
            label = itm.label
            itm.symbol.color = {"RGB": [255, 0, 0, 50]}
            itm.symbol.outlineColor = {"RGB": [255, 255, 255, 100]}
            itm.symbol.outlineWidth = 0.75
            itm.label = str(label)
        print(label)
            
        l.symbology = sym
aprx.save() 
print("Completed"+" "+time.strftime("%x" +" "+ "(%a)" +" "+ "at"+" "+"%I:%M"))

 

0 Kudos
nsidaniel
New Contributor III

The TWP + "_RIGHTS" layer use domains, I'm thinking now that's the source of the problem

0 Kudos
nsidaniel
New Contributor III

Huh. It appears that the actual information is stuck in "all other values".

nsidaniel_0-1682540693601.png

 

0 Kudos