0

I have been trying to create a bar chart from a list containing the number of Landsat images aggregated per year for my point of interest.

I have tried to create a bar chart from an array, and I have also tried from a data table. But I am missing the trick. Could you please help me out with that? Here is my code:

var locat = ee.Geometry.Point(-40.967627131182304, -21.33089753065459); //point of interest

//Select the period
var start='1985-01-1';
var end='2020-12-31';

// Filter Landsat collection for the specified area
var collection8 = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR')
  .filterDate(start, end)
  .filterBounds(locat)
  .select(['B2','B3','B4','B5','B6','B7'],
  ['blue','green','red','NIR','SWIR1','SWIR2']);
var collection7 = ee.ImageCollection('LANDSAT/LE07/C01/T1_SR')
  .filterDate(start, end)
  .filterBounds(locat)
  .select(['B1','B2','B3','B4','B5','B7'],
  ['blue','green','red','NIR','SWIR1','SWIR2']);
var collection5 = ee.ImageCollection('LANDSAT/LT05/C01/T1_SR')
  .filterDate(start, end)
  .filterBounds(locat)
  .select(['B1','B2','B3','B4','B5','B7'],
  ['blue','green','red','NIR','SWIR1','SWIR2']);
var collection4 = ee.ImageCollection('LANDSAT/LT04/C01/T1_SR')
  .filterDate(start, end)
  .filterBounds(locat)
  .select(['B1','B2','B3','B4','B5','B7'],
  ['blue','green','red','NIR','SWIR1','SWIR2']);
//Merge all the collections
var collection=collection8.merge(collection7).merge(collection5).merge(collection4)
  .sort('CLOUD_COVER', true);

//Get the imagery list
var imagery_list =collection.toList(collection.size());

// creating sequence of years 
var year_num = ee.List.sequence(1985, 2020, 1);

// mapping sequence of years to string format and slicing only the round numbers of an year
var years = year_num.map(function (years) { return ee.String(years).slice(0,4)});

//Getting the number of Landsat per year
// mapping filter over the list of years (string format) to get the number of elements in the imagery_list that match string year 

// mapping filter the over the list of years (string format) to get the number of elements in the imagery_list that match string year 
// it returns list with the the number of images per year
// Here I am only interested in the length of the sub lists (the number of images), therefore I used .length() ate the end
var Ltmap = years.map(function(year){
  var LtYearLs = imagery_list.filter(ee.Filter.stringContains('SENSING_TIME', year)).length();
   return LtYearLs;
}); 

// create a dictionary with number of images (value) per year (key)
var Ltdict = ee.Dictionary.fromLists(years, Ltmap);
print(Ltdict, 'Ltdict' );

// create a data table or array to produce the bar charts
// here I where I assume is my problem

var dataTable = [
  [
    {label: 'Image Year', role: 'domain', type: 'string'},
    {label: 'Number of images', role: 'data', type: 'number'},
  ],
[ Ltdict.keys(), Ltdict.values()]
];

// Define the chart and print it to the console.
var chart = ui.Chart(dataTable).setChartType('ColumnChart').setOptions({
  title: 'Landsat images per Year',
  legend: {position: 'none'},
  hAxis: {title: 'Images', titleTextStyle: {italic: false, bold: true}},
  vAxis: {title: 'Year', titleTextStyle: {italic: false, bold: true}},
  colors: ['1d6b99']
});
print(chart);

What I expect to get is something like this bar chart: https://i.stack.imgur.com/MjREF.png

I really appreciated your help.

pbastosd
  • 3
  • 1

1 Answers1

0

Try this:

var locat = ee.Geometry.Point(-40.967627131182304, -21.33089753065459); //point of interest

//Select the period
var start='1985-01-1';
var end='2020-12-31';

// Filter Landsat collection for the specified area
var collection8 = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR')
  .filterDate(start, end)
  .filterBounds(locat)
  .select(['B2','B3','B4','B5','B6','B7'],
  ['blue','green','red','NIR','SWIR1','SWIR2']);
var collection7 = ee.ImageCollection('LANDSAT/LE07/C01/T1_SR')
  .filterDate(start, end)
  .filterBounds(locat)
  .select(['B1','B2','B3','B4','B5','B7'],
  ['blue','green','red','NIR','SWIR1','SWIR2']);
var collection5 = ee.ImageCollection('LANDSAT/LT05/C01/T1_SR')
  .filterDate(start, end)
  .filterBounds(locat)
  .select(['B1','B2','B3','B4','B5','B7'],
  ['blue','green','red','NIR','SWIR1','SWIR2']);
var collection4 = ee.ImageCollection('LANDSAT/LT04/C01/T1_SR')
  .filterDate(start, end)
  .filterBounds(locat)
  .select(['B1','B2','B3','B4','B5','B7'],
  ['blue','green','red','NIR','SWIR1','SWIR2']);
//Merge all the collections
var collection=collection8.merge(collection7).merge(collection5).merge(collection4)
  .sort('CLOUD_COVER', true);

var years = ee.List.sequence(ee.Date(start).get('year'), ee.Date(end).get('year'));

/// This function calculates the amount of images per year
var annualFunction = function(collection) {
return ee.ImageCollection.fromImages(
years.map(function (y) {
var w = collection
.filter(ee.Filter.bounds(locat))
.filter(ee.Filter.calendarRange(y, y, 'year'))
.count();
return w.set('year', y)
.set('system:time_start', ee.Date.fromYMD(y, 1, 1)); 
}).flatten())};

var collectionAnnual = annualFunction(collection)

var chart = ui.Chart.image.series({
  imageCollection: collectionAnnual,
  region: locat,
  reducer: ee.Reducer.sum(),
  scale: 30, // resolution of Landsat
})

print(chart)
CrossLord
  • 574
  • 4
  • 20
  • That worked well. Thank you very much @CrossLord. I only added `.setChartType('ColumnChart') ` to the `var chart` and got exactly what I was looking for. – pbastosd Oct 27 '21 at 15:02
  • Great! Please consider accepting the answer if your questions are answered – CrossLord Oct 27 '21 at 19:32