6

I am developing a plugin in PyQGIS 3. Within this plugin, I want to change the symbology of a layer to categorized. I want to categorize based on the column Collecti_2 in PyQGIS 3. This step has been done in the first section of the code. However, when I want to give these produced categories a color based on the fieldName Color the results are colored shapefiles with a legend that contains only blue colors? This is my code:

#add National_BC_produced
layer = QgsVectorLayer(output_folder + 'National_BC_Joined3_' + str(year) + '.shp', "Collection_Systems_" + str(year), "ogr")
QgsProject.instance().addMapLayer(layer)
layer = QgsProject().instance().mapLayersByName('Collection_Systems_' +str(year))[0]

fieldName = 'Collecti_2'
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()

# The "magic" missing part
for index, category in enumerate(renderer.categories()):
    newSymbol = QgsFillSymbol()
    newSymbolLayer = newSymbol.symbolLayers()[0]
    data_defined = QgsProperty.fromField("Color")  # "color" is the name of the field
    newSymbolLayer.setDataDefinedProperty(QgsSymbolLayer.PropertyFillColor, data_defined)  
    newSymbol.appendSymbolLayer(newSymbolLayer)
    renderer.updateCategorySymbol(index, newSymbol)

layer.setRenderer(renderer)
layer.triggerRepaint()

And these are the results:

Legend Shapefile with symbology

How can I create a code which also gives the categories in the legend a same color?

1 Answer 1

6

I have no idea what the problem is. It may be related to setDataDefinedProperty. Instead, I made a dictionary containing {"Type": "Color"} and used setFillColor.

Use this script:

layer = ....

fieldName = 'Collecti_2'
fieldIndex = layer.fields().indexFromName(fieldName)

uvp_set = set([(f["Collecti_2"], f["Color"]) for f in layer.getFeatures()])
uvp_dict = {i[0]: i[1] for i in uvp_set}

categories = {}
for u in uvp_dict:
    symbol = QgsSymbol.defaultSymbol(layer.geometryType())
    category = QgsRendererCategory(u, symbol, str(u))
    categories[u] = category

renderer = QgsCategorizedSymbolRenderer(fieldName, categories.values())
style = QgsStyle().defaultStyle()

for index, [code, category] in enumerate(categories.items()):
    newSymbol = QgsFillSymbol()
    newSymbolLayer = newSymbol.symbolLayers()[0]
    newSymbolLayer.setFillColor(QColor(uvp_dict[code]))
    newSymbol.appendSymbolLayer(newSymbolLayer)
    renderer.updateCategorySymbol(index, newSymbol)

layer.setRenderer(renderer)
layer.triggerRepaint()

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.