4

I have a shapefile of a country with 50 fields. Each field contains values (-3 to 3) for a particular month. I would like to create a for loop that iterates through the fields, updates the map, uses a common symbology and exports to a PNG file.

The symbology I would like to use is one color per number. -3 = dark orange, -2 = light orange, -1 = light yellow, 0 = grey, 1 = light green, 2 = dark green, 3 = very dark green. I've assigned these colors to the layer in the .mxd, and created a .lyr.

So far, I have this:

import arcpy
mxd = arcpy.mapping.MapDocument(r'path/to/mxd')
shp = r'path/to/country_shapefile'
outdir = r'path/to/out/directory'
symbology = r'path/to/symbology.lyr'

df = arcpy.mapping.ListDataFrames(mxd)[0]
fields = [field.name for field in arcpy.ListFields(shp)]
fields = fields(17:len(fields) # I only need to display the data in fields 17 onwards
layer = arcpy.mapping.ListLayers(mxd, 'country')[0]
symbol = layer.symbology

for field in fields:
    symbol.valueField = field
    symbol.classValues = [-3,-2,-1,0,1,2,3] # The range of values in the symbology
    arcpy.ApplySymbologyFromLayer_management(layer, symbology)
    arcpy.RefreshActiveView()
    arcpy.RefreshTOC()
    arcpy.mapping.ExportToPNG(mxd, outdir+'\\'+field+".png")

---

When I try this, I get a map displaying the values in every field, but not with the correct symbology.

  • Welcome to GIS SE! As a new user please take the tour to learn about our focused Q&A format. – Midavalo Nov 24 '17 at 3:20
  • Hi Midavalo, I've edited my question to describe the symbology in a bit more detail. Let me know if this is still unclear? – K2609 Nov 24 '17 at 3:24
  • Apply symbology from layer resources.arcgis.com/en/help/main/10.2/index.html#//… takes two arguments, neither of which is field and symbol, the first is the layer to set and the 2nd is the layer (or layer file) with the symbology to copy from. – Michael Stimson Nov 24 '17 at 3:44
  • Hi @MichaelStimson, could you kindly indicate how to modify the current code based on your suggestion? – K2609 Nov 24 '17 at 3:46
  • Do you have a layer with the correct symbology, preferably saved as a layer file? arcpy.ApplySymbologyFromLayer_management(layer, r'c:\some\path\SymbolLayer.lyr') should do it (change the path to match). – Michael Stimson Nov 24 '17 at 4:50
2

As I commented, I don't think you can use arcpy.ApplySymbologyFromLayer_management() and symbol.valueField to change the field but keep the same symbols.

A possible work-around would be to create a new field to store your values in for symbolising. This field could be temporary if you can't leave it in the shapefile, or alternatively if you can't modify the shapefile you could copy the entire dataset to an in_memory layer for processing purposes.

The idea is to loop through your different fields and copy the values to your symbology field. Your symbology properties will then stay the same, but the actual values on the feature will change each time the script loops.

Create your layer file first, with the symbology you want to use (set to a field called temp_field or whatever you want to call your temporary field

Sample Data:
enter image description here

Layer file symbology properties: enter image description here

import arcpy, os
mxd = arcpy.mapping.MapDocument("CURRENT")
outdir = r"C:\GIS\SE\SymOutput"
symLayer = r'C:\GIS\SE\LayerToSymboliseFrom.lyr'
myLayer = arcpy.mapping.ListLayers(mxd)[0]
arcpy.AddField_management(myLayer,'temp_field', "SHORT")
fields = [field.name for field in arcpy.ListFields(myLayer) if field.name <> 'temp_field']
fields = fields[2:len(fields)]
for field in fields:
    arcpy.CalculateField_management(myLayer, "temp_field", "!{0}!".format(field), "PYTHON_9.3")
    arcpy.ApplySymbologyFromLayer_management(myLayer, symLayer)
    arcpy.RefreshActiveView()
    arcpy.mapping.ExportToPNG(mxd, os.path.join(outdir, "{0}.png".format(field)))
arcpy.DeleteField_management(myLayer, 'temp_field')

Screenshots showing the output:

Field 1:
enter image description here

Field 2:
enter image description here

Field 3:
enter image description here

  • Hi Midavalo! This is exactly what I am after. Unfortunately when I try to replicate your code, I get the same map for all the fields (e.g. the Field 1 map in your case, repeated over and over). Do you know why this may be the case? – K2609 Nov 24 '17 at 19:45
  • Your saved Layer file containing the symbology must have the symbology set to use the name of the temporary field. You may need to create a dummy shapefile with this field present in order to select that field name – Midavalo Nov 24 '17 at 20:23
0

here are a few remarks to move further (see my comments on your script):

for field in fields: # this returns some fields objects, but you need to work with fields names (this can be managed here or later)
    arcpy.ApplySymbologyFromLayer_management(layer, symLayer) #symLayer is a lyr file with your symbology 
    layer.symbology.valueField = field.name #this must be changed AFTER you import the symbology, and I use the name of the field
    arcpy.RefreshActiveView()
    arcpy.RefreshTOC()
    arcpy.mapping.ExportToPNG(mxd, outdir+'\\'+field.name+".png")#here again, use fields' name
  • In my testing it seemed that layer.symbology.valueField = field.name reset the symbology that had been set in the line above (arcpy.ApplySymbologyFromLayer_management()) – Midavalo Nov 24 '17 at 19:27

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.