3

According to the PyQGIS Cookbook, a color ramp can be assigned in the following way:

rlayer.setColorShadingAlgorithm(QgsRasterLayer.ColorRampShader)
lst = [ QgsColorRampShader.ColorRampItem(0, QColor(0,255,0)), \
    QgsColorRampShader.ColorRampItem(255, QColor(255,255,0)) ]
fcn = rlayer.rasterShader().rasterShaderFunction()
fcn.setColorRampType(QgsColorRampShader.INTERPOLATED)
fcn.setColorRampItemList(lst)

However, this code appears to be old, because setColorShadingAlgorithm is not present in QGIS 2.2.0. This bug report states that setDrawingStyle can be used instead, but I haven't been able to assign a color ramp through its use.

How would I assign a color ramp through PyQGIS, using setDrawingStyle or otherwise?

Nathan W
  • 34,706
  • 5
  • 97
  • 148
Chris S.
  • 101
  • 1
  • 4
  • Though not an answer to my specific question, I found an easier way to accomplish what I'm trying to automate. This question/answer shows how to load a saved style using PyQGIS. Rather than specifying the color ramp using PyQGIS, I can manually save a style in a .qml file, then load this file using PyQGIS. – Chris S. Oct 19 '14 at 14:44

2 Answers2

2

Based in this answer, What is the replacement for 'setColorShadingAlgorithm' in QGIS 2.6?, I include the following code where it is also employed the procedure substitute for 'setColorShadingAlgorithm' ('setRasterShaderFunction', objet of the QgsRasterShader class). This code get the minimum and maximum values of the raster, by using some dataProvider class methods, to calculate the ColorRampItem's .

from PyQt4.QtCore import *
from PyQt4.QtGui import *

layer = iface.activeLayer()

renderer = layer.renderer()
provider = layer.dataProvider()

ver = provider.hasStatistics(1, QgsRasterBandStats.All)

stats = provider.bandStatistics(1, QgsRasterBandStats.All,extent, 0)

if ver is not False:
    print "minimumValue = ", stats.minimumValue

    print "maximumValue = ", stats.maximumValue

if (stats.minimumValue < 0):
   min = 0  

else: 
    min= stats.minimumValue

max = stats.maximumValue
range = max - min
add = range//2
interval = min + add

colDic = {'red':'#ff0000', 'yellow':'#ffff00','blue':'#0000ff'}

valueList =[min, interval, max]

lst = [QgsColorRampShader.ColorRampItem(valueList[0], QColor(colDic['red'])),\
       QgsColorRampShader.ColorRampItem(valueList[1], QColor(colDic['yellow'])), \
       QgsColorRampShader.ColorRampItem(valueList[2], QColor(colDic['blue']))]

myRasterShader = QgsRasterShader()
myColorRamp = QgsColorRampShader()

myColorRamp.setColorRampItemList(lst)
myColorRamp.setColorRampType(QgsColorRampShader.INTERPOLATED)
myRasterShader.setRasterShaderFunction(myColorRamp)

myPseudoRenderer = QgsSingleBandPseudoColorRenderer(layer.dataProvider(), 
                                                    layer.type(),
                                                    myRasterShader)                                                                    

layer.setRenderer(myPseudoRenderer)

layer.triggerRepaint()

When this code was running in the Python Console, with a single gray raster band (minimum value = 1323.0, maximumValue = 3556.0), the image resulting had the following pseudocolor renderer:

enter image description here

xunilk
  • 29,891
  • 4
  • 41
  • 80
1

Although this question is relatively old, I was struggling for quite some time to get it working as I wanted (for QGIS 3).

My goal is to just load a layer, and get some single band pseudocolor styling to avoid having to click through the properties repeatedly. And I'd like to use one of the default QGIS colormaps.

It's worth noting that the QgsStyle().defaultStyle().colorRamp object has a .color() method which does the interpolation for you; no need to parse the ramp properties like suggested here: How can singleband pseudocolor style's values be computed using PyQgis

from typing import List

from qgis.core import ( QgsRasterBandStats, QgsColorRampShader, QgsRasterShader, QgsSingleBandPseudoColorRenderer, QgsStyle, )

def color_ramp_items( colormap: str, minimum: float, maximum: float, nclass: int ) -> List[QgsColorRampShader.ColorRampItem]: delta = maximum - minimum fractional_steps = [i / nclass for i in range(nclass + 1)] ramp = QgsStyle().defaultStyle().colorRamp(colormap) colors = [ramp.color(f) for f in fractional_steps] steps = [minimum + f * delta for f in fractional_steps] return [ QgsColorRampShader.ColorRampItem(step, color, str(step)) for step, color in zip(steps, colors) ]

def pseudocolor_styling(layer, colormap: str, nclass: int) -> None: stats = layer.dataProvider().bandStatistics(1, QgsRasterBandStats.All) minimum = stats.minimumValue maximum = stats.maximumValue

ramp_items = color_ramp_items(colormap, minimum, maximum, nclass)
shader_function = QgsColorRampShader()
shader_function.setClassificationMode(QgsColorRampShader.EqualInterval)
shader_function.setColorRampItemList(ramp_items)

raster_shader = QgsRasterShader()
raster_shader.setRasterShaderFunction(shader_function)

renderer = QgsSingleBandPseudoColorRenderer(layer.dataProvider(), 1, raster_shader)
layer.setRenderer(renderer)
layer.triggerRepaint()

Example use:

layer = QgsProject.instance().mapLayersByName("example_layer")[0]
pseudocolor_styling(layer, colormap="Viridis", nclass=10)

Where "example layer" is the name of the layer in the Layers Panel. It'll error if you ask for a colormap that isn't available (e.g. "viridis", lower case).

Huite Bootsma
  • 621
  • 4
  • 7