how to keep symbology outlines the same when I change the value field

6441
18
Jump to solution
12-03-2012 04:24 AM
TimothyMcNeel
New Contributor II
I'm using graduated colors symbology with quantiles, and I have different fill colors and outline colors for the different quantile categories.  My python script loops through several fields, and for each field it sets the layer's symbology.valueField to the new field and creates a JPEG using arcpy.mapping.ExportToJPEG.  The quantiles recalculate correctly based on the new field, and the fill colors for each quantile group remain correct, but the outlines all change to gray.  How can I keep outlines the same (or reset them after they change) when I change the value field?

I don't see any way to to set the outline colors directly using Python.  I tried setting up a layer with the correct symbology and applying that (using arcpy.mapping.UpdateLayer and, in a separate attempt, arcpy.ApplySymbologyFromLayer_management) to my main layer after switching the value field.  But it appears that these functions set the symbology value field in addition to the fill colors and outlines.

I'm using ArcGIS 10.1.
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
JeffMoulds
Esri Contributor
I got this to work using the ApplySymbologyFromLayer GP tool. You will need a seed layer file that contains the symbology and field that you want to symbolize with. However, the underlying data (and therefore the class break values) do not need to be the same. The GP tool will reclassify the class breaks after applying the seed layer. Here is some sample code:
import arcpy mxd = arcpy.mapping.MapDocument(r"C:\backup\ValueField\ValueField.mxd") lyr = arcpy.mapping.ListLayers(mxd)[0] lyr.symbology.valueField = 'POP2000' arcpy.ApplySymbologyFromLayer_management(lyr, r"C:\backup\ValueField\ThickOutline.lyr") arcpy.mapping.ExportToPDF(mxd, 'foo.pdf') mxd.saveACopy(r"C:\backup\ValueField\foo.mxd") print 'done'

View solution in original post

0 Kudos
18 Replies
JeffMoulds
Esri Contributor
Unfortunately, that's a bug (the bug tracking number is NIM085601). We have a targeted fix of SP2 (tentative date spring 2013).

Workarounds could get tricky for this issue. You can try using arcpy.mapping.UpdateLayer with the symbology_only option set to True. You would have to have a staged .lyr file that contains the fields and symbology that you want. However, if the data is different, then the class breaks may not be what you expect - in which case you would call symbology.reclassify(). However, reclassify has the same bug in that it resets outline properties. In that case, you would NOT use reclassify() and instead determine the breaks and labels using some scripting logic and then apply those values to the renderer via .classBreakValues and .classBreakLabels.
0 Kudos
TimothyMcNeel
New Contributor II
Jeff: Thanks for the response.  If I understand your workaround correctly, I would need to create a layer or MXD by hand for each of the fields I want to use and set up the symbology for each one.  That's the part I want to automate--I have dozens of fields.

I tried a new approach: changing the underlying data.  I set up a field named mainField and used that as the value field in the symbology.  Then in the Python script, for each of my other fields, I used arcpy.da.UpdateCursor to copy the values of the field into mainField and then I exported to JPEG.  The values of mainField get set correctly and the fill colors and outlines are right, but the class breaks are still based on the original values of mainField.  As you said, using symbology.reclassify causes the outlines to turn gray.  You mentioned using symbology.classBreakValues instead, but when I tried it, the outlines turned gray--am I missing something?
0 Kudos
JeffMoulds
Esri Contributor
It appears classBreakValues has the same issue of clearing the outlines. I'll look into another workaround...
0 Kudos
JeffMoulds
Esri Contributor
I got this to work using the ApplySymbologyFromLayer GP tool. You will need a seed layer file that contains the symbology and field that you want to symbolize with. However, the underlying data (and therefore the class break values) do not need to be the same. The GP tool will reclassify the class breaks after applying the seed layer. Here is some sample code:
import arcpy mxd = arcpy.mapping.MapDocument(r"C:\backup\ValueField\ValueField.mxd") lyr = arcpy.mapping.ListLayers(mxd)[0] lyr.symbology.valueField = 'POP2000' arcpy.ApplySymbologyFromLayer_management(lyr, r"C:\backup\ValueField\ThickOutline.lyr") arcpy.mapping.ExportToPDF(mxd, 'foo.pdf') mxd.saveACopy(r"C:\backup\ValueField\foo.mxd") print 'done'
0 Kudos
TimothyMcNeel
New Contributor II
Maybe I'm missing something, but I don't see how that solution helps.  Suppose I have 50 fields in my data, and I want to create 50 jpegs using the same symbology for each field.  As you said, to use the ApplySymbologyFromLayer GP tool, the seed layer file must use a field that is named the same as the field in my data.  So I would need to make 50 seed layer files by hand, one for each field in my data, right?
0 Kudos
JeffMoulds
Esri Contributor
Yes, if you have that many fields, then it may get to the point where its not worth it. This workaround would be better for workflows where you have 50 feature classes, all with the same field. Then only one seed file would be req'd. Unfortunately, I cant think of any other python workarounds.
0 Kudos
TimothyMcNeel
New Contributor II
Jeff: I thought again about what you wrote about the ApplySymbologyFromLayer GP tool, and I realized that combining that with the method of changing the underlying data I mentioned earlier yields the solution I was looking for.  Thanks for the help!

Here is the whole approach, in case someone else wants to do the same thing before the bug gets fixed:

Do the following by hand:

  1. Set up two layers in the MXD, named mainLayer and donorLayer.  Each layer should have a field named mainField.  The layer named mainLayer should have the fields you want to use to create the JPEGs.

  2. Set up the symbology in donorLayer, using mainField as the value field.

  3. Make mainLayer visible and donorLayer invisible.  (Alternately, donorLayer could be a separate layer file or in a separate MXD.)

In the Python script, loop through each field you want to use, doing the following for each:

  1. Use arcpy.da.UpdateCursor to copy the values of the field into mainField.

  2. Use arcpy.ApplySymbologyFromLayer_management to copy the symbology from donorLayer to mainLayer.  The similar function arcpy.mapping.UpdateLayer does not work here.

  3. Use arcpy.mapping.ExportToJPEG to create the JPEG.

0 Kudos
ShaneArmour
New Contributor II
I am having the same issue. Were you able to get around this issue? Can you please post the code with the workaround. I am still having issues with the symbology outlines.

Thank you in advance!
0 Kudos
TimothyMcNeel
New Contributor II
I am having the same issue. Were you able to get around this issue? Can you please post the code with the workaround. I am still having issues with the symbology outlines.

Thank you in advance!

Yes, I worked around it as I described in post #8 in this thread.  Did you follow those steps?  What part isn't working for you?  I'm reluctant to post the whole script (it's fairly complex).
0 Kudos