Using QGIS's permimeter-based labeling, what is the best way to arrange multiple different labels along a line so that they are visually spaced apart, instead of clustering together?

Example image

In my example, I am labeling the border between the USA and Canada, so I have a separate label for each nation, one placed above and one below the line (or left and right, depending on orientation); these should appear in pairs. I also have labels for the province above the line and the county below it; these don't have to be paired (and I don't need a label for the state below the line).

The county labels are always a separate layer. For the other labels, I've tried:

  • US and Canada on one layer, province on another layer (shown here)
  • US and Canada on one feature, province on another feature in the same layer
  • US, Canada and province as three separate labels on one feature

All of these produce similar results, where the labels for US/Canada are bunched together with the province or county label. How can I get the different labels to appear a good distance apart using perimeter labeling?

  • A technique that have used in the past was to create polygons that are invisible to user [no fill/line weight] that were used to only place the text within them. The term we used was 'region mask' this was used for project with National Geographic, this works better for mountain ranges etc but this method can be used for borders and provinces/states
    – Mapperz
    Commented May 3, 2017 at 15:37
  • Well, I thought of breaking the boundary line into separate segments, each of which would be labeled with either US/Canada or the province name, in alternating order. But then, if my current map extent doesn't include one of the segments, that label won't appear in the current view. However, I have another idea that I will try next…
    – Nathan
    Commented May 3, 2017 at 16:24
  • See my new example below for this idea…
    – Nathan
    Commented May 3, 2017 at 18:08
  • How about adding another line layer dedicated to labels? (Manually digitizing a short invisible (No Pen) line where you want to put labels.)
    – Kazuhito
    Commented May 3, 2017 at 18:28
  • The line layers are already dedicated to labels (the cartographic boundary line you see here is yet another separate layer) and use No Pen styling for their features. The problem with digitizing short lines is that they will only be labeled if they appear in the current map extent, and I want QGIS to be able to choose any position along the boundary, wherever I may pan and zoom the view. I just want it to choose a placement that isn't near another label. So, my overlapping segment method grew out of the idea of short segments.
    – Nathan
    Commented May 3, 2017 at 19:06

2 Answers 2


This is a solution I found to be partially successful:

Example image

Here, the nation labels are in one layer and the province labels in another. In the province layer, I've split the line into segments at each intersecting county boundary (the "Clinton/Franklin" line in this image). In the nation layer, I've split the line at the mid-point of each province segment, but not at the county boundary. This way, the entire line is covered by alternating, but also overlapping, segments. QGIS tends to choose different labeling points for these segments; it's not perfect, but much better. For the nation labels, I've also set the maximum number of labels displayed to 1 so that the same names do not repeat.

Disadvantages to this method are:

  • It doesn't work as you zoom in, because both overlapping segments will fill the entire extent, so QGIS will again cluster the labels at the center of the map view. Splitting the segments into shorter lengths would solve this, but would result in too many labels displayed at lower zoom levels.
  • I would actually prefer not to repeat the province labels, but I cannot set the maximum to 1 because in some views two provinces (or states) will be visible. I also cannot merge the linestrings to avoid repeats, because that negates the purpose of splitting into segments. I wish I could set the maximum number of identical labels to 1, while still allowing repeats of labels that are different.

If I have understood, you don't mind the pairing of the labels but want to avoid bunching where you have country and province labels. To avoid this, you can put the country labels in one layer and the provinces in another. In the country layer, set the labeling priority to max and use a little formula in the label to add white space either side of the name something like this:

'         '   || "country"  ||  '        '

This will force the province labels to avoid the country labels by at least the amount of white space you add either side. Yes, this is crude, but can be fairly effective.

  • Interesting, I will try that as well. I actually found I would prefer not to pair the province labels with the counties; I'd rather have each unique province name appear only once. But the pairing is still better than the clustering.
    – Nathan
    Commented May 3, 2017 at 18:13
  • This technique seems to work well as part of a combination of all the methods mentioned so far in this thread. I found that the whitespace method, on its own, works reasonably well but gives less predictable results than my overlapping segments method, and it actually tends to break up the pairs of US/Canada labels. However, it is much better at avoiding duplicate labels because it allows me to merge the linestrings.
    – Nathan
    Commented May 3, 2017 at 20:13
  • Another disadvantage is that, when using curved labels, the whitespace characters count towards the angle limit, and so more labels are suppressed than if there were no spaces. However, I can overcome this by using conditional expressions or data-defined labeling to apply whitespace only to those features that need it (or by increasing the angle threshold).
    – Nathan
    Commented May 3, 2017 at 20:16

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.