Search code examples
pythonarraysnumpyimage-processingearthpy

How to show negative values in an NDVI image?


I am fairly new to python. I am working with some Landsat 8 .tiff images to produce an NDVI image. When I produce the image, the river does not show as a negative value. NDVI goes from -1 to 1, but the lowest it goes to is 0 in this image. This is a portion of the code I used:

import os
from glob import glob

import sys
import numpy as np 
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap  
import rasterio as rio 
from rasterio.plot import plotting_extent 
import rioxarray as rxr
import geopandas as gpd 
import earthpy as et  
import earthpy.spatial as es  
import earthpy.plot as ep 
#create image stack
arr_st, meta = es.stack(stack_bands_path, nodata = -9999)

#allow division by 0
np.seterr(divide='ignore', invalid='ignore')

#create NDVI
red = arr_st[3].astype(float)
nir = arr_st[4].astype(float)

ndvi = np.divide((nir-red), (nir+red))
ep.plot_bands(ndvi, cmap="RdYlGn", cols=1, vmin=-1, vmax=1)
plt.show()

I am not sure what I am doing wrong. I was originally using earthpy.spatial.normalized_difference but the rivers were coming out green (or 1 on the colorbar).

My theory is that the numbers less than 0 are showing up as zero...but I am not sure. Any help is appreciated. Image of the NDVI is below.

NDVI image


Solution

  • The NDVI will fall in the range -1 to +1 so an integer is not a good representation because there are only 3 possible integer outcomes in that range, namely -1, 0 and 1.

    I am not familiar with the specific package you are using but, if you want fractional (decimal) results, I would imagine you'd want to use the float type, i.e.:

    red = arr_st[3].astype(float)
    nir = arr_st[4].astype(float)