2

I have a hexagon grid with the dominant species of tree listed in each cell. I want to symbolize the tree type but put them in order of percentage of dominance in the legend. So a table like this:

Maple - 85%
Oak - 100%
Pine - 75%

would end up looking like this in the legend:

Oak - 100%
Maple - 85%
Pine - 75%

despite being out of alphabetical order.

  • 2
    A few questions for clarification...Are you using ArcPy or anything to create the legend? It also may be helpful to see a screenshot of what you are trying to accomplish, – MaryBeth Apr 10 '17 at 19:04
  • no, it's just ArcGIS. The workaround is to manually rename the categories in the symbology window but I there's gotta be another way to do this. Every time I change the color ramp I'm gonna lose my classification titles. – cpbride Apr 10 '17 at 19:31
  • 2
    It sounds like we need some more information like MaryBeth said above. A screenshot would help. – SteveC Apr 10 '17 at 20:48
  • You said, "table like this:", but your example is a line, not a table. You need to clarify what you mean. Explain where these values are coming from, how they're stored in the GDB and how the legend is constructed. – Son of a Beach Apr 11 '17 at 0:07
  • 2
    you referred to your data as a hexagon "grid" - assuming this is vector data, you can just reorder the categories in the symbology tab, which will result in the reorder in the legend. – Adam Apr 11 '17 at 2:27
2

You wouldn't be able to do this using ArcMap built-in tools. However, this can be easily done using arcpy and Python scripting techniques. We are essentially interested in updating the layer labels for the symbology (unique values type).

  1. Create a layer in the map document.

This is how attribute table would look like:

enter image description here

  1. Choose Symbology > Unique values. Your tree species will be sorted alphabetically.

enter image description here

  1. Run this snippet code in your Python window in ArcMap.

Code when both tree type and percentage are stored in multiple fields:

import arcpy.mapping as mp

mxd = mp.MapDocument('current')
lyr = mp.ListLayers(mxd, 'TreeTypes')[0]
symb = lyr.symbology

symb.classLabels
print(symb.classLabels)
#[u'Apple', u'Birch', u'Cedar', u'Maple', u'Oak', u'Pear', u'Poplar', u'Willow']
lookup = {f[0]: int(f[1]) for f in arcpy.da.SearchCursor(lyr,["TreeType","Percentage"])}
print(lookup)
#{u'Apple': 20, u'Willow': 75, u'Pear': 30, u'Oak': 100, u'Poplar': 40, u'Birch': 50, u'Cedar': 10, u'Maple': 80}

symb.classLabels = sorted(symb.classLabels, key=lookup.get, reverse=True)
symb.classLabels = [i + ' - ' + str(lookup[i]) + '%' for i in symb.classLabels]
arcpy.RefreshTOC()
  1. Your layer symbology will be updated. You can create a new legend now which will use the labels you want. Should you already have a legend created, you can run arcpy.RefreshActiveView() in Python window to refresh it.

enter image description here

Note: the code above assumes that you have your percentage values stored in a field named Percentage. Should you keep both the tree type and percentage in a single field (not the best alternative in terms of data management), then you should run this code instead:

Code when both tree type and percentage are stored in a single field:

import arcpy.mapping as mp

mxd = mp.MapDocument('current')
lyr = mp.ListLayers(mxd, 'TreeTypes')[0]
symb = lyr.symbology

symb.classLabels
print(symb.classLabels)
#[u'Apple - 20%', u'Birch - 50%', u'Cedar - 10%', u'Maple - 80%', u'Oak - 100%', u'Pear - 30%', u'Poplar - 40%', u'Willow - 75%']

symb.classLabels = sorted(symb.classLabels, key=lambda x: int(x.split(' - ')[1].split('%')[0]), reverse=True)
arcpy.RefreshTOC()
  • question regarding a code function in the top script. "reverse = True" is this arranging the classes from greatest to least? – NULL.Dude Apr 11 '17 at 13:18
  • 1
    @Joe, this is correct. The ones with the largest percentage value will end up in the top of the list. You can think of reverse=True as SQL DESC that is in descending order. – Alex Tereshenkov Apr 11 '17 at 14:39
  • so it is safe to say that by default its ascending order? – NULL.Dude Apr 12 '17 at 12:23
  • 1
    @Joe this is correct. By default the integers will be sorted in ascending order, so you can leave out the reverse parameter. I've used the reverse order because the questioner was interested in descending order. – Alex Tereshenkov Apr 12 '17 at 12:32
  • @cpbride, have you managed to execute the Python code? Has it solved your problem? – Alex Tereshenkov Apr 12 '17 at 13:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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