2

I have polygon layer containing overlapping features (service areas for several years) and I want their symbology to

  1. use a color ramp in QgsCategorizedSymbolRenderer applied for each year
  2. use a transparent fill and apply their former fill color to the outline.

For the first part I successfully use this code:

categories=[]
for u in layer.uniqueValues(fieldIndex):
    symbol = QgsSymbol.defaultSymbol(layer.geometryType())
    category = QgsRendererCategory(u, symbol, str(u))
    categories.append(category)

renderer = QgsCategorizedSymbolRenderer("year",categories)
style = QgsStyle().defaultStyle()
ramp = style.colorRamp('Greens')
renderer.updateColorRamp(ramp)
layer.setRenderer(renderer)
layer.triggerRepaint()

How do I get each symbol's fill color after having applied the color ramp in order to make it the outline color for each symbol according to the ramp's gradient? Could there be a way to do so in the loop beforehand and then apply the ramp directly on the outlines?

Sidenote: I am really puzzled that using a feature's outline for symbology apparently requires some tinkering everytime...

2

You can use below recipe

layer = iface.activeLayer()
fieldName = 'ADM0_A3' # Change
fieldIndex = layer.fields().indexFromName(fieldName)
categories = []
for u in layer.uniqueValues(fieldIndex):
    symbol = QgsSymbol.defaultSymbol(layer.geometryType())
    category = QgsRendererCategory(u, symbol, str(u))
    categories.append(category)

renderer = QgsCategorizedSymbolRenderer(fieldName, categories)
style = QgsStyle().defaultStyle()
ramp = style.colorRamp('Greens')
renderer.updateColorRamp(ramp)

# The "magic" missing part
for index, category in enumerate(renderer.categories()):
    newSymbol = QgsFillSymbol()
    newSymbolLayer = newSymbol.symbolLayer(0)
    newSymbolLayer.setStrokeColor(category.symbol().symbolLayer(0).fillColor())
    newSymbolLayer.setBrushStyle(Qt.NoBrush)
    newSymbol.appendSymbolLayer(newSymbolLayer)
    renderer.updateCategorySymbol(index, newSymbol)

# Alternate solution (commented) using properties in QgsFillSymbol.createSimple
# (you need to look in keys from the qgs file, otherwise impossible to guess)
# for index, category in enumerate(renderer.categories()):
#     newSymbol = QgsFillSymbol.createSimple({
#       'style': 'no',
#       'outline_color': category.symbol().symbolLayer(0).fillColor().name()
#     })
#     renderer.updateCategorySymbol(index, newSymbol)

layer.setRenderer(renderer)
layer.triggerRepaint()
| improve this answer | |

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.