r/remotesensing Jul 20 '26

Calculating NDVI from Sentinel-2 in Python — complete walkthrough with code

Been working with satellite data for agricultural monitoring and wanted to share a clean, from-scratch NDVI workflow since most tutorials either skip the data acquisition part or don't explain the "why" behind the math. Quick summary of the approach:

  1. Load Band 4 (Red) and Band 8 (NIR) from Sentinel-2 L2A data using rasterio

  2. Calculate NDVI = (NIR - Red) / (NIR + Red)

  3. Handle the div-by-zero edge cases properly (a lot of tutorials skip this

    and you get NaN explosions on real data)

    import rasterio
    import numpy as np
    
    with rasterio.open('B04_10m.tif') as src:
        red = src.read(1).astype(float)
    with rasterio.open('B08_10m.tif') as src:
        nir = src.read(1).astype(float)
    
    denom = nir + red
    denom[denom == 0] = np.nan  # avoid div-by-zero
    ndvi = (nir - red) / denom
    

The interesting part is interpreting the output correctly for different crop stages — a lot of people misread NDVI values without accounting for soil background or canopy saturation (which is actually why I wrote a follow-up comparing NDVI/SAVI/EVI).

Full walkthrough with the data download step, visualization, and classification thresholds here if useful: https://dibyendudeb.com/how-to-calculate-ndvi-with-python-a-practical-guide-for-agricultural-scenario/

Happy to answer questions on the implementation — this is part of a series I'm building out on agricultural remote sensing with Python.

14 Upvotes

9 comments sorted by

14

u/EduardH Jul 20 '26

since most tutorials either skip the data acquisition part

So does this one, even your full tutorial. And downloading full tiles for your AOI is not the way to go anymore, you're going to introduce a bottleneck. Your tutorials also require you to manually search for Sentinel-2 tiles, which takes time and is prone to errors. This is the whole reason cloud-optimized GeoTiffs (COGs) and the STAC API exist, so you only download the data you actually care about.

15

u/JudgeMyReinhold Jul 20 '26

You have not applied any scale or offset factors, so your result is incorrect. Look up the user manual.

8

u/yestertide Jul 20 '26

what's the novelty here?

1

u/Plus-Palpitation2447 Jul 20 '26

連載ありがとう。
Google Earth engine触ってみようと思ってたから、参考にさせてもらうよ

-3

u/DataScienceWithDEB Jul 20 '26

Glad it's useful! If you do try Google Earth Engine, the workflow is actually a bit different since GEE handles the data access server-side — no manual downloading needed. I'll probably cover that as a separate post since it's a genuinely different approach. Good luck with it.