I'm trying to customize the rendering of a point layer in QGIS using python. Thus I have written a renderer class as explained in the documentation (http://www.qgis.org/pyqgis-cookbook/vector.html#creating-custom-renderers).

From what I have understood, I should define which symbol to render for each feature using the method 'symbolForFeature'. My problem is that inside this function when I try to get the attribute map using 'attributeMap' I always get an empty dictionary.

class MyRenderer(QgsFeatureRendererV2):
  def __init__(self, syms=None):
    QgsFeatureRendererV2.__init__(self, "MyRenderer")
    self.syms = syms if syms else [ QgsSymbolV2.defaultSymbol(QGis.Point), QgsSymbolV2.defaultSymbol(QGis.Point) ]

  def symbolForFeature(self, feature):
    attrs = feature.attributeMap()
    # attrs[0] should be the id
    if attrs[0] > 10 :
      return self.syms[0]
    else :
      return self.syms[1]

  def startRender(self, context, vlayer):
    for s in self.syms:

  def stopRender(self, context):
    for s in self.syms:

  def usedAttributes(self):
    return []

  def clone(self):
    return MyRenderer(self.syms)

When I use this class, I get the error: 'KeyError: 0', simply because attrs is empty.

However, the other methods of the feature object seem to provide the expected results, for instance when I replace 'attrs[0]' by 'feature.id()' everything works fine.

What am I doing wrong?

  • Are you sure that is the problem? Your return statement after "else" has an error. It should be self.syms[1], not sel.syms[1].
    – gsherman
    Mar 14, 2013 at 14:59
  • Thanks for spotting the error, I corrected it. But the problem is still there...
    – Florian
    Mar 15, 2013 at 8:56

2 Answers 2


Your clone statement needs to return a copy of itself:

  def clone(self):
    return MyRenderer(self.syms)
  • That is very true. It was a poor copy paste from the example of the documentation. However I still have the problem with the 'symbolForFeature' function.
    – Florian
    Mar 15, 2013 at 15:24

The answer was in the documentation, right under the example. Shame on me...

The problem was coming from the 'usedAttributes' method, which should return the list of the attributes that will be present in the AttributeMap.

def usedAttributes(self):
    return ['id']

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.