1

I want to change the color of my point layer with the ruled based option so that I create blue and red dots based on an expression. Now I get only blue dots. How do I create 2 renderers with a ruled based color?

    layer = iface.activeLayer()

# define some rules: label, expression, color name, (min scale, max scale)
road_rules = (
    ('rood', "kleur = 'red'", 'red', None),
    ('blauw', "kleur" 'blue', 'blue', None)
    
)

# create a new rule-based renderer
symbol = QgsSymbol.defaultSymbol(layer.geometryType())
renderer = QgsRuleBasedRenderer(symbol)

# get the "root" rule
root_rule = renderer.rootRule()

for label, expression, color_name, scale in road_rules:
    # create a clone (i.e. a copy) of the default rule
    rule = root_rule.children()[0].clone()
    # set the label, expression and color
    rule.setLabel(label)
    rule.setFilterExpression(expression)
    rule.symbol().setColor(QColor(color_name))
    # set the scale limits if they have been specified
    if scale is not None:
        rule.setScaleMinDenom(scale[0])
        rule.setScaleMaxDenom(scale[1])
    # append the rule to the list of rules
    root_rule.appendChild(rule)

1 Answer 1

1

You are most of the way there- you have some inconsistent syntax in your rule expressions, and are missing a few lines at the end of your script which removes the original child legend node, sets the renderer to the layer and repaints the layer.

Also the setScaleMinDenom() and setScaleMaxDenom() methods of QgsRuleBasedRenderer.Rule class have changed to:

setMinimumScale() and setMaximumScale().

Try this slightly modified version of your script:

layer = iface.activeLayer()

# define some rules: label, expression, color name, (min scale, max scale)
road_rules = (
    ('rood', "kleur LIKE 'red'", 'red', None),
    ('blauw', "kleur LIKE 'blue'", 'blue', None)
    
)

# create a new rule-based renderer
symbol = QgsSymbol.defaultSymbol(layer.geometryType())
renderer = QgsRuleBasedRenderer(symbol)

# get the "root" rule
root_rule = renderer.rootRule()

for label, expression, color_name, scale in road_rules:
    # create a clone (i.e. a copy) of the default rule
    rule = root_rule.children()[0].clone()
    # set the label, expression and color
    rule.setLabel(label)
    rule.setFilterExpression(expression)
    rule.symbol().setColor(QColor(color_name))
    # set the scale limits if they have been specified
    if scale is not None:
        rule.setMinimumScale(scale[0])
        rule.setMaximumScale(scale[1])
    # append the rule to the list of rules
    root_rule.appendChild(rule)

root_rule.removeChildAt(0)
layer.setRenderer(renderer)
layer.triggerRepaint()

Results on a test point layer:

enter image description here

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.