TVX – Temperature–Vegetation Index (example)
TVX represents the relationship between vegetation greenness (NDVI) and land-surface temperature (LST) to indicate canopy water / heat stress. Here it is implemented as an example index combining normalised NDVI and LST in a simple way for drought and stress analysis.
What does TVX measure?
In the temperature–vegetation (TVX) framework, healthy, well-watered vegetation tends to be green and relatively cool (high NDVI, low LST), while stressed vegetation tends to be less green and hotter. TVX captures this contrast by combining normalised NDVI and LST into one index.
- Qualitative drought and crop-stress mapping.
- Screening water-limited vs. well-watered agricultural areas.
- Supporting TVDI / VSWI / VHI-style analyses as an additional view.
- Providing a quick, intuitive NDVI–LST stress indicator.
Important: There is no single, universal algebraic formula for a TVX index. The expression below is a practical example. You can replace it with your preferred TVX / TVDI formulation while keeping this HTML layout.
TVX formula (example)
NDVIn = (NDVI − NDVImin) / (NDVImax − NDVImin)
Tsn = (Ts − Tsmin) / (Tsmax − Tsmin)
TVX = Tsn − NDVIn
With this definition, high TVX values indicate relatively hot and/or low-NDVI conditions (higher stress), while low or negative TVX indicates cool, green conditions (lower stress).
You may also scale TVX to 0–100, or invert / shift it so that higher values correspond to healthier vegetation, depending on your convention.
Required inputs
Spectral & thermal components
| Component | Source |
|---|---|
| NDVI | RED & NIR bands (Landsat, Sentinel-2, MODIS, etc.) |
| Ts / LST | Thermal band (Landsat) or LST product (MODIS, etc.) |
| NDVImin/max | Derived over ROI / season or reference period |
| Tsmin/max | Derived over ROI / season or reference period |
Tip: TVX is more robust when NDVI and LST are derived from cloud-free, atmospherically corrected imagery and when reference min/max values are computed over a representative period.
Interpreting TVX (example)
| TVX value | Interpretation (relative) |
|---|---|
| High positive | Hot & low NDVI – high stress / drought |
| Moderate | Intermediate conditions – mild to moderate stress |
| Near zero or negative | Cool & relatively green – low stress / well-watered |
| Very low / noisy | Bare soil / non-vegetated / mixed pixels |
Exact ranges are project-specific. Calibrate TVX against field observations or known drought events for your region.
Using TVX in Google Earth Engine (example with Landsat 8/9)
- Compute NDVI and LST / Ts from Landsat or another sensor.
- Derive NDVImin/max and Tsmin/max over ROI / season.
- Normalise NDVI and Ts to [0–1].
- Compute TVX = Tsn − NDVIn and map relative stress.
// TVX – Temperature–Vegetation Index example (Landsat 8/9) in Google Earth Engine
var roi = /* your geometry here */;
// Landsat 8/9 L2 collection (surface reflectance + surface temperature)
var l8 = ee.ImageCollection('LANDSAT/LC08/C02/T1_L2')
.filterBounds(roi)
.filterDate('2023-04-01', '2023-09-30')
.filter(ee.Filter.lt('CLOUD_COVER', 20));
// Scale function for optical & thermal bands
function scaleL8(img) {
var optical = img.select(['SR_B.']).multiply(0.0000275).add(-0.2);
var ts = img.select('ST_B10').multiply(0.00341802).add(149.0); // Kelvin
return img.addBands(optical, null, true)
.addBands(ts.rename('Ts'));
}
l8 = l8.map(scaleL8);
// Median composite
var img = l8.median();
// NDVI
var nir = img.select('SR_B5');
var red = img.select('SR_B4');
var ndvi = nir.subtract(red).divide(nir.add(red)).rename('NDVI');
// Surface temperature (Kelvin)
var ts = img.select('Ts');
// Derive min/max for NDVI and Ts over ROI
var ndviStats = ndvi.reduceRegion({
reducer: ee.Reducer.minMax(),
geometry: roi,
scale: 30,
maxPixels: 1e7
});
var tsStats = ts.reduceRegion({
reducer: ee.Reducer.minMax(),
geometry: roi,
scale: 30,
maxPixels: 1e7
});
var ndviMin = ee.Number(ndviStats.get('NDVI_min'));
var ndviMax = ee.Number(ndviStats.get('NDVI_max'));
var tsMin = ee.Number(tsStats.get('Ts_min'));
var tsMax = ee.Number(tsStats.get('Ts_max'));
// Normalised NDVI and Ts
var ndvi_n = ndvi.subtract(ndviMin)
.divide(ndviMax.subtract(ndviMin).add(1e-6));
var ts_n = ts.subtract(tsMin)
.divide(tsMax.subtract(tsMin).add(1e-6));
// TVX = Ts_n - NDVI_n
var tvx = ts_n.subtract(ndvi_n).rename('TVX');
// Visualisation (example palette: low = cool/green, high = hot/stressed)
Map.centerObject(roi, 8);
Map.addLayer(tvx, {
min: -1.0, max: 1.0,
palette: ['#0f766e','#22c55e','#eab308','#f97316','#7f1d1d']
}, 'TVX - Temperature–Vegetation Index');
// Optional export
Export.image.toDrive({
image: tvx,
description: 'TVX_Landsat8_example',
region: roi,
scale: 30,
maxPixels: 1e13
});
Important: treat this TVX definition as a practical example. If you use a specific TVX / TVDI / NDVI–LST relationship from a paper, simply replace the equations while keeping this HTML structure in your indices library.