I have a DEM raster with pixel values between about 3000 and -0.0003. I need to set all pixel with a value of 0 and smaler (<=0) to "nodata" (for later raster calculations and to reduce the filesize).

It seems for me that this is a task for the raster calculator (set value of pixels <=0 to "nodata") or a reclassification (set value of pixels <=0 to "nodata" and keep all other values) but I dont know how.


8 Answers 8


It can be done in one step in QGIS in the raster calculator.

In QGIS3, for a raster layer named "x", use the following expression:

(("x">0)*"x") / (("x">0)*1 + ("x"<=0)*0)

This trick maps raster values x>0 into the ratio x/1 = x, and raster values x<=0 into the ratio 0/0 = NaN. This NaN is rendered as FLOAT_MIN (aka -3.402832...e+38) if the raster is 4-byte float.

Strangely this question seems to have been around a while, with (as far as my quick Google search today shows) most respondents saying it can't be done in a single step. It certainly shouldn't need to be hacked like this. The QGIS documentation could be better too.

  • This is an excellent answer I've been looking for. Heaps of thanks!
    – Summer
    Feb 26, 2020 at 5:36
  • Very helpfull. And strange enough this is so cumbersome...
    – Vincé
    Jun 22, 2021 at 14:40

I didn't find a one-tool solution, but you can first use raster calculator to turn all values below a certain threshold to zero and then use gdal_translate with -a_nodata 0 to turn the 0 into nodata.

enter image description here

enter image description here


Here's the GRASS mapcalc expressions to set a range to NULL:

r.mapcalc "dem_corrected = if(dem<=0, null(), dem)"
  • Great, works for me!
    – ilFonta
    Jan 27, 2019 at 12:12

You can also save the layer (right click, save as ...) and specify a nodata range. This will keep the original nodata and create new nodatas for the specified range of values.


Many thanks to Dominik. My first answer is not correct for QGIS 2.8.3 (the expression "myraster@1" > 0 returns 0 or 1 for non-nodata input, for nodata input it returns nodata).

The following QGIS Raster Calculator expression should be sufficient (raster layer named "myraster"), since the QGIS Raster Calculator sets all pixels that do not satisfy the condition to nodata:

("myraster@1" > 0) * "myraster@1"

The following solution is based on https://docs.qgis.org/2.8/en/docs/training_manual/processing/no_data.html, and works for QGIS 2.8.3 with SAGA 2.1.2.

In QGIS Processing, use the SAGA Raster calculator and enter the following in Formula:

ifelse(g1=0, 0/0, ifelse(g1<0, 0/0, g1))


ifelse(a=0, 0/0, ifelse(a<0, 0/0, a))

This will turn all values less than or equal to 0 into nodata (0/0).


I had a similar issue, but had BOTH values I wanted to convert to no-data AND existing no-data values in the raster.

Identify Results

I came to this page for help, but I think there is a caveat to the approaches here. The methods of @underdark and @Micha only seem to work where there are no existing no-data values in the raster.

To get round this, you need to convert both the no-data values, and the values you wish to convert to no-data, to a consistent number. It is then okay to use the second step of @underdark.

To do this, use the Processing Toolbox > Reclassify Grid Values (SAGA) to convert the values and the no-data values to a common number (e.g. -999), at the same time. Specifically, use method "range" and specify the range. Then in replace no-data values, choose this same value (e.g. -999). Untick replace other values. This works for a single value change or more complex changes too.

Then follow the method of @underdark, and save the raster using Raster>Conversion>Translate, and tick no-data, entering the value you used (e.g. -999).


I could not find a solution to this problem in QGIS. However, exporting the raster to R was easy:


values(dem)[values(dem) <= 0] = NA
writeRaster(dem,'/home/.../DEM_0.tif', overwrite=TRUE)

This is also possible in GDAL raster calculator and (imho) more intuitive than native raster calculator. Since it uses numpy functions, you can use numpy.where and numpy.nan like so:


if you have loaded you layer as "Input layer A"

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