0

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

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
techsense
  • 15
  • 4

1 Answers1

0

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)
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • I tried that, but it still does not show any negative values. Thanks anyways. – techsense Feb 18 '21 at 23:10
  • You haven't provided a *"Minimum Complete Verifiable Example"* with `import` statements and representative images so it's harder to help you. Try checking `ndvi.min()` and `ndvi.max()` to see the range of your data before display. Bear in mind that PNG format cannot store negative values. Try rescaling your data to the range 0..255 by doing `ndvi=((ndvi+1)*127).astype(np.uint8)` – Mark Setchell Feb 19 '21 at 07:19
  • Ahh, I see! Sorry. I did end up thinking of doing the max and min, and it came out to be 6673 and -1. I did np.max(ndvi) since I am using numpy. I am also working with tiff files. I edited my question to include the import statements. – techsense Feb 21 '21 at 00:45
  • You've gone wrong if your `max` exceeds 1. There are no values for `a` and `b` such that `(a-b)/(a+b) > 1`. – Mark Setchell Feb 21 '21 at 08:41
  • Yes, I am aware. – techsense Feb 22 '21 at 13:56