I've written a plugin which randomly generates fill colours for differing categories. I'm wondering if there's a way to iterate through the category renderer and output the RGB colour as text.

I have so far an example of the creation of the categories:

def styleMap(self):
    categories = []
    for cat in range(0,10):
        symbol = QgsSymbol.defaultSymbol(self.activeLayer.geometryType())
        layer_style = {}
        layer_style['color'] = '%d, %d, %d' % (randrange(0, 256), randrange(0, 256), randrange(0, 256))
        layer_style['outline'] = '#000000'
        symbol_layer = QgsSimpleFillSymbolLayer.create(layer_style)

        # replace default symbol layer with the configured one
        if symbol_layer is not None:
                symbol.changeSymbolLayer(0, symbol_layer)

        # create renderer object
        if cat == 0:
                category = QgsRendererCategory("", symbol, "")
                category = QgsRendererCategory(str(cat+1), symbol, str(cat+1))
        # entry for the list of category items
    renderer = QgsCategorizedSymbolRenderer(self.field_name, categories)

From here I'd like to create a new function which loops through all the features in the layer and returns the colour of the renderer in RGB to save to an attribute file.

So, if self.field_name == 1, return the colour associated with category 1 in text format.

How would one go about iterating through all the category data and accessing the colour information?


You could use something like the following function which gets the categorised values for each symbol as a key and stores this into dictionary with its RGB value. We could then iterate through each feature, extract the RGB since the feature value would match the key in the dictionary and write the RGB values into either a new field or update an existing one.

def get_RGB(self, layer, categoryField, outputField):
    # Create dictionary to hold field values and rgb keys
    colour_dict = {}
    # Define renderer
    renderer = layer.renderer()
    # Only execute for Categorised symbology
    if renderer.type() == "categorizedSymbol":
        # Iterate through the categories
        for cat in renderer.categories():
            # Fetch the RGB values for each category
            rgb = cat.symbol().symbolLayer(0).color().getRgb()
            # Insert info into dictionary
            colour_dict[cat.value()] = str(rgb)
        with edit(layer):
            # Check if outputField exists otherwise create it
            idx = layer.fields().indexFromName(outputField)
            if idx == -1:
                layer.addAttribute(QgsField(outputField, QVariant.String))
            # Iterate through features
            for feat in layer.getFeatures():
                # A category with 'None' value applies to features with NULL values
                # so will get RGB value of this category when checking
                if feat[categoryField] == NULL:
                    feat.setAttribute(feat.fieldNameIndex(outputField), colour_dict[None])
                # Else get RGB value of all other features
                    feat.setAttribute(feat.fieldNameIndex(outputField), colour_dict[feat[categoryField]])

self.get_RGB(iface.activeLayer(), 'someField', 'RGB')

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.