2

I am trying to create a categorization by symbols I have reviewed this address but I failed to adapt it Apply symbol to each feature (Categorized symbol)

I need each point to be different according to the field. For example:

VALVULA 
0..............circle   
Aire...........triangle
0..............circle
Mariposa.......star
0..............circle
Alivio.........square
Aire...........triangle
0..............circle
Mariposa.......star
0..............circle
Alivio.........square

# Modifying simple symbol
layer6.renderer().symbol().setSize(2.5)
layer6.renderer().symbol().setColor(QColor("blue"))
layer6.renderer().symbol().symbolLayer(0).setShape(QgsSimpleMarkerSymbolLayerBase.Star)
layer6.triggerRepaint()
iface.layerTreeView().refreshLayerSymbology(layer6.id())

enter image description here

I only have this and it only works for me to change all the nodes of a layer.

Can you help me?

1

You could use a rule based renderer.

I have partially based this answer on another answer here by @Joseph). I have tried this solution on a test layer and it works well:

Note: The second item in each nested list of rules is the filter expression for each rule. From your question I assume that your field which contains these values is called "VALVULA". If this is not the case you will have to change the expressions accordingly. Otherwise this should work fine on your layer.

# Get layer object
layer6 = QgsProject().instance().mapLayersByName('Layer_Name')[0] #Change to your layer name

symbol = QgsSymbol.defaultSymbol(layer6.geometryType())
renderer = QgsRuleBasedRenderer(symbol)


rules = [['0', """"VALVULA" LIKE '0'""", QgsSimpleMarkerSymbolLayerBase.Circle, 'Yellow'],
        ['Aire', """"VALVULA" LIKE 'Aire'""", QgsSimpleMarkerSymbolLayerBase.Triangle, 'Blue'],
        ['Mariposa', """"VALVULA" LIKE 'Mariposa'""", QgsSimpleMarkerSymbolLayerBase.Star, 'Red'],
        ['Alivio', """"VALVULA" LIKE 'Alivio'""", QgsSimpleMarkerSymbolLayerBase.Square, 'Green']]


def rule_based_symbology(layer, renderer, label, expression, symbol, shape, color):
    root_rule = renderer.rootRule()
    rule = root_rule.children()[0].clone()
    rule.setLabel(label)
    rule.setFilterExpression(expression)
    rule.symbol().symbolLayer(0).setShape(shape)
    rule.symbol().setColor(QColor(color))
    root_rule.appendChild(rule)
    layer.setRenderer(renderer)
    layer.triggerRepaint()

for rule in rules:
    rule_based_symbology(layer6, renderer, rule[0], rule[1], symbol, rule[2], rule[3])

renderer.rootRule().removeChildAt(0)
iface.layerTreeView().refreshLayerSymbology(layer6.id())

Result:

enter image description here

Edit: If you wish to collapse the legend nodes for the layer symbology categories:

layer_node = QgsProject().instance().layerTreeRoot().findLayer(layer6.id())
layer_node.setExpanded(False) #or True to expand again
| improve this answer | |
1

They key part is to create a dictionary which holds all the symbology properties that you are interested in such as the field value, colour, label and shape. Once this is done, you create a list to store these properties which is then fed into the QgsCategorizedSymbolRenderer and then set your expression and apply the renderer.


So you could try something like the following:

# Get active layer
layer = iface.activeLayer()
# Define shape class
shape = QgsSimpleMarkerSymbolLayerBase
# Create dictionary to store field value, colour, label and shape
land_class = {
    '0': (QColor("yellow"), '0', shape.Circle),
    'Aire': (QColor("blue"), 'Aire', shape.Triangle),
    'Alivio': (QColor("green"), 'Alivio', shape.Diamond),
    'Mariposa': (QColor("red"), 'Mariposa', shape.Star),
}
# Create list to store symbology properties
categories = []
# Iterate through the dictionary
for classes, (colour, label, shape) in land_class.items():
    # Define symbol based on layer's geometry
    symbol = QgsSymbol.defaultSymbol(layer.geometryType())
    # Set shape
    symbol.symbolLayer(0).setShape(shape)
    # Set colour
    symbol.setColor(QColor(colour))
    # Set the renderer properties
    category = QgsRendererCategory(classes, symbol, label, shape)
    categories.append(category)

# Field name
expression = 'VALVULA'
# Set the categorized renderer
renderer = QgsCategorizedSymbolRenderer(expression, categories)
layer.setRenderer(renderer)
# Refresh layer
layer.triggerRepaint()
| improve this answer | |
  • Thank you very much friend works perfect. A small query When categorizing a layer it shows the categories (it expands). Which expression can I use to get it? Thank you – Jose Manolo Barahona Oct 31 '19 at 19:57
  • 1
    @JoseManoloBarahona - I believe Ben W has answered that in his solution :) – Joseph Nov 1 '19 at 11:33

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.