[GIS] Apply graduated symbology renderer works in Python console but not in standalone script

pyqgisqgissymbology

I use the following PyQGIS script to load a vector layer from a shapefile and apply graduated symbology to it (tried to make it as minimalistic as possible). This works well in the QGIS 2.4 Chugiak Python console – the specified vector layer is loaded and graduated symbology is applied according to the arguments given to the function (vectorLayer, targetField, classes, mode).

However, when using this in a standalone script, I always get

layer loaded succesfully
ERROR 1: Argument of column Summary Function 'MIN' should be a column.
applying graduated symbology
ERROR 1: Argument of column Summary Function 'MAX' should be a column.

and no graduated rendering is applied. Any suggestions why this happens or how I can use QgsGraduatedSymbolRendererV2 in a standalone script (preferably by using one of the existing rules instead of creating all classes on my own)?

Other functions like a more or less selfmade appliance of categorized rendering work well, so this does not seem to be a general issue with my Python/IDE/QGIS environment. I already made sure that my columns are numeric (and otherwise it would not work in the Python console).

Here is the code I use. When trying this out, make sure to adapt the parameters at the top to match your file. When trying it in the Python console, comment/delete the part at the top concerning set up qgis app and the last line app.exitQgis(), otherwise QGIS will probably crash.

# imports
from qgis.core import *
from qgis.utils import *
from PyQt4.QtCore import *
from PyQt4.QtGui import *

import os, glob

###########
# parameters
###########
pathToLayer = '/path/to/your/favorite/vectorLayer.shp'
targetField = 'someNumericColumnInTheVectorLayer'

pathToQGIS = '/path/to/your/qgis/folder/'

###########
# set up qgis app
###########
QgsApplication.setPrefixPath(pathToQGIS, True)
QgsApplication.initQgis()
app = QgsApplication([], True)


###########
# load a layer
###########
def loadVectorLayer(pathToLayer):
    vectorLayer = QgsVectorLayer(pathToLayer, 'ThisIsAVectorLayer', 'ogr')

    # validity check. if layer is valid, add to canvas
    if not vectorLayer.isValid():
        print "Layer failed to load!"
    else:
        QgsMapLayerRegistry.instance().addMapLayer(vectorLayer, True)
        print 'layer loaded succesfully'
        return vectorLayer


###################################
# function to apply graduated symbology to a layer
###################################
def applyGraduatedSymbology(vectorLayer, targetField, classes, mode):

    print 'applying graduated symbology'

    # set up renderer
    symbol =  QgsLineSymbolV2()

    colorRamp = QgsVectorGradientColorRampV2.create({'color1' : '0,255,0,255',
                                                     'color2' : '255,0,0,255',
                                                     'stops' : '0.5;255,255,0,255'})

    renderer = QgsGraduatedSymbolRendererV2.createRenderer(vectorLayer, targetField, classes, mode, symbol, colorRamp)

    vectorLayer.setRendererV2(renderer)
    return


###################################
# main
###################################
def main():

    vectorLayer = loadVectorLayer(pathToLayer)

    applyGraduatedSymbology(vectorLayer, targetField, 3, QgsGraduatedSymbolRendererV2.Jenks)

    print 'finished'

    return

main()

app.exitQgis()

Best Answer

I haven't seen graduated symbol documentation quite like that before. This code might be a bit more comprehensible and will probably solve your problem because I too use PyCharm IDE and I have used these graduated symbols many times.

 # create graduated marker symbol based on ('label', 'lower_range', 'upper_range', 'color')
colorRamp = (('label1', lwrTargetFieldVal, upprTargetFieldVal, '0,255,0,255'), \
           ('label2', lwrTargetFieldVal2, upprTargetFieldVal3, '255,0,0,255'), \
           ('label3', lwrTargetFieldVal3, upprTargetFieldVal3, '0.5;255,255,0,255'))
ranges = []
for label, lower, upper, color in colorRamp:
    rng = QgsRendererRangeV2(lower, upper, sym, label)
    ranges.append(rng)
field = "someNumericColumnInTheVectorLayer"
renderer = QgsGraduatedSymbolRendererV2(field, ranges)
layer.setRendererV2(renderer)
Related Question