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.

6
  • 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, Commented Apr 10, 2017 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. Commented Apr 10, 2017 at 19:31
  • 2
    It sounds like we need some more information like MaryBeth said above. A screenshot would help. Commented Apr 10, 2017 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. Commented Apr 11, 2017 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. Commented Apr 11, 2017 at 2:27

1 Answer 1

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()
5
  • question regarding a code function in the top script. "reverse = True" is this arranging the classes from greatest to least? Commented Apr 11, 2017 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. Commented Apr 11, 2017 at 14:39
  • so it is safe to say that by default its ascending order? Commented Apr 12, 2017 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. Commented Apr 12, 2017 at 12:32
  • @cpbride, have you managed to execute the Python code? Has it solved your problem? Commented Apr 12, 2017 at 13:21

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.