1

I have limited expertise with Python.

I need to create labels based on groups of attributes. I've figured out a clumsy way to accomplish this but it involves 20 different annotation classes / SQL queries / label expressions, and I really hope there is a way to accomplish this more elegantly and efficiently, ideally with just 1 label expression.

My input data (which cannot be altered) is a feature class with 3 relevant fields (which I've made generic here).

  • Codelist - numeric codes
  • Attribute1 - an attribute
  • Attribute2 - a second attribute

Codelist contains 100 numbers. Groups of these numbers require one label - for example codes 1,3,35,7,8 would get the label "Christmas, Attribute1, Attribute2" on 3 separate lines. Codes 2,9,34,100,54,22 would get the label "Easter, Attribute 1, Attribute2" on 3 separate lines. Etc etc.

I can't figure out how to use an SQL-like 'if [CODELIST] in (1,3,35,7,8):' statement in the Python label expression builder.

Is it possible?

Am I approaching this the right way or is my first effort using multiple annotation classes and SQL queries the best way to do this after all?

  • Are the text values associated with each code stored somewhere, or do they need to be part of the code itself? – jpmc26 May 11 '18 at 2:59
  • Also, Attribute1 and Attribute2 are the same for all the codes, right? – jpmc26 May 11 '18 at 3:07
  • The code values are not stored elsewhere, I was planning to just type those in. Attribute1 and Attribute2 are the same type, but not the same value. So the end product would be (a generic example) [HolidayName] [Month] [Year] = Christmas December 2018, Easter April 2019, Victoria Day May 2017 etc etc. Three lines of text, one of those lines made bold. – DavidA May 11 '18 at 12:56
  • @DavidA, please mark the answer which solved your problem. – fatih_dur May 11 '18 at 15:25
3

So, it depends. If you need the labels to look different (one needs to be green text, another large bold black), or if you need to manage label placement properties (one needs to be above a line the other below a line), or if you need to affect label/feature weights and/or label draw order, or if you need to manage any other label settings/properties separately for the different groups, then you will need to use separate label classes with SQL Queries on the classes as you are doing.

That said, if you are wanting to label all of the features essentially the same except for the actual text of the label, you can accomplish that with an advanced label expression as well depicted in @Dan's answer. However, an important note about using the python parser for an advanced label expression where you are looking at numeric values:

From my testing (ArcMap 10.5.1), it appears that the label expression will read all values, INCLUDING numeric ones, as strings. So use essentially what @Dan posted, except you will likely have to modify the `in (...) from what you would expect; possibly use code similar to the following.

def FindLabel ([Codelist],[Attribute1],[Attribute2]):
  if [Codelist] in ('1','3','35','7','8'):
    return 'Christmas\n'+[Attribute1]+'\n'+[Attribute2]
  elif [Codelist] in ('2','9','34','100','54','22'):
    return 'Easter\n'+[Attribute1]+'\n'+[Attribute2]
  elif ...
    return ...
  else:
    return 'No holiday\n'+[Attribute1]+'\n'+[Attribute2]

Note: I included an else: at the end with a return statement after it. You would use that if you wanted to return a specific string when the [Codelist] field doesn't match any the criteria you've previously provided in the above if and elif statements. If you don't need that, you can leave those last 2 lines off.

  • All the labels will be formatted the same so I think this will work well. And thank you for the else statement at the bottom - you predicted what I forgot to mention that certain codes in my list don't require "HolidayName" but just need "Attribute1, Attribute2." I will give this a go and let you know how it works out! Thanks again. – DavidA May 10 '18 at 22:30
  • Oh and if I wanted to add a formatting tag in the return, would I put it outside the square brackets: 'No holiday\n'+[Attribute1]+'\n'+<BOL>[Attribute2]</BOL> or is that no bueno? – DavidA May 10 '18 at 22:37
  • @DavidA it would need to be part of the output string and is not part of any of the field names, so it would be outside the brackets and inside the quotes, ex: 'No holiday\n'+[Attribute1]+'\n<BOL>'+[Attribute2]+'</BOL>'. Otherwise, if it's easier for you to read, see the bottom of @Dan's answer for another good string assembly method, which may look something like "No Holiday\n{}\n<BOL>{}</BOL>".format([Attribute1], [Attribute2]) – John May 11 '18 at 13:54
1

Yes, it's possible. Tick the Advanced option in the Label Expression dialog box.

Then add your labelling conditions in the code block.

In my case, I used the following code block (which you can adapt to your situation).

def FindLabel ( [Report_FC], [Report_Group], [Request_UFI]):
  if [Report_Group] in ('Administration', 'Information'):
    return [Report_FC]
  if [Report_Group] == 'Infrastructure':
    return [Request_UFI] 

enter image description here

To get three attributes back with a new line between each you would use:

return "{}\n{}\n{}".format([Attrib1], [Attrib2], [Attrib3])

or in your case:

return "{}\n{}\n{}".format("Christmas", [Attrib1], [Attrib2])

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.