In EO Browser, you can view two kinds of statistical information for your imagery: a line chart of values through time for either a point or a polygon, and a histogram of values (see the chapter Statistical Analysis on our EO Browser page). To enable statistical features, an evalscript supporting statistical API should be used in your layers.
Because statistics operates on the indicator values themselves (and not on RGB), you must add an additional output to the evalscript, which returns the value without conversion to color. For example, statistics can be calculated for values of B04 or for an index like NDVI. Additionally, the evalscript should include dataMask to exclude no-data values from the calculation (no-data pixels often have value 0, which could skew the statistics), and it’s also recommended to check for presence of clouds, so we can exclude them as well (cloudy pixels usually have very high values, which could also skew the results). The user can exclude any pixels from the statistics, such as for example snow or water.
The evalscript should contain the following outputs, with the exact same names:
default
: Mandatory. A visualization output, that defines what will be displayed on the map. The visualization can return anything you like, a single value grayscale, an RGB visualization, etc.index
: Optional. Returning the raw values of your index, enabling the histogram functionality. Use FLOAT32 format to include decimals and negative values.eobrowserStats
: Mandatory. An output containing both the index values and cloud information, used for line chart generation. Cloud information will allow us to filter the tiles by maximum cloud coverage. Use FLOAT32 format to include decimals and negative values.dataMask
Mandatory. A dataMask output to take no-data values into account.Here is an example evalscript for NDVI:
//VERSION=3
function setup() {
return {
input: ["B04", "B08", "SCL","dataMask"],
//The four outputs should be setup here in the setup function, and defined under the evaluatePixel function.
output: [
{ id: "default", bands: 4 },
{ id: "index", bands: 1, sampleType: 'FLOAT32' },
{ id: "eobrowserStats", bands: 2, sampleType: 'FLOAT32' },
{ id: "dataMask", bands: 1 }
]
};
}
// Optional filtering for clouds using the Sentinel-2A SCL band (values 1, 2, 7, 8, 9, 10, 11 are either clouds or snow)
function isCloud (scl) {
if ([1, 2, 7, 8, 9, 10, 11].includes(scl)) {
return false;
}
}
function evaluatePixel(samples) {
let val = index(samples.B08, samples.B04); // NDVI calculation
let imgVals = null;
const indexVal = samples.dataMask === 1 ? val : NaN; //NDVI index without no-data values
const cloud = isCloud(samples.SCL) //calling in our cloud filtering functon as a cloud variable
//Define the RGB NDVI visualization and write it into imgVals
if (val<-0.5) imgVals = [0.05,0.05,0.05,samples.dataMask];
else if (val<-0.2) imgVals = [0.75,0.75,0.75,samples.dataMask];
else if (val<-0.1) imgVals = [0.86,0.86,0.86,samples.dataMask];
else if (val<0) imgVals = [0.92,0.92,0.92,samples.dataMask];
else if (val<0.025) imgVals = [1,0.98,0.8,samples.dataMask];
else if (val<0.05) imgVals = [0.93,0.91,0.71,samples.dataMask];
else if (val<0.075) imgVals = [0.87,0.85,0.61,samples.dataMask];
else if (val<0.1) imgVals = [0.8,0.78,0.51,samples.dataMask];
else if (val<0.125) imgVals = [0.74,0.72,0.42,samples.dataMask];
else if (val<0.15) imgVals = [0.69,0.76,0.38,samples.dataMask];
else if (val<0.175) imgVals = [0.64,0.8,0.35,samples.dataMask];
else if (val<0.2) imgVals = [0.57,0.75,0.32,samples.dataMask];
else if (val<0.25) imgVals = [0.5,0.7,0.28,samples.dataMask];
else if (val<0.3) imgVals = [0.44,0.64,0.25,samples.dataMask];
else if (val<0.35) imgVals = [0.38,0.59,0.21,samples.dataMask];
else if (val<0.4) imgVals = [0.31,0.54,0.18,samples.dataMask];
else if (val<0.45) imgVals = [0.25,0.49,0.14,samples.dataMask];
else if (val<0.5) imgVals = [0.19,0.43,0.11,samples.dataMask];
else if (val<0.55) imgVals = [0.13,0.38,0.07,samples.dataMask];
else if (val<0.6) imgVals = [0.06,0.33,0.04,samples.dataMask];
else imgVals = [0,0.27,0,samples.dataMask];
// Return the 4 inputs and define content for each one
return {
default: imgVals,
index: [indexVal],
eobrowserStats: [indexVal,cloud?1:0],
dataMask: [samples.dataMask]
};
}
See the script in EO Browser.
The evalscript can be used directly in EO Browser using the custom script function, or setup for the layer within the Sentinel Hub Configuration Utility.
When you create a custom layer, it is possible to select the same layer in EO Browser. See the section 2 of this FAQ to see how to visualize your configuration in EO Browser, or follow the steps below.
For more information on how to create configurations and layers see our Webinar, and for BYOC collections, see this FAQ.