Programmatically Set Colors for Unique Values Symbology?

7213
5
08-19-2013 11:31 AM
PatrickLivingood
New Contributor
I have Python code that iterates through about 100 value fields and makes a single PDF composed of maps from each display.  I am using Unique Values Symbology, and I would like to figure out a way to programmatically control the color that is displayed with each value.  That is, value A should be red on all the maps, Value B blue, etc.  Is there a way to do this with arcpy?  Or, if not, what is the quickest way to accomplish this?

The existing code I cobbled together using examples on this forum, and so I thought I would pay forward by including the existing code for

#This code reads in a list of Species Names from a Table
#then interates through those and for each one sets the
#symbology on the map to a corresponding field and exports
#each page as a part of a single PDF


import arcpy,os

def MakeMap(SpeciesName):
    #Takes a Species Name and exports a PDF Map
    #The field name is Based on Species Name

    print SpeciesName
    FieldName="SpeciesData$." + SpeciesName + "__Source"
    FieldName=FieldName.replace (" ","_")

    #Set title on Map
    for elm in arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "Title"):
        elm.text = SpeciesName

    #Set Unique Values Field to FieldName
    if lyr.symbologyType == "UNIQUE_VALUES":
      lyr.symbology.valueField = FieldName
      lyr.symbology.addAllValues()

      #Remove Null Value fron display
      sourceList=lyr.symbology.classValues
      sourceList.remove("<Null>")
      lyr.symbology.classValues=sourceList
      lyr.symbology.showotherValues = False

    arcpy.RefreshActiveView()
    arcpy.RefreshTOC()

    #Position Legend
    legend = arcpy.mapping.ListLayoutElements(mxd, "LEGEND_ELEMENT", "Legend")[0]
    legend.elementPositionY=.15

    #Export to PDF
    arcpy.mapping.ExportToPDF(mxd, r"C:\temp.pdf")
    pdfDoc.appendPages(r"C:\temp.pdf")
    return


sourceList = []
speciesList = []
mxd = arcpy.mapping.MapDocument("current")
lyr = arcpy.mapping.ListLayers(mxd, "DistrictMap")[0]

#Fill Species List from Table
fc = "C:\Species List.xlsx\Species_List$"
rows = arcpy.SearchCursor(fc)
for row in rows:
    speciesList.append(row.Species)

#Set PDF file name and remove if it already exists
pdfPath = r"C:\FullMapsPDF.pdf"
if os.path.exists(pdfPath):
    os.remove(pdfPath)
#Create the PDF file
pdfDoc = arcpy.mapping.PDFDocumentCreate(pdfPath)

#Iterate through Species
for MySpecies in speciesList:
    MakeMap(MySpecies)

#Commit changes and delete variable reference
pdfDoc.saveAndClose()
del pdfDoc
del mxd
Tags (2)
0 Kudos
5 Replies
RhettZufelt
MVP Frequent Contributor
Well, if value A and B are the same in all the maps, the easiest way would be to open ArcMap, load your feature class and symbolize as desired.  then, right click on the FC and save as layer file.

Then, you can use UpdateLayer in python to update the symbology using the layer file you created http://resources.arcgis.com/en/help/main/10.1/index.html#/UpdateLayer/00s30000003p000000/ .

If the values for A and B can differ, you can set up and create the layer file in python http://resources.arcgis.com/en/help/main/10.1/index.html#/Layer/00s300000008000000/ , then use that one to update the layer(s).

R_
0 Kudos
PatrickLivingood
New Contributor
Well, if value A and B are the same in all the maps, the easiest way would be to open ArcMap, load your feature class and symbolize as desired.  then, right click on the FC and save as layer file.

Then, you can use UpdateLayer in python to update the symbology using the layer file you created http://resources.arcgis.com/en/help/main/10.1/index.html#/UpdateLayer/00s30000003p000000/ .

If the values for A and B can differ, you can set up and create the layer file in python http://resources.arcgis.com/en/help/main/10.1/index.html#/Layer/00s300000008000000/ , then use that one to update the layer(s).

R_


Thank you so much for helping, but I am not sure about your answer.  Let me explain my problem a little more clearly.  My table is a series of counties.  For each county there are about 100 fields that list source data for each of 100 species.  If no value exists, then the species has not been noted in that county.  If the species has been recorded in that county then there is a an academic source such as Adams 1900 or Bruce 1985 or Cohn 1990 listed that is the source of the information about its presence.

The script I posted above iterates through each of the species and shows a unique color map for each so that the presence/absence and the academic source for the information can be understood.  What I would like to ensure is that Adams 1900 is always red in all the maps, Bruce 1985 is always blue, etc.

There are about 14 sources and they show up on each of the species maps in varying combinations.  One map might only have Adams 1900, another might only have Bruce 1985, yet another might have 10 different sources.  I would estimate about 30 permutations of sources present exist across my 100 maps.

In the first example you provide above, that changes the symbology including the DisplayField, which is not really what I want.  In the second, that shows some of the Layer properties exposed in arcpy, but I am not sure how to access colors for a Unique_Value map.

Help is definitely appreciated!
0 Kudos
RhettZufelt
MVP Frequent Contributor
Well, that definatly gets more complicated, however, if you are using 10.1, here is one way.

Open your arcmap document that has the most permeatations.
create the symbology you want for the values (if it doesn't exist in that layer/map, you can add value to the list, even if it isn't displayed)
  Adams 1900 - red
  Bruce 1985  - blue
  etc...

now, save that as a layer file.  in your map document, legend properties, check the box that says "Only show classes that are visible in the current map extent" and save the mxd.

Now, with python, after you have your data genereated, us the updateSymbology to apply that layer file to the FC.  With the "Only show" box checked, you will only see the values/symbology for feature that show in the current layout extent, so, if a particular permeatation doesn't exist in the map, it won't display it on the legend.

Of course, now that I think about it some, ESRI has not given python access to the "only show " legend box, so you would have to manually set that on your layer in all your mxd's.
  Might be able to utilize a template to set this on all mxd's, would have to look into that a little.

I see we can change class values, labels, etc., but I don't see any way to assign a color to a feature using python, other than with a .lyr file.
If we could, there might be a way to iterate through all of them and append the classes to a list, then get the unique set, create a dictionary from that and apply it to the layer(s) you want.  however, not sure how you would control the colors

anyone know if we have access to the "colors" used for unique symbology?

In the first example you provide above, that changes the symbology including the DisplayField, which is not really what I want. In the second, that shows some of the Layer properties exposed in arcpy, but I am not sure how to access colors for a Unique_Value map.



symbology_only - A Boolean that determines whether or not to update only the layer's symbology, or all other properties as well. If set to True, only the layer's symbology will be updated.

R_
0 Kudos
AmyKlug
Occasional Contributor III
anyone know if we have access to the "colors" used for unique symbology?



http://ideas.arcgis.com/ideaView?id=087E00000004REYIA2


At 10.1 we added minScale and maxScale properties on the Layer Class so you can get and set the scale range of a layer. We also added a symbologyType property to ask the layer what kind of symbology it has defined and the symbology propety to allow you to access and modify some properties of the symbology.
0 Kudos
PatrickLivingood
New Contributor
It sounds like arcpy does not currently support the ability to set the Unique Value colors like I need to for this application.  I have experimented with the updateSymbology tool and I cannot get the effect I need.

ArcGIS currently supports a lot of different scripting technologies.  Which one would be the recommended one to do this task: iterate through about 100 different variables and for each one produce a unique values map, set its colors correctly, and export all of the maps to a PDF?
0 Kudos