Set symbols and labels the same in different data frames

1246
9
Jump to solution
02-08-2012 07:34 AM
Zeke
by
Regular Contributor III
I know some python, and less arcpy. What I want to do is to loop through the features in the first data frame of two or more, get the symbology and label properties of each feature, then set the same features in all other data frames to the same property. This would be a kind of cleanup tool so I don't have to do it manually if I make changes.
Any ideas on where to start? I'm not sure how to get the features/properties from just the first data frame. The help files seem to deal with .lyr files, while I'm using shapefiles and feature classes in a gdb.
Maybe there's already a tool for this, but I'd like to do this as a learning exercise anyway. Thanks.
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
BenjaminGale
New Contributor III
Were you using my code?
If so, did you make any changes to it before getting the error?


I just retested the script and got an error too...primarily due to a typo.
It appears I missed a bracket when I put the code up.

I have fixed it though and tested the code below in PythonWin, in ArcMap and as a stand alone file.

If you made some changes to it...or used another script...I'd probably need to see it to determine where the error came from.
(The error sounds like the variable didn't get set to a layer object).

Sorry about my blunder.
Hope this helps : )

 import arcpy  mxd = arcpy.mapping.MapDocument('>>MXDPATHHERE<<') df = arcpy.mapping.ListDataFrames(mxd)  #Create list of layer from first dataframe symbologyList = arcpy.mapping.ListLayers(mxd,"",df[0]) layerList = list()  #Remove first dataframe from list df.remove(df[0])   #Add the rest of the layers to a list for d in df:     layerList.extend(arcpy.mapping.ListLayers(mxd,"",d))  #Compare the layers. If they are the same feature change the symbology. for symbologyLayer in symbologyList:     for layer in layerList:         if symbologyLayer.dataSource == layer.dataSource:             arcpy.ApplySymbologyFromLayer_management(layer, symbologyLayer) mxd.save() del mxd  

View solution in original post

0 Kudos
9 Replies
HenryColgate
Occasional Contributor
Maybe you could export as tempoarary layer files and then import the symbology over each layer in the subsequent data frames.

Of course this doesn't solve the labelling but may be 50% of what you need.
0 Kudos
BenjaminGale
New Contributor III
You could probably do something like this to apply the symbology from the first dataframe to the others.
I only tested it with two frames though (one to grab the symbology from and one to apply it too). You
should be able to grab the symbology from layers in more than one data frame with a bit of tweaking.

To compare if layers in different data frames are the same this example compares the layer's data sources.

I'm not sure how to apply this to the labels though...

Hope it helps! : )

import arcpy
mxd = arcpy.mapping.MapDocument('CURRENT')
df = arcpy.mapping.ListDataFrames(mxd)

#Create list of layer from first dataframe
symbologyList = arcpy.mapping.ListLayers(mxd,"",df[0])
layerList = list()

#Remove first dataframe from list
df.remove(df[0]) 

#Add the rest of the layers to a list
for d in df:
    layerList.extend(arcpy.mapping.ListLayers(mxd,"",d)

#Compare the layers. If they are the same feature change the symbology.
for symbologyLayer in symbologyList:
    for layer in layerList:
        if symbologyLayer.dataSource == layer.dataSource:
            arcpy.ApplySymbologyFromLayer_management(layer, symbologyLayer)
0 Kudos
Zeke
by
Regular Contributor III
Thanks, I'll give that a try. Appreciate it.
0 Kudos
Zeke
by
Regular Contributor III
Well, I think the error message below means the layer doesn't have a datasource property, although it comes up in the intellisense window in PythonWin after typing the dot after symbologyLayer & layer. The help files seem to indicate that the layer has to be a layer, .lyr, file, and not a feature class or shapefile. I don't know why this would be the case.

  File "C:\Users\greg\Desktop\Clone_symbology_data_frames.py", line 19, in <module>
    if symbologyLayer.dataSource == layer.dataSource:
  File "C:\Program Files (x86)\ArcGIS\Desktop10.0\arcpy\arcpy\arcobjects\_base.py", line 70, in _get
    return convertArcObjectToPythonObject(getattr(self._arc_object, attr_name))
AttributeError: LayerObject: Get attribute dataSource does not exist
0 Kudos
BenjaminGale
New Contributor III
Were you using my code?
If so, did you make any changes to it before getting the error?


I just retested the script and got an error too...primarily due to a typo.
It appears I missed a bracket when I put the code up.

I have fixed it though and tested the code below in PythonWin, in ArcMap and as a stand alone file.

If you made some changes to it...or used another script...I'd probably need to see it to determine where the error came from.
(The error sounds like the variable didn't get set to a layer object).

Sorry about my blunder.
Hope this helps : )

 import arcpy  mxd = arcpy.mapping.MapDocument('>>MXDPATHHERE<<') df = arcpy.mapping.ListDataFrames(mxd)  #Create list of layer from first dataframe symbologyList = arcpy.mapping.ListLayers(mxd,"",df[0]) layerList = list()  #Remove first dataframe from list df.remove(df[0])   #Add the rest of the layers to a list for d in df:     layerList.extend(arcpy.mapping.ListLayers(mxd,"",d))  #Compare the layers. If they are the same feature change the symbology. for symbologyLayer in symbologyList:     for layer in layerList:         if symbologyLayer.dataSource == layer.dataSource:             arcpy.ApplySymbologyFromLayer_management(layer, symbologyLayer) mxd.save() del mxd  
0 Kudos
Zeke
by
Regular Contributor III
Thanks. I caught the typo w/the parenthesis. Only thing I changed was the directory, from CURRENT to an absolute path. At one point I did add a 'print d.name' after the layerList.Extend, and that gave the correct names. I know that sometimes the error is in the line above the cited one, but that's just a For loop declaration.

My code (well, your code):
import arcpy
mxd = arcpy.mapping.MapDocument(r'F:\Muzyl\GIS\Old Data\Michigan LP\MXD\Michigan.mxd')
df = arcpy.mapping.ListDataFrames(mxd)

#Create list of layer from first dataframe
symbologyList = arcpy.mapping.ListLayers(mxd,"",df[0])
layerList = list()

#Remove first dataframe from list
df.remove(df[0]) 

#Add the rest of the layers to a list
for d in df:
    layerList.extend(arcpy.mapping.ListLayers(mxd,"",d))

#Compare the layers. If they are the same feature change the symbology.
for symbologyLayer in symbologyList:
    for layer in layerList:
        if symbologyLayer.dataSource == layer.dataSource:
            arcpy.ApplySymbologyFromLayer_management(layer, symbologyLayer)


and the error in PythonWin:
Traceback (most recent call last):
  File "C:\Python26\ArcGIS10.0\Lib\site-packages\pythonwin\pywin\framework\scriptutils.py", line 309, in RunScript
    debugger.run(codeObject, __main__.__dict__, start_stepping=0)
  File "C:\Python26\ArcGIS10.0\Lib\site-packages\pythonwin\pywin\debugger\__init__.py", line 60, in run
    _GetCurrentDebugger().run(cmd, globals,locals, start_stepping)
  File "C:\Python26\ArcGIS10.0\Lib\site-packages\pythonwin\pywin\debugger\debugger.py", line 624, in run
    exec cmd in globals, locals
  File "C:\Users\greg\Desktop\Clone_symbology_data_frames.py", line 19, in <module>
    if symbologyLayer.dataSource == layer.dataSource:
  File "C:\Program Files (x86)\ArcGIS\Desktop10.0\arcpy\arcpy\arcobjects\_base.py", line 70, in _get
    return convertArcObjectToPythonObject(getattr(self._arc_object, attr_name))
AttributeError: LayerObject: Get attribute dataSource does not exist
>>> 
0 Kudos
BenjaminGale
New Contributor III
I've been doing some testing on my script and now I am somewhat confused too.

I've tried the script in the Python window of ArcMap for a number of mxds. Usually I'd copy/paste the present data frame so I had two data frames to test on.
Most of the time the script works perfectly but I have had one set of data that keeps causing me to get an error (below).
The error for me seems to occur in the last line when I try to apply the symbology.

However, because I did my test in the ArcMap python window I am not sure if it is the same error that you are getting.

Runtime error <class 'arcgisscripting.ExecuteError'>: ERROR 000967: The input layer type must be a feature layer, raster layer, or tin layer. ERROR 000840: The value is not a Layer.


The error appears to be complaining about my input put not being the right kind of layer...
The thing that I'm confused about in my case is that when I check the feature the error occurs on it says it IS a feature layer.
Strangely there doesn't seem to be anything special about the data that would make it cause this error...


>>> symbologyLayer.isFeatureLayer
True
>>> layer.isFeatureLayer
True
>>> for lyr in layerList:
...  if lyr.isFeatureLayer:
...     print "TRUE"
... 
TRUE

TRUE

TRUE

TRUE

TRUE

>>> for lyr in symbologyList:
...  if lyr.isFeatureLayer:
...     print "TRUE"
... 
TRUE

TRUE

TRUE

TRUE

TRUE



So now I am a little puzzled at what might be the problem for either of us...
0 Kudos
Zeke
by
Regular Contributor III
Well, it did work in the python window. It also added duplicate layers to the first data frame, presumably because the ApplySymbologyLayer tool ran on all layerList, which had included the features from the first data frame. Adding them in again seems a strange behavior, but whatever.
One thing I found strange, but maybe is normal, is that the iterators - d, symbologyLayer & layer - didn't pop up any intellisense.
Don't know why a stand alone script wouldn't work. Next step is to try it after adding the script as a tool, then work on labels.
I really appreciate the help, thanks.
0 Kudos
Zeke
by
Regular Contributor III
Well, that's odd. Last time I typed the script line by line into the Python window in ArcGIS, and it ran. This time, I imported the .py file - same script - and got the same error 'arcgisscripting...' as above. Besides the riddle of why it runs one way and not the other, why an arcgisscripting error when this is ArcGIS 10, importing arcpy?
To further muddy the waters, I just loaded the script in the Python window and changed the hardcoded path to the mxd in MapDocument to CURRENT, and it worked. Maybe this is a PATH problem when running the script outside ArcGIS? Python isn't in my PATH variable anywhere. But shouldn't a hardcoded path from within ArcGIS work anyway? Hmmm...
0 Kudos