3

I am trying to achieve this -> How to copy the color styling to a color column in a layer's attribute table?

script by @Germán Carrillo

prefix = "'"
layer = iface.activeLayer()
attr = layer.rendererV2().classAttribute()
attrColor = 'color' # Name of the field to store colors
fieldIndex = layer.dataProvider().fieldNameIndex(attrColor)
attrFeatMap = {}

for cat in layer.rendererV2().categories(): 
  expr = "\""+attr+"\"="+prefix+unicode(cat.value())+prefix
  for f in layer.getFeatures(QgsFeatureRequest(QgsExpression(expr))):
    attrMap = { fieldIndex : cat.symbol().color().name()}
    attrFeatMap[ f.id() ] = attrMap

layer.dataProvider().changeAttributeValues( attrFeatMap )

but after using that script I am getting an error

Traceback (most recent call last):
  File "<input>", line 1, in <module>
AttributeError: 'QgsGraduatedSymbolRendererV2' object has no attribute 'categories'

because it is for a layer classified with a Categorized Symbol Renderer.

So problem is that I can use this script only with random color... But how to make same thing gradient colors like ndvi -1 / 1

could this help me? -> http://docs.qgis.org/testing/en/docs/pyqgis_developer_cookbook/vector.html#graduated-symbol-renderer

First time working with python.....

EDIT: Qgis 2.10.1 - PISA EDIT: Iam adding picture

enter image description here

  • What version of QGIS are you using? – ArMoraer Mar 10 '17 at 7:07
  • @ArMoraer Qgis 2.10.1 - PISA – ABCD Mar 10 '17 at 7:46
  • The issue is that the renderer class is QgsCategorizedSymbolRendererV2 instead of QgsGraduatedSymbolRendererV2. Please, see my answer. – xunilk Mar 10 '17 at 17:12
3

The issue is that the renderer class is QgsCategorizedSymbolRendererV2 instead of QgsGraduatedSymbolRendererV2. So, I categorized next shapefile by FID field:

enter image description here

and identical code (Germán Carrillo' script ) was run at the Python Console of QGIS:

prefix = "'"
layer = iface.activeLayer()
attr = layer.rendererV2().classAttribute()
attrColor = 'color' # Name of the field to store colors
fieldIndex = layer.dataProvider().fieldNameIndex(attrColor)
attrFeatMap = {}

for cat in layer.rendererV2().categories(): 
  expr = "\""+attr+"\"="+prefix+unicode(cat.value())+prefix
  for f in layer.getFeatures(QgsFeatureRequest(QgsExpression(expr))):
    attrMap = { fieldIndex : cat.symbol().color().name()}
    attrFeatMap[ f.id() ] = attrMap

layer.dataProvider().changeAttributeValues( attrFeatMap ) 

As you can see at the next image, result was completely satisfactory (I am not getting any error):

enter image description here

Editing Note:

This is the code for Graduated Symbol Renderer:

layer = iface.activeLayer()

provider = layer.dataProvider()

renderer = layer.rendererV2()

feats = [ feat for feat in layer.getFeatures() ]
values = [ feat.attribute('FID')  for feat in feats ] #change for 'NDVI' in case of NDVI field

n = len(feats)

color_feats = [ renderer.symbolForValue(value).color().name() for value in values ]

idx = layer.fieldNameIndex('color')

for i, feat in enumerate(feats):
    new_values = {idx : color_feats[i]}
    provider.changeAttributeValues({i:new_values})

After running it at the Python Console of QGIS, values at 'color' field were placed as expected.

enter image description here

By using 'NDVI' field it also works perfectly:

enter image description here

  • I cant use Categorized I really need graduated. I have edited question and added picture – ABCD Mar 11 '17 at 7:55
0

This code should work for a graduated render:

prefix = "'"
layer = iface.activeLayer()
attr = layer.rendererV2().classAttribute()
attrColor = 'color' # Name of the field to store colors
fieldIndex = layer.dataProvider().fieldNameIndex(attrColor)
attrFeatMap = {}

for cat in layer.rendererV2().ranges():
    expr = "\""+attr+"\">="+prefix+unicode(cat.lowerValue())+prefix+'AND'+"\""+attr+"\"<="+prefix+unicode(cat.upperValue())+prefix
    for f in layer.getFeatures(QgsFeatureRequest(QgsExpression(expr))):
        attrMap = { fieldIndex : cat.symbol().color().name()}
        attrFeatMap[ f.id() ] = attrMap
layer.dataProvider().changeAttributeValues( attrFeatMap ) 

The only difference with your code is the using of the ranges() method instead of categories() and the slight editing of the expr expression because this time you don't deal with a single value, but with a whole range of values.

  • your code give this error <pre>File "<input>", line 6 layer.dataProvider().changeAttributeValues( attrFeatMap ) ^ SyntaxError: invalid syntax<code> have look on my answer there is plugin made by underdark which is working fine – ABCD Mar 11 '17 at 9:16
  • It worked for me, I tried to copy&paste it again. – mgri Mar 11 '17 at 9:21
  • Your code is wrong. It doesn't work when number of classes is lesser than features number. QgsCategorizedSymbolRendererV2 class has different methods compared to QgsGraduatedSymbolRendererV2 and for this reason an algorithm similar to Germán Carrillo' script doesn't work. You can see my Editing Note. – xunilk Mar 11 '17 at 12:54
  • @xunilk I have accepted your answer – ABCD Mar 11 '17 at 17:39
  • @xunilk I didn't widely tested it, but it worked for my sample dataset... Thanks for the clarification, I'll do some research about that! – mgri Mar 11 '17 at 18:05
0

OK I have answer

here is plugin made by @underdark

and here is it on GitHub

Working fine! enter image description here

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.