1

Working on a Python script that I will run inside of ArcGIS 10.5 that will export PNG maps. Each map will be a different state and for every state there will be 5 different physician specialty types, resulting in about 250 total maps. My current version of the script can export one type of physician for all states, but when I move on to the next physician type, I have to manually enter the next one into my script and run again.

I can loop through all 50 states, but I am not finding success in looping through all 5 physician types in a single go. I suspect it's part Python and part data set-up, but I was wondering if anyone had pointers on how to effectively loop within a loop.

So right now, it loops through a dictionary list of the states. How do I include a sub-loop list and be able to use it in a for loop in the script?

Code is below; all of the 'spec%' items are the physician types and in my MXD, I have separate layers for each point layer.

for state, fname, spec1, spec2, spec3, spec4, spec5, spec6, spec7, spec8, spec9, spec10, spec11, spec12, spec13, spec14, spec15, spec16, spec17, spec18, spec19, spec20, spec21, spec22, spec23, spec24, spec25, spec26, spec27, spec28, spec29 in st_list_tup:

lyr3.visible  = False
lyr4.visible  = False
lyr6.visible  = False
lyr7.visible  = False
lyr8.visible  = False
lyr9.visible  = False
lyr10.visible = False
lyr11.visible = False
lyr12.visible = False
lyr13.visible = False

# CREATE SELECTION LAYER AND WHERE CLAUSE
arcpy.SelectLayerByAttribute_management(layer,"NEW_SELECTION", st_abbr.format(state))

# ZOOM TO STATE SELECTION THEN CLEAR SELECTION
df.zoomToSelectedFeatures()

# APPLY SYMBOLOGY
arcpy.ApplySymbologyFromLayer_management (lyr6, symlyr3)

# CLEAR SELCTION
arcpy.SelectLayerByAttribute_management(layer, "CLEAR_SELECTION")

# DEFINITION QUERIES
lyr.definitionQuery = st_abbr.format(state)
lyr5.definitionQuery = count_lyr.format(fname)

for layer in arcpy.mapping.ListLayers(mxd):
    if layer.name == "Facial Surgeons":
        layer.visible = True
        layer.definitionQuery = FSurg_lyr.format(state)

print lyr.definitionQuery, lyr3.definitionQuery, lyr4.definitionQuery

# UPDATE MAP ELEMENTS
for elm in arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT"):
    if elm.name == "Title":
        elm.text = "{}".format(spec16)

for elm in arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT"):
    if elm.name == "Subtitle":
        elm.text = "{}".format(fname)
1

I would use Data Driven Pages with your state layer as index layer. Set the data driven pages in the mxd (this must be done manually), then in your script, iterate over a list/dictionnary/tuple of specialties and related text elements/properties to change:

...
mxd = arcpy.mapping.MapDocument(r"C:\mxd.mxd")
...

list = [["spec1", "text1", "lyr1"], 
        ["spec2", "text2", "lyr2"], ...]

## iterate over specialties and related settings
for l in list:
  where = """Specialty = '{}'""".format(l[0]) 
  ## use this as a where clause in a Select Layer By Attribute,
  ## or as definition query for a layer

  elm = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "Title")[0]
  elm.text = l[1]

  lyr = arcpy.mapping.ListLayers(mxd, l[2])[0]
  lyr.visible = True

  mxd.save()

  # export each state map to PNG
  for pageNum in range(1, mxd.dataDrivenPages.pageCount + 1):
    mxd.dataDrivenPages.currentPageID = pageNum
    arcpy.mapping.ExportToPNG(mxd, """r"C:\PNGs\{}_{}.png""".format(l[0], pageNum))
  del mxd
  • I was able to solve this by simply wrapping the state selection for loop inside another loop that iterates through the physician specialty layers. I will at some point need to optimize my script so may need to incorporate data driven pages. Thanks! – Dave Jan 4 '18 at 13:05

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.