3

In a vector layer is it possible to tune up/scripting the style columns attributes to map "Label" column to a specific attribute field/column instead of being populated with same content as the "Value" column? I'm working on QGIS 2.14.

We have symbology by categories and symbols in a XML created based on a key field ("ID_UCF" [type integer]) which is used to classify the style attributes - match to symbols from file - but this way we have the legend of the map taking the "ID_UCF" codes as symbol labels and we need those labels as a description of those codes. This description/text is given by a column present in the attribute table of the label ("DSCR_UCF" [type text]).

How can we change the content of style column "Label" - in this case "Legend" to assume the descriptions?

We have been looking at qgis.core such as rendererV2 class but could not find how to deal with the issue.

enter image description here

7
  • 1
    I'm not sure what exactly you are trying to do. Wouldn't you be able to just categorize by the column that contains the description of the code? That would make both the value and legend to be the description of the code rather than the code. Is there something specific you are trying to do by having the Value column be the code and the legend being the description?
    – TJR
    Mar 13, 2017 at 15:23
  • ID_UCF contains codes and is the key field of our model. We have a style file which is used to match symbols and it runs by that key field. There is a field DSCR_UCF (txt type field). This should populate the field "Legend" so it makes sense to be shown in the map legend instead of the codes. Categorizing classes and matching the symbolization by DSCR_UCF does not work. Mar 13, 2017 at 15:45
  • So you have an xml file that matches ID_UCF to the symbol that needs to be displayed using Advanced -> Match to symbols from file, and you can't change that xml file or get it to match based on DSCR_UCF, so the category column has to be ID_UCF to match the symbology correctly, but you want Legend to be the description which is another attribute column in your layer DSCR_UCF?
    – TJR
    Mar 13, 2017 at 15:58
  • Exactly @TJRockefeller the description is the column "DSCR_UCF" of the layer attribute table. Mar 13, 2017 at 16:03
  • At least it's clear now what needs to be done, but sadly I don't know of anything to do that automatically. My only suggestion is to try changing your xml file so that it can match based on DSCR_UCF, but it sounds like you have at least briefly tried that already.
    – TJR
    Mar 13, 2017 at 16:12

1 Answer 1

1

Hoping I have understood well your issue, you may set the text from a specified field as Legend by directly creating the categorized style.

Assuming to start from this self-explanatory Attribute Table:

enter image description here

you may assign the "DSCR_UCF" field as Legend for the "ID_UCF" values using the following code from the Python Console:

from PyQt4.QtGui import *
import random

layer = iface.activeLayer()

my_dict = {}
for feat in layer.getFeatures(): #iterate over the features for defining the lookup: value -> (color, label) 
    if feat["ID_UCF"] not in my_dict.keys():
        color = QColor.fromRgb(random.randint(0,255),random.randint(0,255),random.randint(0,255)) #assign a random color
        my_dict[feat["ID_UCF"]] = (color.name(), feat["DSCR_UCF"]) #lookup: value -> (color, label) 
    else: # go to the next feature since the label is already stored
        continue

# Create a category for each item in my_dict
categories = []
for value, (color_name, label) in my_dict.items():
    symbol = QgsSymbolV2.defaultSymbol(layer.geometryType())
    symbol.setColor(QColor(color_name))
    category = QgsRendererCategoryV2(value, symbol, label)
    categories.append(category)

# Create the render and assign it to the layer
renderer = QgsCategorizedSymbolRendererV2("ID_UCF", categories)
layer.setRendererV2(renderer)
layer.triggerRepaint()

You will get this result:

enter image description here

EDIT

If you want to keep the original colors unchanged, you may run the following code (assuming you previously assigned a custom categorized renderer with custom colors):

from PyQt4.QtGui import *

layer = iface.activeLayer()
f_index = layer.dataProvider().fieldNameIndex('ID_UCF')
unique_values = layer.uniqueValues(f_index)
rend = layer.rendererV2()
colors = [symb.color().name() for symb in rend.symbols()]  
diz = dict(zip(unique_values, colors))

my_dict = {}
for feat in layer.getFeatures(): #iterate over the features for defining the lookup: value -> (color, label) 
    if feat["ID_UCF"] not in my_dict.keys():
        val = [diz[feat["ID_UCF"]]]
        val.append(feat["DSCR_UCF"])
        my_dict[feat["ID_UCF"]] = tuple(val) #lookup: value -> (color, label) 
    else: # go to the next feature since the label is already stored
        continue

# Create a category for each item in my_dict
categories = []
for value, (color_name, label) in sorted(my_dict.items()):
    symbol = QgsSymbolV2.defaultSymbol(layer.geometryType())
    symbol.setColor(QColor(color_name))
    category = QgsRendererCategoryV2(value, symbol, label)
    categories.append(category)

# Create the render and assign it to the layer
renderer = QgsCategorizedSymbolRendererV2("ID_UCF", categories)
layer.setRendererV2(renderer)
layer.triggerRepaint()
11
  • Sweet automation @mgri it would be possible to call the xml containing the symbols configuration instead of using the random module? Mar 24, 2017 at 10:02
  • Is the color stored in a field in the Attribute Table?
    – mgri
    Mar 24, 2017 at 10:16
  • Color is a tag stored in the xml file - check it style sample Mar 24, 2017 at 10:52
  • @AbreuFreire So, it is already stored on your layer and you want to leave it unchanged? Or you want to set it by referring to an external source?
    – mgri
    Mar 24, 2017 at 11:43
  • 1
    That is right @mgri my question was mostly about automate the fill up of Legend with field values (IDE_UCF); you gave me a good support!! I made another stage of the question asking if was possible in the same scripting operation to call a xml file for the symbols; will ask about this then. Thanks :) Mar 27, 2017 at 10:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.