Hi everyone,
I’m working on a project where I need to automate map production in ArcGIS Pro using ArcPy. One of the layers in my layout is the USA Cropland dataset, which contains nearly 150 cropland classes. Including all of these classes in the legend makes the map extremely cluttered.
What I would like to do is display only the top 10 classes for each state, based on pixel count, and group the remaining classes into an “Other Classes” category.
Is there a way to achieve this dynamically using ArcPy—either by modifying the legend, the symbology, or by generating a temporary raster/layer for each state?
Any guidance or examples would be greatly appreciated.
Thank you!
This is not the most elegant answer, but maybe create a layout template for each state and generate the legend at design time and then break it up (ungroup) and modify the legend to meet your needs. This would be a good amount of upfront work, but I don't think the data you are working with changes so it should be applicable for a long time which is your return on investment.
The workflow would need to know which state to want a print-out for and based on that is would select the appropriate print template.
I want to create a map for every state of the US, so making a template for each state doesn't seem to be a good idea. I already have the pixel count of each class for each state as a table. I want this information in my Legend and want to use the existing colour code for each crop class which Cropland Data Layer uses.
Is there any way I can use that in my legend?
I agree with @MikeVolz , one thing you could also do is, save the land use as a .lyr file, then apply it each map with arcpy.management.ApplySymbologyFromLayer. I've never tried with an image file, but that might work.
Hi @gauravparajuli9,
If you are changing symbology to only show the top 10, all other values will be the same color. If that is ok, you can use the Python CIM with ArcPy. Create the symbology for all cropland classes and add the option to Include all other values. Save as a layer file.
While I have not fully tried the following, it is a guide for the workflow (that may work first time around 😅)
## access the APRX. You can set to be the APRX path
aprx = arcpy.mp.ArcGISProject("CURRENT")
## get the layout
lyt = aprx.listMaps("LAYOUT_NAME")[0]
m = lyt.listEelements("MAPFRAME_ELEMENT", "MF_NAME")[0].map
rst_lyr = m.listLayers("RASTER_LAYER_NAME")[0]
## apply the symbology
arcpy.management.ApplySymbologyFromLayer(rst_lyr, "PATH_TO_LYRX")
## get top 10
# Raster attribute table already has a count
count_dict = {row[0] : row[1] for row in arcpy.da.SearchCursor(rst_lyr, ["YOUR_CODE_FIELD_HERE", "Count"])}
# top 10 codes
top_10 = [
code for code, count in sorted(
count_dict.items(),
key=lambda x: x[1],
reverse=True
)[:10]
]
## get CIM definition
cim = rst_lyr.getDefinition('V3')
## remove any codes that are not it top 10 - they go into other
cim.colorizer.groups[0].classes = [item for item in cim.colorizer.groups[0].classes if item.values[0] in top_10]
## update the CIM def for the layer
rst_lyr.setDefinition(cim)
## EXPORT ##