In the [print] Layout Composer in QGIS 3.18.1 I am trying to filter the legend styles displayed for an item that is a polygon layer styled by the "categorised renderer" by the min, max and median values displayed within the current view of the linked map in the layout.

What I have:

Generated from the "categorised renderer" there is a different shade of purple for each season since ~1950 for each polygon in the layer.

When I use the "only show items inside linked map" checkbox in the legend there is now a subset of the ~70 years coloured purples since 1950 that are within/intersect the linked layout map.

However there are still say 20 entries, which makes for an overly large legend.

Entry shown for every season intersecting the linked map

What I want:

I want to just show in the legend the min, max and median year entries as a subset of those within the linked map (not the entire layer) so that the result is just 3 lines in the legend (or 3 shades of purple labelled with the oldest, most recent and middle of the subset season).

Showing only Min, Median, Max values

What I've tried:

I know how to use the "Filter Expression" button (bottom right of the Legend Items list) to filter for some expressions, but not for the one desired and described above.

For example I can use right("SEASON" ,1) IN ('0','2','4','6','8') to only return entries that end in those numbers, and it works.

I can also see that if I use minimum("SEASON") the "Preview" returns the oldest record in the dataset, but because the oldest record is not within my current linked layout map, nothing is shown in the legend.

I suspect I need an expression that applies something like minimum("SEASON") to just those polygons that intersect my linked map, so I can use something like: "SEASON" = minimum("SEASON") OR "SEASON" = maximum("SEASON") OR "SEASON" = median("SEASON")

Is this the case, is it possible, what is the correct expression, or is there another or better way I should do this?

  • Make a polygon layer of the same extent as your layout. Then include a test for intersection between your polygons and this layer in your expression. – wingnut Apr 21 at 7:23
  1. Make a rectangular polygon the same extent as your layout. I called mine 'limits'

  2. Copy your polygons layer to a new layer, and create a new attribute 'legend' using the attribute calculator. I used this expression:

    overlay_intersects( 'limits')

    Then set a query on this layer to:


    Save changes

  3. You should only see the relevant polygons, but the legend is still too long:

enter image description here

  1. In the legend expression editor, I used this expression to limit the display to the 3 items required:

    (_max = minimum(_max) OR _max = maximum(_max) or _max=median(_max)) 
  2. This changed the legend display to this:

enter image description here

  1. Compare to the original full layer, which has the global min/max/median (not what you want):

enter image description here

Hope that helps.

  • Thank you very much for your answer wingnut. I am trying to work my way through it now ... except (forgive my limited capacities!) ... I am stuck on point 1 (ha, doh)! How do I "Make a rectangular polygon the same extent as your layout." ? (for a layout with an atlas with many maps) – guestagain Apr 21 at 9:09
  • If the extents of the pages of your atlas is defined by polygons, then just use those. – wingnut Apr 21 at 12:59

Your Answer

