Google Earth Engine中绘制NDVI散点图及去异常值趋势线方法
GEE Landsat 8 NDVI时序散点图与趋势线绘制
问题背景
我目前使用 USGS Landsat 8 Level 2, Collection 2, Tier 1 数据集计算研究区平均NDVI,期望基于散点形式绘制NDVI变化趋势。
原有实现代码
// 导入数据 var imageCollection = 'USGS Landsat 8 Level 2, Collection 2, Tier 1' var table = '研究区shapefile矢量文件' // 定义为Landsat 8影像添加NDVI波段的函数 var addNDVI = function(image) { var ndvi = image.normalizedDifference(['SR_B5', 'SR_B4']).rename('NDVI'); return image.addBands(ndvi); }; function add_NDVI_collection(image_IC){ var NDVI_IC = table.map(addNDVI); return NDVI_IC; } // 筛选时间范围并批量添加NDVI波段 var withNDVI = imageCollection.filterDate('2015-01', '2015-12') .map(addNDVI); // 生成时序图表 var chart = ui.Chart.image.series({ imageCollection: withNDVI.select('NDVI'), region: table, reducer: ee.Reducer.mean() }) // 图表配置 var options = { title: 'NDVI时序变化', hAxis: { title: '时间' ,format: 'YYYY-MMM',gridlines:{count:12}}, vAxis: { title: 'NDVI' }, series: { 0: { color: 'blue' } } }; // 应用配置并输出图表 chart = chart.setOptions(options); print(chart);
原有运行效果
运行上述代码默认输出连线形式的NDVI时序结果,示例如下:
待实现需求
需要调整代码完成两个目标:
- 将默认的连线式绘图改为NDVI散点展示
- 剔除NDVI异常值后绘制NDVI变化趋势线
调整方案
核心修改点
- 散点样式配置:在图表
series配置项中设置lineWidth: 0关闭默认连线,同时配置散点大小、形状参数,实现纯散点展示。 - 异常值剔除:两层处理逻辑,一是调用Landsat 8 Collection 2数据集自带的
QA_PIXEL、QA_RADSAT波段做去云、去除辐射饱和像元处理,消除云、云阴影、传感器饱和导致的NDVI偏差;二是对计算得到的NDVI做值掩膜,直接剔除超出NDVI理论取值范围[-1,1]的异常值。 - 趋势线添加:使用GEE图表内置的
trendlines配置项,自动基于过滤后的有效散点生成线性拟合趋势线,支持自定义趋势线样式、显示拟合决定系数R²。 - 冗余逻辑清理:删除原有代码中无效的
add_NDVI_collection函数,补充filterBounds筛选研究区范围内影像,明确设置30米计算分辨率,避免计算结果出现不必要的偏差。
调整后完整可运行代码
// 导入数据 var imageCollection = ee.ImageCollection("LANDSAT/LC08/C02/T1_L2"); var table = ee.FeatureCollection("研究区矢量文件"); // Landsat 8 C2 SR数据集去云掩膜函数 function maskL8sr(image) { var qaMask = image.select('QA_PIXEL').bitwiseAnd(parseInt('11111', 2)).eq(0); var saturationMask = image.select('QA_RADSAT').eq(0); return image.updateMask(qaMask).updateMask(saturationMask); } // 定义添加NDVI波段+掩膜异常值函数 var addNDVI = function(image) { var ndvi = image.normalizedDifference(['SR_B5', 'SR_B4']).rename('NDVI'); // 掩膜超出[-1,1]合理范围的NDVI异常值 ndvi = ndvi.updateMask(ndvi.gte(-1).and(ndvi.lte(1))); return image.addBands(ndvi).copyProperties(image, ['system:time_start']); }; // 影像筛选、去云、添加NDVI var withNDVI = imageCollection.filterDate('2015-01-01', '2015-12-31') .filterBounds(table) .map(maskL8sr) .map(addNDVI); // 生成时序图表 var chart = ui.Chart.image.series({ imageCollection: withNDVI.select('NDVI'), region: table, reducer: ee.Reducer.mean(), scale: 30 // 匹配Landsat 8原生30米分辨率 }) // 图表配置 var options = { title: '2015年研究区NDVI时序变化(散点+趋势线)', hAxis: { title: '日期' ,format: 'YYYY-MMM',gridlines:{count:12}}, vAxis: { title: 'NDVI值', viewWindow: {min: -0.2, max: 1} }, series: { 0: { color: '#1f77b4', lineWidth: 0, // 关闭默认连线 pointSize: 4, // 散点大小 pointShape: 'circle' // 散点形状 } }, // 线性趋势线配置 trendlines: { 0: { color: '#d62728', lineWidth: 2, opacity: 0.8, showR2: true, // 显示拟合R² visibleInLegend: true } } }; // 应用配置并输出图表 chart = chart.setOptions(options); print(chart);
内容的提问来源于stack exchange,提问作者Jui Sen
相关产品推荐
相关产品推荐

