3

I am working on QGIS 3.20 on a raster layer symbology using PyQGIS singlebandpseudocolor and min/max values from the target raster layer.

My own color ramp (from blue to red) does not spread homogeneously the raster values, since it uses 0 to 255 range, instead of the min/max values. e.g. for a raster layer with min/max [150-300], the layer will be mostly blueish, whereas a raster layer with min/max [0.1-0.15] will be mostly reddish.

enter image description here

enter image description here

I would like the min value to be always blue and the max value to be red.

I am missing something I guess in the following code (e.g. for raster_interpol_ibco_clip and repeated for raster_interpol_shannon_clip):

# ibco:
rlayer = QgsProject.instance().mapLayersByName('raster_interpol_ibco_clip')[0]
extent = rlayer.extent()
provider = rlayer.dataProvider()
colDic={'5':'#d7191c','4':'#fdae61','3':'#ffffbf','2':'#abdda4','1':'#2b83ba'}
myColorRamp = QgsColorRampShader()
myColorRamp.setColorRampType(QgsColorRampShader.Interpolated)
stats = provider.bandStatistics(1, QgsRasterBandStats.All, extent, 0)
if (stats.minimumValue < 0):
   min = 0  
else: 
   min = stats.minimumValue
max = stats.maximumValue
etape = (stats.maximumValue - stats.minimumValue) //4
interval_orange = min + (etape*1)
interval_jaune = min + (etape*2)
interval_vert = min + (etape*3)
lst2 = [ QgsColorRampShader.ColorRampItem(min, QColor(colDic['1']), str(min)),
        QgsColorRampShader.ColorRampItem(interval_orange, QColor(colDic['2']), str(interval_orange)),
        QgsColorRampShader.ColorRampItem(interval_jaune, QColor(colDic['3']), str(interval_jaune)),
        QgsColorRampShader.ColorRampItem(interval_vert, QColor(colDic['4']), str(interval_vert)),
        QgsColorRampShader.ColorRampItem(max, QColor(colDic['5']), str(round(max)))]
myColorRamp.setColorRampItemList(lst2)
myRasterShader = QgsRasterShader()
myRasterShader.setRasterShaderFunction(myColorRamp)
myPseudoRenderer = QgsSingleBandPseudoColorRenderer(rlayer.dataProvider(), 1, myRasterShader)
rlayer.setRenderer(myPseudoRenderer)
rlayer.setOpacity(0.8)
rlayer.triggerRepaint()
iface.layerTreeView().refreshLayerSymbology(rlayer.id())

1 Answer 1

2

I found the issue. The code is correct, but I did not know how Python was dealing with floating values! My calculation for the color ramp was rounded and thus wrong.

The solution:

from decimal import Decimal

if (stats.minimumValue < 0):
   min = Decimal('0')
else: 
   min = Decimal(stats.minimumValue)

max = Decimal(stats.maximumValue)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.