Select to view content in your preferred language

Labels Still Not Visible after setting lyr.labelClasses[0].showLabels = True

5575
20
Jump to solution
12-24-2013 10:05 AM
JonathanMulder
New Contributor III
Thanks to an earlier reply today, I'm moving along on my script but have encountered another hiccup.

I've set "lyr.showLabels = True".  After looking through some other threads, it looks like I also need to set labelClasses to "showLabels = True".  The script runs with no errors but does not show the labels.  When clicking on layer properties|Labels, it shows that the labelClasses[0].expression DID accept the StateWellNumber field.  But the checkbox for showing labels is not checked.

Is this "par for the course"?  Not a big deal (I can just go in and fill the checkbox), but it would be nice to see the labels come in as the script runs.

Thanks,

Jon Mulder 



LayerFileLocation = "H:\Documents\GIS\HydstraData" LayerName = "WellPoints.lyr" ##Define layer: lyr = arcpy.mapping.Layer(os.path.join(LayerFileLocation,LayerName)) arcpy.AddMessage(lyr) ##Show labels for WellPoints. lyr.supports("LABELCLASSES") lyr.showLabels = True lyr.labelClasses[0].expression =  "StateWellNumber" lyr.labelClasses[0].showLabels = True arcpy.RefreshActiveView()
Tags (2)
0 Kudos
20 Replies
T__WayneWhitley
Frequent Contributor
oh, probably where I took out your other 'if' statement...it'll probably still run with that indention, but if not you can 'unindent' the entire region.  If you don't already know how, if you open the script to edit in IDLE, you can select the line and of course the following lines, then go to the Format menu (I think it is, but you may have to look around...), and I think the item you need is 'Dedent'.  Anyway, try that- it's quick and easy and less error-prone than all the backspacing...good luck.

Wayne


...and about your last question, making print statements in the Python window of ArcMap - once you've defined your variables (mxd, lyr, etc.), you could simply use print:

print str(lyr.supports("SHOWLABELS"))
0 Kudos
JonathanMulder
New Contributor III
This is the result of the script:

=================================================
Executing: UpdateMap
Start Time: Fri Dec 27 09:07:02 2013
Running script UpdateMap...
H:\Documents\GIS\HydstraData\HydstraMeasurementsDeep\GSE_Daily_Contours_20130625_20131015.gdb\WellPoints
H:\Documents\GIS\HydstraData\HydstraMeasurementsDeep\GSE_Daily_Contours_20130625_20131015.gdb\AllContours3D
H:\Documents\GIS\HydstraData\CasedContours.lyr
Layer name: WellPoints
WellPoints supports labeling.
Layer labeling is on?:  False
   Class Name:  Default
    Expression:  [StateWellNumber]
    SQL Query:  
Label class is on?:   True
Layer name: AllContours3D
AllContours3D supports labeling.
Layer labeling is on?:  False
   Class Name:  Default
    Expression:  [ContourDate]
    SQL Query:  
Label class is on?:   True
Completed script UpdateMap...
Succeeded at Fri Dec 27 09:07:04 2013 (Elapsed Time: 1.39 seconds)
===================================================

So, it's saying that the WellPoints layer DOES support labeling, but that the Layer labeling is False.

I kind of thought that the "Wells_lyr.showLabels = True" would make Layer labeling True.

Jon Mulder
0 Kudos
T__WayneWhitley
Frequent Contributor
hmmm, now we're getting somewhere.  I don't have ArcMap open at the moment, but can you try reordering the following statements, so that the showLabels statement is after defining the class labeling - not that it should make a difference, but let's see (and you don't need the 'supports' statement for LABELCLASSES):


##Show labels for WellPoints.
arcpy.AddMessage(Wells_lyr)
Wells_lyr.labelClasses[0].expression =  "\"StateWellNumber\""
Wells_lyr.labelClasses[0].showClassLabels = True
Wells_lyr.showLabels = True


Also, I question the expression feedback you got:

Expression: [StateWellNumber]
0 Kudos
JonathanMulder
New Contributor III
I think I'm getting hung up on the line:

Wells_lyr.labelClasses[0].expression =  "\""StateWellNumber"\""

According to the site you referred me to, [ should be replaced with "\"" and ] should be replaced with "\"".  But when I do that it errors out saying:

==========================================
Executing: UpdateMap
Start Time: Fri Dec 27 09:41:01 2013
Running script UpdateMap...
SyntaxError: invalid syntax (UpdateMxd20131225.py, line 48)
Failed to execute (UpdateMap).
Failed at Fri Dec 27 09:41:01 2013 (Elapsed Time: 0.01 seconds)
==========================================

But, when I use "\"StateWellNumber\"" it does not error out.  Am I missing something here?

Jon Mulder
0 Kudos
T__WayneWhitley
Frequent Contributor
You have too many quotes - the \ character tells Python to interpret the following character as part of the string to pass (and not signify the end of the string), understand?  So when you enter the expression, "\""StateWellNumber"\"", Python is really trying to interpret 3 things (", StateWellNumber, ") that don't make sense (and it's expecting a single string).

So, as a single string (that you said it did not error on, a good thing) it should have been:
"\"StateWellNumber"\"

Which in turn is interpreted by Python as "StateWellNumber" (with the double-quotes).  However, ArcMap itself may not interpret this with its label engine as expected and not return errors --- so do this as a test:

Open the layer properties in ArcMap and enter the expression in the label class as StateWellNumber --- verify the expression (which produces the label?) - I think for file gdbs, either will work, with or without the double-quotes.  When you click verify, if you get an empty text box sample as a result, hello houston that is a failure to launch...

So what I'm getting at here is to use the expression that tests positive in ArcMap as you test interactively...change your code accordingly.  Realize that for multiple classes you must have the labeling 'turned on' at 2 levels -- you can 'see' this from the layer properties as well if you check directly within ArcMap.  There is a 'class level' and at a higher level, the 'layer level'....at the layer level, toggling labeling off turns all class labels off (although still checked 'on' at the class level).

Let me know what your progress is...

Wayne
0 Kudos
JonathanMulder
New Contributor III
Wayne,

Everything seems to work, but still no labels visible.  I've confirmed that "StateWellNumber" is the proper field, and I'm using your syntax for double quotes (now that I understand it more).  In any case, I condensed down my dataset to just two days of contours (ultimately, this will have a time property to view contour changes over time).  Can I send you my geodatabase, layer files, and script?  I tried to attach a zip file here, but I'm not able to do that.  Possibly contact me via e-mail (mulder@water.ca.gov) and I can send you the zip file (which would be better than a bunch of separate files because it would retain the directory structure).

Thanks,

Jon Mulder
California Department of Water Resources
0 Kudos
T__WayneWhitley
Frequent Contributor
Okay, yes I am curious - all testing on my test data worked fine, so I'd like to see what's going on with yours...
If your private message feature of your forum acct is enabled, I'll send you a msg with my email addy.
Otherwise if there's any convenient way for you to clip a sample of the relevant data, you should pkg that up for shipment....either way, but when I send it back likely that's what I would do.

Just checking one more thing, I think you said earlier that you could 'manually' toggle on labels in ArcMap.  Is that still true?...and for successful labeling, what is the expression written to the Layer Properties, Labeling tab, class window text box?  I asked you to check that, but if you don't know what I mean or that checked out okay already, then just send the map, lyr files, gdb, just whatever is needed to make it work.  If you don't clip, then I don't think the contours layer is necessary - I imagine that one is huge and the failure was evident with the wells point layer, correct?  So that one should be sufficient.

...one more thing...I was looking at something else, so how time-sensitive is this when you need it back?

Wayne
0 Kudos
T__WayneWhitley
Frequent Contributor
Jon, I received the data and corrected the script - only where the labeling is concerned for the well points layer.

First of all, the file gdb labeling does indeed use brackets...the field must be referenced - I should've known actually the text I had you insert would actually be interpreted as raw text, i.e. every label would simply be the text, StateWellNumber, lol!  That was my mistake...but not the primary problem.  Your problem was the labels wouldn't turn on.

Just before Jeff's post you made a statement that turns out after further testing to be essentially true:
"Could it be that my "wells_lyr" variable near the bottom of my code does not actually refer to the "AllPoints" layer (i.e. Featureclass) in the map?"

Nice catch - so the fix was to manipulate the labeling before adding the layer to the map.  I don't know if this is a design feature or a bug, but at least there's a relatively simple workaround...I sent you the script pared down to a few lines designed for you to simply load and run in ArcMap to see it in action.  The relevant lines I'll post below:
WellPtsLyrFile = os.path.join(rootPath, 'WellPoints201312271743.lyr') Wells_lyr = arcpy.mapping.Layer(WellPtsLyrFile)  ##Show labels for WellPoints. if Wells_lyr.supports("LABELCLASSES"):     Wells_lyr.labelClasses[0].expression =  "[StateWellNumber]"      ## class labeling is on by default; showClassLabels is optional.     #Wells_lyr.labelClasses[0].showClassLabels = True     Wells_lyr.showLabels = True  arcpy.mapping.AddLayer(df, Wells_lyr, "AUTO_ARRANGE")


Hope that finally clears up any lingering confusion.  Actually the showClassLabels property I can see could be pretty useful, say if you defined multiple label classes in a single layer file, then wanted to run for example multiple PDF exports showing only certain label classes...with them already defined, all you'd have to manage is switching them on/off as needed in a loop to produce your PDF pages.  (Or, say you had multiple data frames - same principle applies, using the same lyr file but managing labeling in various different ways for each data frame.)

Wayne
0 Kudos
JonathanMulder
New Contributor III
Gosh Wayne!

Thanks very much!  Obviously, I was getting buried in the weeds instead of looking at the big picture.  But let me ask a (hopefully) simple question.  This script will be used for running many different groundwater level scenarios from different sets of WellPoints and Contours featureclasses.  I'm thinking that I'd have two layer files that act as templates for the featureclasses.  As I understand your script, it is loading the actual well data that is currently associated with the layer.

After the WellPtsLayerFile is added to the document, is there a way to re-direct the layer reference to another featureclass?

Once again, thanks very much for looking at my script.  And thanks for a quick tutorial on using the ArcMap Python window.  Obviously, the three-day course I took only whetted my appetite.  Now I need to go to a follow-up class with plenty of questions!

Jon Mulder
California Department of Water Resources
0 Kudos
T__WayneWhitley
Frequent Contributor
Sure, and I was stumbling around a bit there too, so glad to contribute and learn something at the same time.

Short answer to your question, I believe you'd use the replaceDataSource method.  The schema would need to be the same for labeling, etc., to work without further manipulation - and I think that's what you mean by using the layer file as a template, so yes that should work (I haven't tested this yet with 10.2).

A sort of one-stop page of info in the webhelp on arcpy properties/methods concerning data sources and such is here:

Updating and fixing data sources with arcpy.mapping (arcpy.mapping)
Desktop » Geoprocessing » ArcPy
http://resources.arcgis.com/en/help/main/10.2/index.html#//00s30000004p000000

At the bottom of that page at the link above is a good very short sample I'll copy below which fits what it sounds like you're doing - with a minor exception I'll note further below--
import arcpy
mxd = arcpy.mapping.MapDocument(r"C:\Project\Project.mxd")
for lyr in arcpy.mapping.ListBrokenDataSources(mxd):
    if lyr.supports("DATASOURCE"):
        if lyr.dataSource == r"C:\Project\Data\Transportation.gdb\MajorRoads":
            lyr.replaceDataSource(r"C:\Project\Data\Transportation.gdb", "FILEGDB_WORKSPACE", "Highways")
            lyr.name = "Highways"
mxd.saveACopy(r"C:\Project\Project2.mxd")
del mxd


Instead of using ListBrokenDataSources above, you'd more likely need to use ListLayers (probably with a wildcard) in order to get a 'handle' on the layer in the map.  (Or, if the layer is not already in the map, use the Layer command on a lyr file as you have done previously to make a layer obj and change its source before adding to the map.)

If any of that doesn't make sense, just let me know....


Enjoy,
Wayne

EDIT:
I didn't test this, but the code could be as simple as this:
# fetches the layer from the map called WellPts from your defined mxd and df
Wells_lyr = arcpy.mapping.ListLayers(mxd, "WellPts", df)[0]

if Wells_lyr.supports("DATASOURCE"):
    # replaces WellPts source with the fc, NewWellPts, in YourFileGeodatabase.gdb
    Wells_lyr.replaceDataSource(r"C:\YourFileGeodatabase.gdb", "FILEGDB_WORKSPACE", "NewWellPts")
0 Kudos