Select to view content in your preferred language

Has anyone modified UniqueValuesSymbology???s Lyr.symbology.classLabels successfull?

6618
9
Jump to solution
08-11-2013 03:19 AM
by Anonymous User
Not applicable
Original User: jetaimy

Hi every guys,I want to modify a mxd file???s ???Lyr.symbology.classLabels???(see in Figure1),The main steps as follows:
First,According to Layer???s name and
  Checks whether the property of the  Layer is UniqueValuesSymbology, Then assign the value list ???lyr.symbology.classValues??? to customized ???Values??? List;
                                        Figure 1  Layer???s UniqueValuesSymbology
[ATTACH=CONFIG]26627[/ATTACH]
Second,For each value in ???Values??? List,We reads the corresponding Label form a pre-defined dictionary named ???value_label???(see in Figure2,such as '2101010414'  corresponding to' ground River (single) '),and append it to the ???upt_Labels??? List;

Figure 2 value_label dictionary
[ATTACH=CONFIG]26628[/ATTACH]
Third,I use the ???upt_Labels??? List to modify a mxd file???s ???Lyr.symbology.classLabels???,And I want the result like this(see in Figure3):
Figure 3  Expect layers appear???s UniqueValuesSymbology
[ATTACH=CONFIG]26629[/ATTACH]
But '' lyr.symbology.classLabels = upt_Labels ''cannot affect after i check the labelList in ArcMap10.1(Also no error info appears when i debug),in fact,there was not any change in mxd, The main code as follow(The script was runing in ArcGIS10.1 SP1 ,Windows7 64bit Ultimate😞
''' #According mxd's LayerName to modify symbology.classLabels ''' def EditLyrSymInfo(mxd,lyrName):     lyr = arcpy.mapping.ListLayers(mxd, lyrName)[0]     if lyr.symbologyType == "UNIQUE_VALUES":         Labels=lyr.symbology.classLabels         Values=lyr.symbology.classValues         #use this upt_Labels List to update Layer's symbology.classLabels            upt_Labels=[]          for value in Values:             #value_label dictionary's value in Figure 2             upt_label=label_value[value]             upt_Labels.append(upt_label)             print u'Labels:{0}, Values:{1};'.format(upt_label,value)         lyr.symbology.classLabels=upt_Labels         arcpy.RefreshActiveView()         arcpy.RefreshTOC()

[ATTACH=CONFIG]26630[/ATTACH]
What's wrong? I wonder if the property ???symbology.classLabels???can not modified ,but I read ESRI???s online help document (UniqueValuesSymbology (arcpy.mapping))and know  it can read and write ,and there is an Example in the topic.
Has anyone modified UniqueValuesSymbology???s property ???symbology.classLabels??? successfull? Any help will be appreciated ! Thank you very much!
0 Kudos
1 Solution

Accepted Solutions
RhettZufelt
MVP Notable Contributor
For one, your forward/backward sloping single quotes are invalid to the interpreter.  It either errors out or just hangs there unitil I kill it.  Once I removed them, the script would run.

Then, after I put a mxd.save() in there, the class labels are updated in the mxd.

Here is the code that works just fine for me, using your example data:

# -*- coding: utf-8 -*- import arcpy, os import arcpy.mapping #Pre-defined ???code:name??? key-value pair code_name={'A':'Apples','B':'Bananas','C':'Cherries'} #Get mxd  mxd=arcpy.mapping.MapDocument(r"E:\Test_Symbology\Test_Symbology.mxd") #According mxd&layername ???code:name??? key-value pair to modify lyr.symbology.classLabels def EditLyrSymInfo(mxd,lyrName):     lyr = arcpy.mapping.ListLayers(mxd, lyrName)[0]     if lyr.symbologyType == "UNIQUE_VALUES":         Labels=lyr.symbology.classLabels         Values=lyr.symbology.classValues         upt_Labels=[]         print "Layer Symbology Info to be Edit:",lyrName         for value in Values:             upt_label=code_name[value]             upt_Labels.append(upt_label)             print u'Labels:{0}, Values:{1};'.format(upt_label,value)         lyr.symbology.classLabels=upt_Labels         lyr.symbology.showOtherValues = False         arcpy.RefreshActiveView()         arcpy.RefreshTOC()         mxd.save() def main():     #Print Pre-defined code:name key-value pair     print '##Print Pre-defined code:name key-value pair##'     for key,value in code_name.iteritems():         print key,value           lyrName="PlanPolygonSelectR"     #After modify lyr.symbology.classLabels(Labels:Values)key-value pair:     print '##After modify lyr.symbology.classLabels(Labels:Values)key-value pair:##'     EditLyrSymInfo(mxd,lyrName) if __name__=="__main__":     main()


R_

Keep in mind, I tested this "outside" of ArcMap with a closed mxd.  When I re-open the mxd, the changes are shown as expected.

Before Script:

[ATTACH=CONFIG]26801[/ATTACH]

After Script:

[ATTACH=CONFIG]26802[/ATTACH]

Just tested inside ArcMap with the python window and mxd = CURRENT.  works fine.

View solution in original post

0 Kudos
9 Replies
JeffBarrette
Esri Regular Contributor
Hello,

The .classValues property is read/write but I'm curious about the following line:

Then assign the value list �??lyr.symbology.classValues�?? to customized �??Values�??


The values in the values list MUST match the data in the field being used to generate the unique values.  You can't change the values to anything you want (but you can change the labels as long as both lists have the same length).  For example, lets say these are all the values: ["a","b","c","d","e"].

I can NOT do this:
cList = ["f", "g", "h", "i", "j"]   ## these values don't exist in my data.
sym.classValues = aList

Nothing will happen as you describe in your scenario.

The point of writing the value list is that you may want to generate a subset of values.

cList = ["a", "b", "c"]
lList = ["apples", "bananas", "cherries"]
sym.classValues = aList
sym.classLables = lList


After a refresh you would only see 3 unique values instead of 5.

Jeff
0 Kudos
by Anonymous User
Not applicable
Original User: jetaimy

Thank you Jeff! I use sample data you provide to update mxd again,but ''lyr.symbology.classLabels=upt_Labels''cannot affect at all,there was not any change in mxd,All my code as follows:
# -*- coding: utf-8 -*-
import arcpy, os
import arcpy.mapping
#Pre-defined �??code�?name�?? key-value pair
code_name={'A':'Apples','B':'Bananas','C':'Cherries'}
#Get mxd 
mxd=arcpy.mapping.MapDocument(r"E:\Test_Symbology\Test_Symbology.mxd")
#According mxd&layername �??code�?name�?? key-value pair to modify lyr.symbology.classLabels
def EditLyrSymInfo(mxd,lyrName):
    lyr = arcpy.mapping.ListLayers(mxd, lyrName)[0]
    if lyr.symbologyType == "UNIQUE_VALUES":
        Labels=lyr.symbology.classLabels
        Values=lyr.symbology.classValues
        upt_Labels=[]
        print "Layer Symbology Info to be Edit:"+lyrName
        for value in Values:
            upt_label=code_name[value]
            upt_Labels.append(upt_label)
            print u'Labels:{0}, Values:{1};'.format(upt_label,value)
        lyr.symbology.classLabels=upt_Labels
        lyr.symbology.showOtherValues = False
        arcpy.RefreshActiveView()
        arcpy.RefreshTOC()
def main():
    #Print Pre-defined �??code�?name�?? key-value pair
    print u'##Print Pre-defined �??code�?name�?? key-value pair##'
    for key,value in code_name.iteritems():
        print key,value      
    lyrName="PlanPolygonSelectR"
    #After modify lyr.symbology.classLabels(Labels:Values)key-value pair:
    print u'##After modify lyr.symbology.classLabels(Labels:Values)key-value pair:##'
    EditLyrSymInfo(mxd,lyrName)
if __name__=="__main__":
    main()


The sample data and mxd are in attatchment,Any help will be appreciated !
0 Kudos
jiangjian
Emerging Contributor
Can symbology.classLabels property  read/write? Or there is a bug in ESRI Products? I try the sample data and there was not any change in mxd at all.
Thank you Jeff! I use sample data you provide to update mxd again,but ''lyr.symbology.classLabels=upt_Labels''cannot affect at all,there was not any change in mxd,All my code as follows:
# -*- coding: utf-8 -*-
import arcpy, os
import arcpy.mapping
#Pre-defined �??code�?name�?? key-value pair
code_name={'A':'Apples','B':'Bananas','C':'Cherries'}
#Get mxd 
mxd=arcpy.mapping.MapDocument(r"E:\Test_Symbology\Test_Symbology.mxd")
#According mxd&layername �??code�?name�?? key-value pair to modify lyr.symbology.classLabels
def EditLyrSymInfo(mxd,lyrName):
    lyr = arcpy.mapping.ListLayers(mxd, lyrName)[0]
    if lyr.symbologyType == "UNIQUE_VALUES":
        Labels=lyr.symbology.classLabels
        Values=lyr.symbology.classValues
        upt_Labels=[]
        print "Layer Symbology Info to be Edit:"+lyrName
        for value in Values:
            upt_label=code_name[value]
            upt_Labels.append(upt_label)
            print u'Labels:{0}, Values:{1};'.format(upt_label,value)
        lyr.symbology.classLabels=upt_Labels
        lyr.symbology.showOtherValues = False
        arcpy.RefreshActiveView()
        arcpy.RefreshTOC()
def main():
    #Print Pre-defined �??code�?name�?? key-value pair
    print u'##Print Pre-defined �??code�?name�?? key-value pair##'
    for key,value in code_name.iteritems():
        print key,value      
    lyrName="PlanPolygonSelectR"
    #After modify lyr.symbology.classLabels(Labels:Values)key-value pair:
    print u'##After modify lyr.symbology.classLabels(Labels:Values)key-value pair:##'
    EditLyrSymInfo(mxd,lyrName)
if __name__=="__main__":
    main()


The sample data and mxd are in attatchment,Any help will be appreciated !
0 Kudos
by Anonymous User
Not applicable
Original User: rzufelt

For one, your forward/backward sloping single quotes are invalid to the interpreter.  It either errors out or just hangs there unitil I kill it.  Once I removed them, the script would run.

Then, after I put a mxd.save() in there, the class labels are updated in the mxd.

Here is the code that works just fine for me, using your example data:

# -*- coding: utf-8 -*-
import arcpy, os
import arcpy.mapping
#Pre-defined �??code:name�?? key-value pair
code_name={'A':'Apples','B':'Bananas','C':'Cherries'}
#Get mxd 
mxd=arcpy.mapping.MapDocument(r"E:\Test_Symbology\Test_Symbology.mxd")
#According mxd&layername �??code:name�?? key-value pair to modify lyr.symbology.classLabels
def EditLyrSymInfo(mxd,lyrName):
    lyr = arcpy.mapping.ListLayers(mxd, lyrName)[0]
    if lyr.symbologyType == "UNIQUE_VALUES":
        Labels=lyr.symbology.classLabels
        Values=lyr.symbology.classValues
        upt_Labels=[]
        print "Layer Symbology Info to be Edit:",lyrName
        for value in Values:
            upt_label=code_name[value]
            upt_Labels.append(upt_label)
            print u'Labels:{0}, Values:{1};'.format(upt_label,value)
        lyr.symbology.classLabels=upt_Labels
        lyr.symbology.showOtherValues = False
        arcpy.RefreshActiveView()
        arcpy.RefreshTOC()
        mxd.save()
def main():
    #Print Pre-defined code:name key-value pair
    print '##Print Pre-defined code:name key-value pair##'
    for key,value in code_name.iteritems():
        print key,value      
    lyrName="PlanPolygonSelectR"
    #After modify lyr.symbology.classLabels(Labels:Values)key-value pair:
    print '##After modify lyr.symbology.classLabels(Labels:Values)key-value pair:##'
    EditLyrSymInfo(mxd,lyrName)
if __name__=="__main__":
    main()


R_

Keep in mind, I tested this "outside" of ArcMap with a closed mxd.  When I re-open the mxd, the changes are show as expected.

Before Script:

[ATTACH=CONFIG]26799[/ATTACH]

After Script:

[ATTACH=CONFIG]26800[/ATTACH]
0 Kudos
RhettZufelt
MVP Notable Contributor
For one, your forward/backward sloping single quotes are invalid to the interpreter.  It either errors out or just hangs there unitil I kill it.  Once I removed them, the script would run.

Then, after I put a mxd.save() in there, the class labels are updated in the mxd.

Here is the code that works just fine for me, using your example data:

# -*- coding: utf-8 -*- import arcpy, os import arcpy.mapping #Pre-defined ???code:name??? key-value pair code_name={'A':'Apples','B':'Bananas','C':'Cherries'} #Get mxd  mxd=arcpy.mapping.MapDocument(r"E:\Test_Symbology\Test_Symbology.mxd") #According mxd&layername ???code:name??? key-value pair to modify lyr.symbology.classLabels def EditLyrSymInfo(mxd,lyrName):     lyr = arcpy.mapping.ListLayers(mxd, lyrName)[0]     if lyr.symbologyType == "UNIQUE_VALUES":         Labels=lyr.symbology.classLabels         Values=lyr.symbology.classValues         upt_Labels=[]         print "Layer Symbology Info to be Edit:",lyrName         for value in Values:             upt_label=code_name[value]             upt_Labels.append(upt_label)             print u'Labels:{0}, Values:{1};'.format(upt_label,value)         lyr.symbology.classLabels=upt_Labels         lyr.symbology.showOtherValues = False         arcpy.RefreshActiveView()         arcpy.RefreshTOC()         mxd.save() def main():     #Print Pre-defined code:name key-value pair     print '##Print Pre-defined code:name key-value pair##'     for key,value in code_name.iteritems():         print key,value           lyrName="PlanPolygonSelectR"     #After modify lyr.symbology.classLabels(Labels:Values)key-value pair:     print '##After modify lyr.symbology.classLabels(Labels:Values)key-value pair:##'     EditLyrSymInfo(mxd,lyrName) if __name__=="__main__":     main()


R_

Keep in mind, I tested this "outside" of ArcMap with a closed mxd.  When I re-open the mxd, the changes are shown as expected.

Before Script:

[ATTACH=CONFIG]26801[/ATTACH]

After Script:

[ATTACH=CONFIG]26802[/ATTACH]

Just tested inside ArcMap with the python window and mxd = CURRENT.  works fine.
0 Kudos
by Anonymous User
Not applicable
Original User: jetaimy

That's got it,My previous code was modified from ArcGIS online help(UniqueValuesSymbology (arcpy.mapping)->UniqueValuesSymbology example 2),There isn't  mxd.save() at end,It looks like that not all sample code are completely correct,Thank you very much  rzufelt,your advice is very helpfull!
For one, your forward/backward sloping single quotes are invalid to the interpreter.  It either errors out or just hangs there unitil I kill it.  Once I removed them, the script would run.

Then, after I put a mxd.save() in there, the class labels are updated in the mxd.

Here is the code that works just fine for me, using your example data:

# -*- coding: utf-8 -*-
import arcpy, os
import arcpy.mapping
#Pre-defined �??code:name�?? key-value pair
code_name={'A':'Apples','B':'Bananas','C':'Cherries'}
#Get mxd 
mxd=arcpy.mapping.MapDocument(r"E:\Test_Symbology\Test_Symbology.mxd")
#According mxd&layername �??code:name�?? key-value pair to modify lyr.symbology.classLabels
def EditLyrSymInfo(mxd,lyrName):
    lyr = arcpy.mapping.ListLayers(mxd, lyrName)[0]
    if lyr.symbologyType == "UNIQUE_VALUES":
        Labels=lyr.symbology.classLabels
        Values=lyr.symbology.classValues
        upt_Labels=[]
        print "Layer Symbology Info to be Edit:",lyrName
        for value in Values:
            upt_label=code_name[value]
            upt_Labels.append(upt_label)
            print u'Labels:{0}, Values:{1};'.format(upt_label,value)
        lyr.symbology.classLabels=upt_Labels
        lyr.symbology.showOtherValues = False
        arcpy.RefreshActiveView()
        arcpy.RefreshTOC()
        mxd.save()
def main():
    #Print Pre-defined code:name key-value pair
    print '##Print Pre-defined code:name key-value pair##'
    for key,value in code_name.iteritems():
        print key,value      
    lyrName="PlanPolygonSelectR"
    #After modify lyr.symbology.classLabels(Labels:Values)key-value pair:
    print '##After modify lyr.symbology.classLabels(Labels:Values)key-value pair:##'
    EditLyrSymInfo(mxd,lyrName)
if __name__=="__main__":
    main()


R_

Keep in mind, I tested this "outside" of ArcMap with a closed mxd.  When I re-open the mxd, the changes are shown as expected.

Before Script:

[ATTACH=CONFIG]26801[/ATTACH]

After Script:

[ATTACH=CONFIG]26802[/ATTACH]

Just tested inside ArcMap with the python window and mxd = CURRENT.  works fine.
0 Kudos
RhettZufelt
MVP Notable Contributor
Not all operations require a mxd.save().  If you were exporting an output image in each iteration or something, the changes should be represented in the output.  However, without a mxd.save(), the changes made by the script would not show in the mxd the next time you open it.

In example 2, the mxd was set to "current" ( mxd = arcpy.mapping.MapDocument("current") ) which mean to apply the code to the currently open mxd.  This would be run from the python window within ArcMap, so, you would already have the mxd open and would see the changes take place.  you would then be warned if you tried to close without saving and could save if needed.

Need to be carefull performing such an operation as too many mxd.save(s) within an iteration will crash python (in my case, error = 'PageLayoutObject: Error in executing ExportToJPEG' ).  Often will make somewhere between 47 and 112 iterations, then crash for no reason.  I had this happen in multiple scripts, once I removed the mxd.save(s), it will finish all 1800+ outputs.

R_
0 Kudos
by Anonymous User
Not applicable
Original User: msayler

In example 2, the mxd was set to "current" ( mxd = arcpy.mapping.MapDocument("current") ) which mean to apply the code to the currently open mxd.  This would be run from the python window within ArcMap, so, you would already have the mxd open and would see the changes take place.  you would then be warned if you tried to close without saving and could save if needed.


If you're working with "CURRENT", you might need to throw in a "arcpy.RefreshTOC()" before you actually see the changes.
0 Kudos
jiangjian
Emerging Contributor
Thank you rzufelt,From your complete and accurate replys I learned a lot!
Not all operations require a mxd.save().  If you were exporting an output image in each iteration or something, the changes should be represented in the output.  However, without a mxd.save(), the changes made by the script would not show in the mxd the next time you open it.

In example 2, the mxd was set to "current" ( mxd = arcpy.mapping.MapDocument("current") ) which mean to apply the code to the currently open mxd.  This would be run from the python window within ArcMap, so, you would already have the mxd open and would see the changes take place.  you would then be warned if you tried to close without saving and could save if needed.

Need to be carefull performing such an operation as too many mxd.save(s) within an iteration will crash python (in my case, error = 'PageLayoutObject: Error in executing ExportToJPEG' ).  Often will make somewhere between 47 and 112 iterations, then crash for no reason.  I had this happen in multiple scripts, once I removed the mxd.save(s), it will finish all 1800+ outputs.

R_
0 Kudos