10

How to drive symbol levels based on an attribute or data element such as area in a QGIS layer? How to set data-driven rendering order?

We have a set of boundaries that include very large and very small sizes. Manually setting the symbol level to the known order is ok for a single map, but when dozens of maps are to be made (atlas), driving the symbol levels based on an attribute or data driven expression would be valuable.

1
  • As symbol layers, when activated, are drawn in order for the whole layer, I can't really understand how to drive them with a data element such as area. Sep 16 at 11:15
7

The answer is Yes No.

EDIT

As @Babel pointed it out to me, Symbol levels are a vector layer symbology option to choose the order of symbol layers, see here the official documentation.

QGIS Symbol levels

So the answer is no, see this QGIS Project GitHub issue, opened in 2013, still open : https://github.com/qgis/QGIS/issues/17276.


Here the old answer where I believed that the symbol level was the size of the outline for boundaries for example :

  • For a standard order: if you want your border width to go from 1 to 5, with 5 features, each feature will have an integer width. I insist on the standard because if you have 4 small features and 1 big, the biggest of the 4 small features will have a width of 4.

Here is the expression:

with_variable('sorted_array_by_area', array_agg($id, order_by:=$area),
array_find(@sorted_array_by_area, $id) / array_length(@sorted_array_by_area)
)

The result here is a percentage going from 1/features count to 1. You can reverse this percentage by substracting the expression from 1:

with_variable('sorted_array_by_area', array_agg($id, order_by:=$area),
(1 - array_find(@sorted_array_by_area, $id) / array_length(@sorted_array_by_area))
)

You can adjust the maximum value by multiplying it by this maximum value.

  • For a non-standard order, value dependent: in the previous example, the 4 smallest features will have small values and the big one the max.

Here is the expression:

with_variable('area_array', array_agg($area),
($area - array_min(@area_array)) / (array_max(@area_array) - array_min(@area_array))
)

As with the standard expression, as it returns a percentage, you can reverse the order with 1 - expression.

And if you want to set a maximum value: expression * maximum_value


S̲u̲m̲m̲a̲r̲y̲ T̲a̲b̲l̲e̲

Area value : 2 3 4 7 18
Index in a sorted array by area 0 1 2 3 4
Standard Method : index / array length 1 / 5 = 0.2 0.4 0.6 0.8 1
Standard Method with a maximum value of 5 0.2 * 5 = 1 2 3 4 5
Non-Standard Method : (area - min area) / (max area - min area) 0 (3 - 2) / (18 - 2) = 0.0625 0.125 0.3125 1
Non-Standard Method with a maximum value of 5 0 0.3125 0.375 1.25 5
7
  • 1
    I'm not sure if that answers the question. I don't think the question is about border width, but about rendering order of symbol layers. In my symbol levels dialog, I can't find any place where I could introduce any expression, see this screeshot of several buffers (each a separate symbol layer created with Geometry generator) around a polygon: i.stack.imgur.com/8pgF5.png - fields accept only integer numbers as inputs, no decimals, no characters. See also docs.qgis.org/3.16/en/docs/user_manual/working_with_vector/…
    – Babel
    Sep 14 at 19:16
  • Oh ... I misunderstood the question. Sep 14 at 19:20
  • Never mind: still a great answer (even if to another question...) ;-)
    – Babel
    Sep 14 at 19:21
  • 1
    The question is about rendering order of symbol layers. Babel understood this question correctly.
    – KVO
    Sep 14 at 21:04
  • 1
    I answered in the first part of the answer, there is, for the moment, no solution. I will take a look at PyQGIS, maybe the API can order symbol layers. Sep 15 at 6:59
2
+50

Use Control feature rendering order*?

while not at the same technical depth as @J. Monicolo's answer, a workaround (which is not exactly as sporting a full fledge feature-based Symbol levels), is to enable Control feature rendering order, which support cascading rules:

enter image description here

This of course only takes in consideration features within the same layer, but could be useful for some users.

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.