2

I am using arcpy (ArcMap 10.1) to create a series of maps of the same extent that show increased count of disease in areas over time. For example, in the first map, the disease count will be low in each area, the second map will be slightly more, etc. I created a layer file with a symbology that I want to use in each map so that, as time increases, people can see how the count of disease is increasing in each area relative to prior maps.

In ArcMap itself, I can go to the Layer Properties and Import

enter image description here

my layer file so that ranges for each coloring bin do not change. However, it seems that arcpy only has access to the Apply Symbology From Layer tool. This applies the rules of the layer file I have (ie. Natural Breaks, 10 classes), but changes all of the bin sizes and makes them only appropriate to that specific layer.

Is there any way to access something like the Import button from ArcPy?

4
  • This cannot be done with arcpy. To truly replicate the import button, you would have to use ArcObjects, which is possible with Python. This post is a good start. Also, it is worth noting that if the only problem you are seeing from ApplySymbologyFromLayer is different class breaks, you can use arcpy to to adjust these after you apply the symbology.
    – crmackey
    Commented Mar 4, 2016 at 14:43
  • I have added an ArcObjects Python sample. So far this only has support for Class Breaks Symbology, but it wouldn't be too difficult to do Unique Values or other ones as well.
    – crmackey
    Commented Mar 4, 2016 at 18:58
  • For the sake of making sure I had something working for now, I used ApplySymbologyFromLayer with arcpy and then lyr.symbology.classBreakValues to adjust the values after the symbology was applied. I'll plan to take a look at your ArcObjects solution this weekend, thanks a bunch!
    – jcusick
    Commented Mar 4, 2016 at 19:12
  • For that case, using arcpy will always work well. You will only need ArcObjects when the field names don't match since there is no option to choose a target field in the Apply Symbology tool or if you need to change symbology types. I have been frustrated for a long time that GP tool doesn't let you pick a target field name so I will probably invest some more time to make the ArcObjects solution work with other symbology types.
    – crmackey
    Commented Mar 4, 2016 at 19:29

2 Answers 2

1

I was able to come up with an ArcObjects solution to do this in Python. First thing you'll need is the Snippets module, of which I have a copy on GitHub. Then you can call this function:

def importSymbologyFromLayer(pApp, target_layer, target_field, symbol_layer):
    """imports the symbology from a layer in TOC

    pApp -- reference to current app
    target_layer -- layer to symbolize
    target_field -- name of target field to symbolize
    symbol_layer -- symbology layer
    """
    import comtypes.gen.esriDisplay as esriDisplay
    import comtypes.gen.esriArcMapUI as esriArcMapUI
    import comtypes.gen.esriCarto as esriCarto

    pDoc = pApp.Document
    pMxDoc = CType(pDoc, esriArcMapUI.IMxDocument)
    pMap = pMxDoc.FocusMap

    # get layer references
    targ_lyr = [pMap.Layer(i) for i in range(pMap.LayerCount) if pMap.Layer(i).Name == target_layer][0]
    symb_lyr = [pMap.Layer(i) for i in range(pMap.LayerCount) if pMap.Layer(i).Name == symbol_layer][0]

    # cast to IGeoFeatureLayer interface and get renderers
    targGeo = CType(targ_lyr, esriCarto.IGeoFeatureLayer)
    symbGeo = CType(symb_lyr, esriCarto.IGeoFeatureLayer)
    symbRenderer = symbGeo.Renderer

    # cast to IClassBreaksRenderer
    targClassBreaks = NewObj(esriCarto.ClassBreaksRenderer, esriCarto.IClassBreaksRenderer)
    symbClassBreaks = CType(symbRenderer, esriCarto.IClassBreaksRenderer)

    # set target symbology field
    targClassBreaks.Field = target_field
    targClassBreaks.BreakCount = symbClassBreaks.BreakCount

    # iterate through class beraks from symbol layer and apply to target
    for i in range(symbClassBreaks.BreakCount):
        print i, symbClassBreaks.Break(i)
        targClassBreaks.Break[i] = symbClassBreaks.Break(i)
        targClassBreaks.Description[i] = symbClassBreaks.Description[i]
        targClassBreaks.Symbol[i] = symbClassBreaks.Symbol[i]
        targClassBreaks.Label[i] = symbClassBreaks.Label[i]

    targGeo.Renderer = targClassBreaks
    pMxDoc.ActiveView.Refresh()
    pMxDoc.UpdateContents()

I can push this function to the GitHub repo later, but you can just stick this in it for now. I tested in the ArcMap Python window, passing in arcobjects.GetCurrentApp() as the pApp parameter and it worked.

0

Per the comment from @crmackey above -- 'This cannot be done with arcpy... [but] you can use arcpy to adjust these after you apply the symbology.'

See Replicate Import Symbology Matching Dialog in ArcObjects? from @crmackey for how to do this with ArcObjects.

See Changing graduated color class values with ArcPy? for how to change symbology class breaks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.