引言
- 前面发的一篇推文《Python实现NDVI序列Hants滤波平滑
》中,其中有利用Python实现长时间序列曲线绘制部分内容,现对使用Python+GEE绘制时序曲线单独出一期内容。主要内容如下:
- 提取某区域内的S2_NDVI时间序列数据;
- 将上述数据转换为pandas数据格式;
- 创建时间内的时间序列图表,并使用特定时间窗口进行移动平均滤波平滑曲线。
- 下面是具体实现步骤及代码:
1. 基础Python包的导入和网络代理设置
import ee
import geemap
import json
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
geemap.set_proxy(port=19180)
2. 定义研究区域,buffer函数生成缓冲区
poi = ee.Geometry.Point(98.95782793608701, 37.37657466863545).buffer(10000)
Map = geemap.Map()
Map.centerObject(poi, zoom=10)
Map.add_basemap("SATELLITE")
Map.addLayer(poi, {}, "IMG")
Map.addLayerControl()
Map
3. Sentinel-2数据去云与时空筛选等预处理
def rmCloudByQA(image):
qa = image.select('QA60')
cloudBitMask = 1 << 10
cirrusBitMask = 1 << 11
mask =qa.bitwiseAnd(cloudBitMask).eq(0).And(qa.bitwiseAnd(cirrusBitMask).eq(0))
return image.updateMask(mask);
S2 = ee.ImageCollection('COPERNICUS/S2_SR').filterDate('2019-01-01', '2021-12-01').filterBounds(poi)\
.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20)).map(rmCloudByQA)
4. 定义NDVI函数,添加对应属性信息
def ndvi_mean(img):
ndvi = img.normalizedDifference(['B5', 'B4']).rename('NDVI')
mean = ndvi.reduceRegion(reducer=ee.Reducer.mean(), geometry=poi, scale=10).get('NDVI')
return img.set('date', img.date().format()).set('mean',mean)
5. 使用Map函数生成新的ImageCollection
imgs = S2.map(ndvi_mean)
6. 将数据转换为pandas数据格式
- 对于每一幅影像都包含日期和S2_NDVI均值两个元素的列表;
list = imgs.reduceColumns(ee.Reducer.toList(2), ['date','mean']).values().get(0)
7. 使用getInfo函数来检索数据
df_1 = pd.DataFrame(list.getInfo(), columns=['date','mean'])
8. 将日期列设置为绘图索引
df_1['date'] = pd.to_datetime(df_1['date'])
df_2 = df_1.set_index('date')
9. 使用seaborn库制作一个简单的时间序列线图
# 使用pyplot创建一个图形,并将尺寸设置为15x7
fig, ax = plt.subplots(figsize=(15,7))
# 通过将数据框设置为 data 参数来创建绘图
sns.lineplot(data=df_2, ax=ax)
# 设置标签和标题
ax.set_ylabel('mean radiance',fontsize=20)
ax.set_xlabel('date',fontsize=20)
ax.set_title('S2 NDVI for (2019 to 2021)',fontsize=20)
10. 获取最大值的索引
df_2.idxmax()
11. 移动平均滤波平滑时间序列
fig, ax = plt.subplots(figsize=(15,7))
# 设置时间窗口为6个月,并使用移动平均滤波平滑曲线
window=6
sns.lineplot(data=df_2.rolling(window).mean(), ax=ax)
ax.set_ylabel('mean radiance',fontsize=20)
ax.set_xlabel('date',fontsize=20)
ax.set_title(f'S2 NDVI ({window} moving avg.) for (2019 to 2021)',fontsize=20)