I want my labels to fit nicely within polygons.

Based on this answer to Creating multiline labels in QGIS, I discovered the power of the wordwrap function in QGIS to make labels. However, I'm confused as to how I could specify a minimum AND a maximum length for wrapping: I'd like no line to be longer than say 13 characters, but I also don't want any line to only have 3 characters. Merely nesting the functions didn't work out for me

wordwrap( wordwrap( title(SITE_NAME) , -3), 13)

So I would like this label to fit someone nicely within its polygon
enter image description here

But if I only use the simple wordwrap it looks ridiculous.
enter image description here

And if I try to build an expression for wordwrap, e.g. wordwrap( title("SITE_NAME") , -3), the "output preview" shows

A. Loconte

But the result is still the first image above.

But if I instead put wordwrap( title("SITE_NAME") , -3) in the Label With box (and make sure to disable all wordwrap functions. I get:
enter image description here

  • Please provide an example of how you want the strings to display.
    – kttii
    Jul 11, 2016 at 13:43
  • @kttii, I'm beginning to think there might be a bug somewhere.
    – raphael
    Jul 12, 2016 at 17:56
  • I'm not having the same issue with 32-bit 2.14.2-Essen... wordwrap( title("SITE_NAME") , -3) works for me in the Expression dialog and Label With.
    – kttii
    Jul 12, 2016 at 18:30
  • Weird, I'm using 64-bit.
    – raphael
    Jul 12, 2016 at 18:55

1 Answer 1


From the help section for wordwrap()

If wrap_length is positive the number represents the ideal maximum number of characters to wrap

The key word being ideal ... wordwrap() wont break a 15 char word down at the 13th character.

EDIT: The function below needs further refinement for the sample string provided.

'Anthony A. Loconte Memorial Skating Rink'

This function will inject a specified delimiter at the max number specified:

from qgis.core import *
from qgis.gui import *

@qgsfunction(args='auto', group='Custom')
def MaxWrap(inField, maxn, delim, feature, parent):
    return delim.join([inField[i:i+maxn] for i in range(0, len(inField), maxn)])

Then use wordwrap with the same delimiter and your minimum:

wordwrap(maxwrap( SITE_NAME, 13, '^-^'), -3, '^-^')
  • I wasn't looking for an exact split, more that I wanted each line to be between 3-13 characters, will update question soon
    – raphael
    Jul 8, 2016 at 21:34
  • @raphael Did you try the function? I tested it and it seems to me to do what you are asking.
    – kttii
    Jul 11, 2016 at 13:03

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.