Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
spatialthoughts committed Jul 8, 2023
1 parent da2b77d commit ed532ef
Show file tree
Hide file tree
Showing 14 changed files with 943 additions and 121 deletions.
41 changes: 34 additions & 7 deletions code/gee_charts/04-Advanced_Charts/02b_Box_Plots_(complete)
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,12 @@ var values = withNdvi.map(function(image) {
}
return ee.Feature(null, properties)

})
});

// Remove null values
var values = values.filter(ee.Filter.notNull(
['median', 'min', 'max', 'p25', 'p50', 'p75']));

// Format the results as a list of DataTable rows

// We need a list to map() over
Expand All @@ -93,9 +98,9 @@ var dateList = values.aggregate_array('date');
// '2017-01-01' becomes 'Date(2017,0,1)'
// month is indexed from 0 in Date String representation
function formatDate(date) {
var year = ee.Date(date).get('year').format()
var month = ee.Date(date).get('month').subtract(1).format()
var day = ee.Date(date).get('day').format()
var year = ee.Date(date).get('year').format();
var month = ee.Date(date).get('month').subtract(1).format();
var day = ee.Date(date).get('day').format();
return ee.String('Date(')
.cat(year)
.cat(', ')
Expand Down Expand Up @@ -142,8 +147,29 @@ rowList.evaluate(function(rowListClient) {

var options = {
title:'NDVI Time-Series Box Plot',
vAxis: {title: 'NDVI'},
hAxis: {title: '', format: 'YYYY-MMM'},
vAxis: {
title: 'NDVI',
gridlines: {
color: '#d9d9d9'
},
minorGridlines: {
color: 'transparent'
}
},
hAxis: {
title: '',
format: 'YYYY-MMM',
viewWindow: {
min: new Date(2017, 0),
max: new Date(2018, 0)
},
gridlines: {
color: '#d9d9d9'
},
minorGridlines: {
color: 'transparent'
}
},
legend: {position: 'none'},
lineWidth: 1,
series: [{'color': '#D3362D'}],
Expand All @@ -165,7 +191,8 @@ rowList.evaluate(function(rowListClient) {
fillOpacity: 1,
color: '#777777'
}
}
},
chartArea: {left:100, right:100}
};

var chart = ui.Chart(dataTable, 'LineChart', options);
Expand Down
48 changes: 39 additions & 9 deletions code/gee_charts/04-Advanced_Charts/02b_Box_Plots_(exercise)
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,15 @@ var values = withNdvi.map(function(image) {
'p25': stats.get('ndvi_p25'),
'p50': stats.get('ndvi_p50'),
'p75': stats.get('ndvi_p75'),
}
return ee.Feature(null, properties)
};
return ee.Feature(null, properties);

});

// Remove null values
var values = values.filter(ee.Filter.notNull(
['median', 'min', 'max', 'p25', 'p50', 'p75']));

})
// Format the results as a list of DataTable rows

// We need a list to map() over
Expand All @@ -94,9 +99,9 @@ var dateList = values.aggregate_array('date');
// '2017-01-01' becomes 'Date(2017,0,1)'
// month is indexed from 0 in Date String representation
function formatDate(date) {
var year = ee.Date(date).get('year').format()
var month = ee.Date(date).get('month').subtract(1).format()
var day = ee.Date(date).get('day').format()
var year = ee.Date(date).get('year').format();
var month = ee.Date(date).get('month').subtract(1).format();
var day = ee.Date(date).get('day').format();
return ee.String('Date(')
.cat(year)
.cat(', ')
Expand Down Expand Up @@ -143,8 +148,32 @@ rowList.evaluate(function(rowListClient) {

var options = {
title:'NDVI Time-Series Box Plot',
vAxis: {title: 'NDVI'},
hAxis: {title: '', format: 'YYYY-MMM'},
vAxis: {
title: 'NDVI',
gridlines: {
color: '#d9d9d9'
},
minorGridlines: {
color: 'transparent'
},
viewWindow: {
max: 1
}
},
hAxis: {
title: '',
format: 'YYYY-MMM',
viewWindow: {
min: new Date(2017, 0),
max: new Date(2018, 0)
},
gridlines: {
color: '#d9d9d9'
},
minorGridlines: {
color: 'transparent'
}
},
legend: {position: 'none'},
lineWidth: 1,
series: [{'color': '#D3362D'}],
Expand All @@ -166,7 +195,8 @@ rowList.evaluate(function(rowListClient) {
fillOpacity: 1,
color: '#777777'
}
}
},
chartArea: {left:100, right:100}
};

var chart = ui.Chart(dataTable, 'LineChart', options);
Expand Down
215 changes: 215 additions & 0 deletions code/gee_charts/Supplement/Box_Plot_with_Outliers
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
// Example script showing how to create a box plot with outliers.
var s2 = ee.ImageCollection('COPERNICUS/S2_HARMONIZED');
var geometry = ee.Geometry.Polygon([[
[82.60642647743225, 27.16350437805251],
[82.60984897613525, 27.1618529901377],
[82.61088967323303, 27.163695288375266],
[82.60757446289062, 27.16517483230927]
]]);

Map.addLayer(geometry, {color: 'red'}, 'Farm');
Map.centerObject(geometry);
var rgbVis = {min: 0.0, max: 3000, bands: ['B4', 'B3', 'B2']};

var filtered = s2
.filter(ee.Filter.date('2017-01-01', '2018-01-01'))
.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 30))
.filter(ee.Filter.bounds(geometry));

// Write a function for Cloud masking
function maskS2clouds(image) {
var qa = image.select('QA60');
var cloudBitMask = 1 << 10;
var cirrusBitMask = 1 << 11;
var mask = qa.bitwiseAnd(cloudBitMask).eq(0).and(
qa.bitwiseAnd(cirrusBitMask).eq(0));
return image.updateMask(mask).multiply(0.0001)
.select('B.*')
.copyProperties(image, ['system:time_start']);
}

var filtered = filtered.map(maskS2clouds);
// Write a function that computes NDVI for an image and adds it as a band
function addNDVI(image) {
var ndvi = image.normalizedDifference(['B8', 'B4']).rename('ndvi');
return image.addBands(ndvi);
}

// Map the function over the collection
var withNdvi = filtered.map(addNDVI);

// Extract the values from each image
var values = withNdvi.map(function(image) {
var ndvi = image.select('ndvi');

var allReducers = ee.Reducer.median()
.combine({reducer2: ee.Reducer.min(), sharedInputs: true} )
.combine({reducer2: ee.Reducer.max(), sharedInputs: true} )
.combine({reducer2: ee.Reducer.percentile([25]), sharedInputs: true} )
.combine({reducer2: ee.Reducer.percentile([50]), sharedInputs: true} )
.combine({reducer2: ee.Reducer.percentile([75]), sharedInputs: true} )

var stats = ndvi.reduceRegion({
reducer: allReducers,
geometry: geometry,
scale: 10});
var date = image.date();
var dateString = date.format('YYYY-MM-dd');

var properties = {
'date': dateString,
'median': stats.get('ndvi_p50'), // median is 50th percentile
'min': stats.get('ndvi_min'),
'max': stats.get('ndvi_max'),
'p25': stats.get('ndvi_p25'),
'p50': stats.get('ndvi_p50'),
'p75': stats.get('ndvi_p75'),
}
return ee.Feature(null, properties)

})
// Remove null values
var values = values.filter(ee.Filter.notNull(
['median', 'min', 'max', 'p25', 'p50', 'p75']));
print(values)

// Format the results as a list of DataTable rows

// We need a list to map() over
var dateList = values.aggregate_array('date');

// Helper function to format dates as per DataTable requirements
// Converts date strings
// '2017-01-01' becomes 'Date(2017,0,1)'
// month is indexed from 0 in Date String representation
function formatDate(date) {
var year = ee.Date(date).get('year').format()
var month = ee.Date(date).get('month').subtract(1).format()
var day = ee.Date(date).get('day').format()
return ee.String('Date(')
.cat(year)
.cat(', ')
.cat(month)
.cat(', ')
.cat(day)
.cat(ee.String(')'));
}

// We will compute the values to display whiskers
// at 1.5*(Inter-Quartile Range)
// If the minimum or maximum values fall outside
// if this range, they will be considered outliers.
var rowList = dateList.map(function(date) {
var f = values.filter(ee.Filter.eq('date', date)).first();
var x = formatDate(date);
var median = f.getNumber('median');
var p25 = f.getNumber('p25');
var p50 = f.getNumber('p50');
var p75 = f.getNumber('p75');
// Compute min/max as the Inter-Quartile Range (IQR)
var min = ee.Number.expression('p25 - 1.5*(p75-p25)', {
p75: ee.Number(p75),
p25: ee.Number(p25)})
var max = ee.Number.expression('p75 + 1.5*(p75-p25)', {
p75: ee.Number(p75),
p25: ee.Number(p25)})
var minValue = f.getNumber('min');
var maxValue = f.getNumber('max');
// Add the outlier if they are outside of IQR
var minOutlier = ee.Algorithms.If(minValue.lt(min), minValue, null);
var maxOutlier = ee.Algorithms.If(maxValue.gt(max), maxValue, null);
var rowDict = {
c: [{v: x}, {v: median}, {v: minOutlier}, {v: maxOutlier}, {v: min}, {v: max},
{v: p25}, {v: p50}, {v: p75}]
};
return rowDict;
});

print('Rows', rowList);

// We need to convert the server-side rowList object
// to client-side javascript object
// use evaluate()
rowList.evaluate(function(rowListClient) {
var dataTable = {
cols: [
{id: 'x', type: 'date'},
{id: 'median', type: 'number'},
{id: 'minOutlier', type: 'number', role: 'interval'},
{id: 'maxOutlier', type: 'number', role: 'interval'},
{id: 'min', type: 'number', role: 'interval'},
{id: 'max', type: 'number', role: 'interval'},
{id: 'firstQuartile', type: 'number', role: 'interval'},
{id: 'median', type: 'number', role: 'interval'},
{id: 'thirdQuartile', type:'number', role: 'interval'},

],
rows: rowListClient
};

var options = {
title:'NDVI Time-Series Box Plot with Outliers',
vAxis: {
title: 'NDVI',
gridlines: {
color: '#d9d9d9'
},
minorGridlines: {
color: 'transparent'
},
viewWindow: {
min: -0.2,
max: 1
}
},
hAxis: {
title: '',
format: 'YYYY-MMM',
viewWindow: {
min: new Date(2017, 0),
max: new Date(2018, 0)
},
gridlines: {
color: '#d9d9d9'
},
minorGridlines: {
color: 'transparent'
}
},
legend: {position: 'none'},
lineWidth: 1,
series: [{'color': '#D3362D'}],
interpolateNulls: true,
intervals: {
barWidth: 2,
boxWidth: 4,
lineWidth: 1,
style: 'boxes'
},
interval: {
min: {
style: 'bars',
fillOpacity: 1,
color: '#777777'
},
max: {
style: 'bars',
fillOpacity: 1,
color: '#777777'
},
minOutlier: {
style: 'points',
pointSize: 2
},
maxOutlier: {
style: 'points',
pointSize: 2
},
},
chartArea: {left:100, right:100}
};

var chart = ui.Chart(dataTable, 'LineChart', options);
print(chart);
});

Loading

0 comments on commit ed532ef

Please sign in to comment.