2

I am using QGIS 3.22.2.

I am relatively new to QGIS and have been trying to automate part of a workflow, including changing the rendering of a raster. Following the PyQGIS cookbook, I have this code:

stats = rlayer.dataProvider().bandStatistics(1, QgsRasterBandStats.All)
min = stats.minimumValue
max = stats.maximumValue

fnc = QgsColorRampShader()
fnc.setColorRampType(QgsColorRampShader.Interpolated)

lst = [  QgsColorRampShader.ColorRampItem(min, QColor(255, 0, 0)),
  QgsColorRampShader.ColorRampItem(max, QColor(0, 0, 255))]
  
fnc.setColorRampItemList(lst)

shader = QgsRasterShader()
shader.setRasterShaderFunction(fnc)

renderer = QgsSingleBandPseudoColorRenderer(rlayer.dataProvider(), 1, shader)

rlayer.setRenderer(renderer)
rlayer.triggerRepaint()

This works grand, and changes how a selected raster renders as shown below.

enter image description here

However, the legend doesn't update as expected. In this case, instead of an interpolated color bar between red and blue and specified values min-max, I get an almost completely blue color bar (the last color in my variable lst) between values 0-255. This is shown in the image below. The left hand legend is what I get when manually changing the rendering, and the right hand image is the result when running the above code.

enter image description here

How might I go about updating the legend programmatically?

0

1 Answer 1

6

You can use the script below (just change your layer name in the first line):

layer_name = 'your_layer_name'
rl = QgsProject.instance().mapLayersByName(layer_name)[0]
prov = rl.dataProvider()
stats = prov.bandStatistics(1, QgsRasterBandStats.All, rl.extent(), 0)
min = stats.minimumValue
max = stats.maximumValue
renderer = QgsSingleBandPseudoColorRenderer(rl.dataProvider(), 1)
color_ramp = QgsGradientColorRamp(QColor(255, 0, 0), QColor(0, 0, 255))
renderer.setClassificationMin(min)
renderer.setClassificationMax(max)
renderer.createShader(color_ramp)
rl.setRenderer(renderer)
rl.triggerRepaint()

Results on a test DEM layer:

enter image description here

enter image description here

You can also pass different ramp types and classifaction modes, along with a number of classes to the createShader() method. For example, here I reversed the color ramp and changed this line:

renderer.createShader(color_ramp)

To:

renderer.createShader(color_ramp, QgsColorRampShader.Discrete, QgsColorRampShader.EqualInterval, 15)

Results:

enter image description here

enter image description here

Docs for QgsSingleBandPseudoColorRenderer

I also got some hints by looking through the Python unit tests for QgsRasterLayer here.

0

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.