0

i have a column in my attribute table called 'Color' and 'Line' where I store rgb color codes and line thickness values (in map units) to give my layer elements a color and thickness. You can do it manually style => layerproperties.However I would like to use pyqgis to directly plot it properly.

4
  • Why use python when you can do this with data defined override (rectangles with tiny triangles next to every field where you may enter a value).
    – Erik
    Aug 14, 2020 at 14:06
  • I have over 250 datasets which need to be implemented into various projects and it would simply be efficient to directly have the proper colors by running my script which also builds up the layers to begin with.
    – Tobias
    Aug 14, 2020 at 14:08
  • Well, then I suggest you provide relevant parts of your script and show us, what you tried so far? There are some solutions around here (e.g. gis.stackexchange.com/questions/31789/…) - while some of them might be outdated.
    – Erik
    Aug 14, 2020 at 14:13
  • My question is related to my previous question: gis.stackexchange.com/questions/371437/… I managed to get the RGB codes into the attribute table. Now I simply search for a way to apply them automatically. With symbol.setColor(QColor.fromRgb(0, 0, 0)), I can add 1 color for all layers but I would like this command to take the RGB from my attribute table. Cheers
    – Tobias
    Aug 14, 2020 at 14:23

2 Answers 2

2

Example for RGB column. Most of it from the answer to Applying catgorized symbol to each feature using PyQGIS, but with layer.getFeatures to read colors from attribute table. I have QGIS 3 so I had to change some of the syntax from pyqgis2 to 3, for example QgsSymbolV2 to QgsSymbol

layer = iface.activeLayer()
category_column = 'kommunnamn'
rgb_column = 'rgb'

color = {f[category_column]:f[rgb_column] for f in layer.getFeatures()} #Store all colors in a dictionary

fni = layer.fields().indexFromName(category_column)
unique_values = list(layer.dataProvider().uniqueValues(fni))
categories = []
for unique_value in unique_values:
    symbol = QgsSymbol.defaultSymbol(layer.geometryType())
    layer_style = {}
    layer_style['color'] = color[unique_value] #Read colors from the dictionary
    layer_style['outline'] = '#000000'
    symbol_layer = QgsSimpleFillSymbolLayer.create(layer_style)
    symbol.changeSymbolLayer(0, symbol_layer)
    category = QgsRendererCategory(unique_value, symbol, str(unique_value))
    categories.append(category)

renderer = QgsCategorizedSymbolRenderer(category_column, categories)
layer.setRenderer(renderer)
layer.triggerRepaint()

enter image description here

1
  • I have the current problem that symbol.changeSymbolLayer(0, symbol_layer) gives me false as a response. As a result, the default symbol layer is not replaced with the configured one.
    – Tobias
    Aug 18, 2020 at 11:07
2

I've set a minimum project available at https://labs.webgeodatavore.com/partage/sample-datadefined-colors.zip. Unzip it. Open the qgs file with QGIS and use the following in the Python QGIS console

layer = iface.activeLayer()

# For color defined in attribute column
layer.renderer().symbol().symbolLayer(0).dataDefinedProperties().property(QgsSymbolLayer.PropertyFillColor).setExpressionString("\"rgb\" || ',255'")

layer.renderer().symbol().symbolLayer(0).dataDefinedProperties().property(QgsSymbolLayer.PropertyFillColor).setActive(True)

# For thickness in attribute column
layer.renderer().symbol().symbolLayer(0).dataDefinedProperties().property(QgsSymbolLayer.PropertyStrokeWidth).setExpressionString("\"thickness\"")

layer.renderer().symbol().symbolLayer(0).dataDefinedProperties().property(QgsSymbolLayer.PropertyStrokeWidth).setActive(True)

# Refresh rendering of the layer
layer.triggerRepaint()

You will just need to use the same recipe by looping on your various layers.

Unrelated to usage with PyQGIS but to choose the approach that "fit", the main drawback using data defined properties if that you don't get a "right" legend but you will be able to manage as many colors as you want. The other approach mentioned with QgsCategorizedSymbolRenderer is better for legend as long as you don't have hundred or thousand of categories (because predictable).

1
  • I try to rewrite it into qgis 2.8.8 but I get the Error: QgsSimpleFillSymbolLayerV2' object has no attribute 'dataDefinedProperties'. Does anoyone know what I need to change to make it run in 2.8.8?
    – Tobias
    Aug 17, 2020 at 10:12

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.