QGIS Raster – How to Find Percentile Values in Raster Using QGIS

qgisraster

I have a raster (geotiff) and I would like simply to know some parcentile values, specifically the 80th, 85th, 90th and 95th, because I need to highlight all values above these thresholds in QGIS.

First I thought that in Properties –> Style –> Cumulative count cut I had simply to write the percent value in Min or Max boxes (80 and 95 respectively, for example). But I discovered that if I write 80 in the first box or in the second one (next to the cumulative count cut), the value will be different.

enter image description here

So I tried to convert the raster in an Ascii grid, I opened the Ascii with text editor, I copied the cell values and I pasted in an Excel file. I deleted all the no data values (-9999 in my case) and I used the Percentile function in Excel to extract from the resulting matrix my values.

I thought that it would the right way to find the values, but I wanted to be sure, so I used the Max function in Excel just to see if the value was the same to the one I can find in Propreties–>Metadata–>Maximum value…. and the to values were different, so I don't trust in what I did in Excel.

Any help?

Best Answer

You can use PyQGIS to convert your raster to numpy Array then find percentiles with numpy.percentile():

import gdal
import numpy as np
from osgeo import gdal_array

rasterfile = r"C:\Test\nh_66_5.tif" #Change

#Or replace line above with this, with the raster added to the map and activated by clicking on layer name:
#layer = iface.activeLayer()
#rasterfile = layer.source()

percentiles = [50,80,90] #Change

rasterArray = gdal_array.LoadFile(rasterfile) #Read raster as numpy array

for p in percentiles:
    print('{0}th percentile is: {1}'.format(p, np.percentile(rasterArray,p)))

enter image description here

If your raster is multiband, np.percentile will flatten the Array (=include all bands). If you want percentiles for specific band, use indexing, for example np.percentile(rasterArray[0],50)