Hi there, I was doing some ArcPy coding (ArcGIS Pro 3.4.2). I was applying GraduatedColorRenderer + Manual + 5 classes + customized colors and labels to a feature layer. Everything of the result was good except the labels, not what I expected from my code (below).
'''
I want to apply the GraudatedColorRenderer to my feature layer using the manual classification method.
I also want to use my own colors and labels for each class.
However, the result show different labels and I cannot figure what the problem is.
'''
import arcpy
arcpy.env.overwriteOutput = True
# Obtain the current project and map
project = arcpy.mp.ArcGISProject("CURRENT")
map = project.listMaps("Map")[0]
# Obtain the feature layer
layer = map.listLayers("Ottawa_Census")[0]
# Use GraduatedColorsRenderer
sym = layer.symbology
sym.updateRenderer('GraduatedColorsRenderer')
print('Renderer has been updated to GraudatedColorRenderer')
# Set the classification field, method, and the number of classes
sym.renderer.classificationField = "POP_2016"
sym.renderer.classificationMethod = "Manual"
sym.renderer.breakCount = 5
print('Classification field, method, and breakcount have been set.')
# Customized settings
manual_breaks = [500, 1000, 2000, 3000, 20000]
manual_colors = [
{'RGB': [255, 190, 190, 100]},
{'RGB': [255, 127, 127, 100]},
{'RGB': [255, 0, 0, 100]},
{'RGB': [230, 0, 0, 100]},
{'RGB': [168, 0, 0, 100]}
]
manual_labels = [
"0.0-500",
"500-1000",
"1000-2000",
"2000-3000",
"3000-20000"
]
print('Breaks, colors, and labels have been set.')
# Apply the above settings
for i, brk in enumerate(sym.renderer.classBreaks):
brk.label = manual_labels[i]
brk.symbol.color = manual_colors[i]
brk.upperBound = manual_breaks[i]
layer.symbology = sym
project.save()
pdf = arcpy.mp.CreateExportFormat('PDF', r'D:\Learning ArcPy\challenge\layout_export.pdf')
project.listLayouts()[0].export(pdf)
print("Task done!")
Solved! Go to Solution.
This works for me, the code applies two-step process that first applies default symbology before modifying breaks and applies symbology after setting breakCount.
# Step 1: First apply default graduated colors
sym = lyr.symbology
sym.updateRenderer('GraduatedColorsRenderer')
sym.renderer.classificationField = "Acres"
sym.renderer.breakCount = 5
lyr.symbology = sym # This initializes the breaks
# Step 2: Now modify the breaks
sym = lyr.symbology # Get fresh symbology
# Configure breaks
breaks = [
(100, "0-100", [255, 190, 190, 100]),
(200, "100-200", [255, 127, 127, 100]),
(300, "200-300", [255, 0, 0, 100]),
(400, "300-400", [230, 0, 0, 100]),
(500, "400-500", [168, 0, 0, 100])
]
# Apply breaks
for i in range(5):
sym.renderer.classBreaks[i].upperBound = breaks[i][0]
sym.renderer.classBreaks[i].label = breaks[i][1]
sym.renderer.classBreaks[i].symbol.color = {'RGB': breaks[i][2]}
sym.renderer.classBreaks[i].lowerBound = 0 if i == 0 else breaks[i-1][0]
# Step 3: Final apply
lyr.symbology = sym
print("DONE: Graduated colors applied with 5 manual breaks")
This works for me, the code applies two-step process that first applies default symbology before modifying breaks and applies symbology after setting breakCount.
# Step 1: First apply default graduated colors
sym = lyr.symbology
sym.updateRenderer('GraduatedColorsRenderer')
sym.renderer.classificationField = "Acres"
sym.renderer.breakCount = 5
lyr.symbology = sym # This initializes the breaks
# Step 2: Now modify the breaks
sym = lyr.symbology # Get fresh symbology
# Configure breaks
breaks = [
(100, "0-100", [255, 190, 190, 100]),
(200, "100-200", [255, 127, 127, 100]),
(300, "200-300", [255, 0, 0, 100]),
(400, "300-400", [230, 0, 0, 100]),
(500, "400-500", [168, 0, 0, 100])
]
# Apply breaks
for i in range(5):
sym.renderer.classBreaks[i].upperBound = breaks[i][0]
sym.renderer.classBreaks[i].label = breaks[i][1]
sym.renderer.classBreaks[i].symbol.color = {'RGB': breaks[i][2]}
sym.renderer.classBreaks[i].lowerBound = 0 if i == 0 else breaks[i-1][0]
# Step 3: Final apply
lyr.symbology = sym
print("DONE: Graduated colors applied with 5 manual breaks")
Thank you @TonyAlmeida so much. I have tested your code with my dataset. It worked perfectly. I don't consider using the lowerBound property, as it isn't explicitly listed on the ClassBreak class documentation page. I think you idea of first applying the GraduatedColorRenderer and then changing it is the key to the solution.
import arcpy
arcpy.env.overwriteOutput = True
project = arcpy.mp.ArcGISProject("CURRENT")
map = project.listMaps("Map")[0]
lyr = map.listLayers("Ottawa_Census")[0]
# Step 1: First apply default graduated colors
sym = lyr.symbology
sym.updateRenderer('GraduatedColorsRenderer')
sym.renderer.classificationField = "POP_2016"
sym.renderer.breakCount = 5
lyr.symbology = sym # This initializes the breaks
# Step 2: Now modify the breaks
sym = lyr.symbology # Get fresh symbology
#print(sym.renderer.breakCount)
# Configure breaks
breaks = [ # I prefer lists to sets but both work.
[500, "0-500", [255, 190, 190, 100]],
[1000, "501-1000", [255, 127, 127, 100]],
[2000, "1001-2000", [255, 0, 0, 100]],
[3000, "2001-3000", [230, 0, 0, 100]],
[2000, "3001-20000", [168, 0, 0, 100]]
]
# Apply breaks
for i in range(5):
sym.renderer.classBreaks[i].upperBound = breaks[i][0]
sym.renderer.classBreaks[i].label = breaks[i][1]
sym.renderer.classBreaks[i].symbol.color = {'RGB': breaks[i][2]}
# Step 3: Final apply
lyr.symbology = sym
print("DONE: Graduated colors applied with 5 manual breaks")
project.save()
pdf = arcpy.mp.CreateExportFormat('PDF', r'D:\Learning ArcPy\challenge\layout_export.pdf')
project.listLayouts()[0].export(pdf)
print("Task done!")