4

Experiencing trouble with ArcGIS Pro 2.3.2 sym.renderer to assign symbology to a layer in a map project using only Python. I am automating map creation, and layer creation, symbolization. I am trying to assign symbology to a layer (polygons) using the GraduatedColorsRenderer. I update the renderer, classification method and assign it a field. Then I define the classBreakValues and the breakCount. I can only get one classification break even though I have defined 5 or more.

It appears that the sym.renderer.breakCount will not allow me to assign any value to it. Whenever I assign it to any integer it seems to not take it. When I print out the value of the sym.renderer.breakCount it is always set to 1 regardless of what I set it to. For the classification methods I have tried ManualInterval, EqualInterval, Quantile.

Here is my code:

for lyr in m.listLayers():
if lyr.name == "Binning Analysis":
    sym = lyr.symbology
    sym.updateRenderer('GraduatedColorsRenderer')
    sym.renderer.colorRamp = aprx.listColorRamps('Blues (Continuous)')[0]
    sym.renderer.classificationMethod = 'EqualInterval'
    classBreakValues = [5, 15, 35, 60, 1000]
    classBreakLabels = ["1 - 5", "6 - 15", "16 - 35", "36 - 60", "> 60"]
    sym.renderer.breakCount = len(classBreakValues)
    #sym.renderer.breakCount = 5
    count = 0
    for brk in sym.renderer.classBreaks:
        brk.upperBound = classBreakValues[count]
        brk.label = classBreakLabels[count]
        count += 1
    lyr.symbology = sym

I also put this code in the ArcGIS Pro Python window with a bunch of debug print statements to make sure all of my assignments were valid. Every thing seems valid. But the one thing that keeps happening in the Python window:

sym.renderer.breakCount = 5       #### Or any other number does not matter
print(sym.renderer.breakCount)
1                                 ### always outputs 1 no matter what I assign

What is wrong?

2 Answers 2

1

I have not been able to reproduce your result using ArcGIS Pro 2.4.2, and I do not have an earlier version to test.

The test I ran from IDLE was:

import arcpy
aprx = arcpy.mp.ArcGISProject(
    r"C:\Temp\Projects\TestProject\TestProject.aprx")
mapx = aprx.listMaps("Map")[0]
lyr = mapx.listLayers("ne_10m_populated_places")[0]

sym = lyr.symbology
sym.updateRenderer('GraduatedColorsRenderer')
sym.renderer.classificationMethod = 'EqualInterval'
sym.renderer.classificationField = "POP2020"
sym.renderer.breakCount = 5
print(sym.renderer.breakCount)
sym.renderer.breakCount = 10
print(sym.renderer.breakCount)

and the output, as expected, was:

Python 3.6.8 |Anaconda, Inc.| (default, Feb 21 2019, 18:30:04) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
>>> 
========================== RESTART: C:\Temp\test.py ==========================
5
10
>>>
0

I had this same issue in Pro 2.8.1. The solution for me was such that the feature class contained fewer features than the number of symbology classes I was trying to define (this feature class is derived from previous logic in the gp tool, so my efforts here aren't quite so silly as they seem).

Note that this behavior applies when manually attempting to apply more symbology classes than records in your feature class. In the case below, the "Classes" field in the Symbology form will not allow any input, as there is only one feature in the feature class:

image of ArcGIS Pro symbology menu, with the "Classes" field disabled

To handle this kind of a case, I needed to define the class break(s) based on each value in the layer. The additional function I wrote was this:

def handle_small_dataset(sym, values, colors):
    for i in range(len(values)):
        brk = sym.renderer.classBreaks[i]
        tbl_val = values[i]
        brk.lowerBound = math.floor(tbl_val / 25) * 25
        brk.upperBound = math.ceil(tbl_val / 25) * 25
        brk.label = "{} to {} % refined".format(brk.lowerBound, brk.upperBound)
        brk.symbol.size = 0
        val_class = math.floor(tbl_val / 25) - 1
        brk.symbol.color = colors[val_class]
    return sym

...where sym is the symbology object from the layer; values are the feature class's values in the field I want to symbolize; and colors is the list of RGB values of the desired colors.

The function iterates through the data values, defines the range of values for the class break that will include that value, defines the label for that class, then sets the color for that class. I'm sure there's a more elegant way to do it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.