3

As you can see in the screenshot, I have a layer with a lot of empty categories (0 features). Is it a way to automatically remove this categories from TOC? To do it manually, it is complicated cause I have a lot of empty categories.

I don't want to reclassified, cause I don't want to lose my symbology! enter image description here

EDIT @Mayo: Are you sure it works in this case? See second capture. In case, value is the same as legend, it works... but in the capture, you'll see it is different. And after using the python code, the category is empty. enter image description here

4
  • 1
    Do you want to remove permanently these items ? Or just "dynamically" hide them like the answer below ?
    – etrimaille
    Aug 11 at 14:33
  • I think you can use the standard Windows selection methods (e.g. holding the Ctrl key to click multiple individual categories, shift to click a range from a starting point) to highlight all the categories you don't want, and then hitting the minus sign to delete them. Sure it's manual but it's pretty easy.
    – John
    Aug 11 at 14:47
  • @johns: but when you have more than 50 categories that are empty, I try to find a more "easy" solution! And as you know, in the symbology panel, you don't find the "count value"... so it is not easy when you have a lot of value!
    – katagena
    Aug 11 at 15:56
  • @etrimaille: I want them to disappeared "permanently" from the TOC.
    – katagena
    Aug 11 at 15:59

2 Answers 2

4

Paste this script in the python console, select the layer where you want to remove the nonexistent categories and click run.

layer = iface.activeLayer() # get the active layer
renderer = layer.renderer().clone() # get layer renderer
exp = QgsExpression(renderer.classAttribute()) # get the category expression
field_map = []
# evaluate the expression for each feature and store results in a list
for feature in layer.getFeatures():
    exp_context = QgsExpressionContext()
    exp_context.setFeature(feature)
    field_map.append(exp.evaluate(exp_context))
    
categories = renderer.categories()
for cat in categories.copy():
    if not field_map.count(cat.value()): # if there's no feature with this value
        renderer.deleteCategory(renderer.categoryIndexForValue(cat.value())) # remove the category
layer.setRenderer(renderer)
10
  • Almost... but it doesn't work if the value (for categories) is not the same as the legend. For exemple the value 1 is forest, the value 2 is grass, etc. After using the python code, the symbology is gone.
    – katagena
    Aug 11 at 15:28
  • See my update above.
    – katagena
    Aug 11 at 15:40
  • I don’t understand. I can’t see the relation with « show feature count »?!?
    – katagena
    Aug 11 at 16:30
  • 1
    Be careful @katagena the legend might not be updated visually after the script. After the script, reopen your layer properties and close it. It will refresh the legend.
    – etrimaille
    Aug 11 at 17:30
  • 1
    @Mayo: I found something strange... As you can see on my screen record, the attribut I used for category is a "real". If I use to_string("CODETYP"), it works?!? With to_int(to_string("CODETYP")), it doesn't!
    – katagena
    Aug 16 at 14:07
3

You can use the filter by map content in the table of content.

enter image description here

1
  • The problem is this solution acts on all the layers... and it is not desired!
    – katagena
    Aug 11 at 16:00

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.