I would like to download daily mean AOD data. I already did, but I got a file with 6015 rows and only ten rows with data, the rest of raws are empty.
How can I download only the data available?
var clipToCol = function(image){
return image.clip(buff1k)};
var AOD = ee.ImageCollection('MODIS/006/MCD19A2_GRANULES')
.select('Optical_Depth_055')
.filterDate('2019-07-10', '2019-07-15').map(clipToCol);
//.filterBounds(RMSP);
var band_viz = {
min: 0,
max: 350,
palette: ['black', 'blue', 'purple', 'cyan', 'green', 'yellow', 'red']
};
Map.addLayer(AOD.mean(), band_viz, 'Optical Depth 055');
var outline = ee.Image().byte().paint({
featureCollection: buff1k,
color: 1,
width: 1
});
Map.addLayer(outline, {palette: ['black']}, 'buff1k');
Map.setCenter(-46.63203, -23.55221, 9);
var AODmean_2 = AOD.map(function(img) {
return img.reduceRegions({
collection: buff1k,
reducer: ee.Reducer.mean(),
scale: 1000,
}).map(function(f){
return f.set('date', img.date());
});
}).flatten();
Export.table.toDrive({
collection:AODmean_2,
folder: "Google EE results",
selectors:(["date","mean"]),
});
Use a notNull filter on the collection: change
collection:AODmean_2,
to
collection: AODmean_2.filter(ee.Filter.notNull(["mean"])),
Related
I am using Google Charts - Line Chart to show a weeks trend(x-axis) to Cost(y-axis).
Now if i span the number of weeks in past 9 months, then most of the x-axis labels are hidden because of the space constraint.
I am trying to show an axis label only for the first week of a month and have set blank to the rest.
Is there a way to show all of the 9 labels(first week of each month) for 9 months
to show specific axis labels, use config option --> hAxis.ticks
ticks takes an array of values, each value will be shown as a label.
the value should be the same type as the x-axis values in the data table.
if you are using dates, then the array should be filled with date values.
hAxis: {
ticks: [new Date(2018, 0, 1), new Date(2018, 1, 1), new Date(2018, 2, 1), ...]
}
you can also use object notation to fill the array,
using object notation, you can provide the value (v:) and the formatted value (f:).
hAxis: {
ticks: [{v: new Date(2018, 0, 1), f: '01/01/2018'}, {v: new Date(2018, 1, 1), f: '02/01/2018'}, ...]
}
see following working snippet, the data and ticks are built dynamically...
google.charts.load('current', {
callback: function () {
drawChart();
window.addEventListener('resize', drawChart, false);
},
packages:['corechart']
});
function drawChart() {
var datePattern = 'MM/dd/yyyy';
var formatDate = new google.visualization.DateFormat({
pattern: datePattern
});
var dataTable = new google.visualization.DataTable();
dataTable.addColumn('date', 'X');
dataTable.addColumn('number', 'Value');
var oneDay = (1000 * 60 * 60 * 24);
var startDate = new Date(2018, 0, 1);
var endDate = new Date(2018, 9, 0);
var ticksAxisH = [];
for (var i = startDate.getTime(); i <= endDate.getTime(); i = i + oneDay) {
// set x value
var rowDate = new Date(i);
var xValue = {
v: rowDate,
f: formatDate.formatValue(rowDate)
};
// add tick at beginning of each month
if (rowDate.getDate() === 1) {
ticksAxisH.push(xValue);
}
// set y value (y = 2x + 8)
var yValue = (2 * ((i - startDate.getTime()) / oneDay) + 8);
// add data row
dataTable.addRow([
xValue,
yValue
]);
}
var container = document.getElementById('chart_div');
var chart = new google.visualization.LineChart(container);
chart.draw(dataTable, {
chartArea: {
height: '100%',
width: '100%',
top: 32,
left: 48,
right: 18,
bottom: 32
},
hAxis: {
ticks: ticksAxisH
},
height: 288,
legend: {
position: 'top'
},
width: '100%'
});
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
I have a datatable created from database data that gets aggregated by google.visualization.data.group, then fed into a columnChart.
By default, the resulting chart's bars are all the same color but i would like to make the bars different colors (by iterating through the datatable and assigning a different color to each row in the datable).For now, i'll just try to assign the colour 'gold' to each bar, for simplicity.
This is the documentation for a columnChart and is the documentation for style roles.
I don't think my code can be far wrong:
var groupedCategoryData = new google.visualization.data.group(
stacked01Data, // arg 1 is the array of input data
[{ // arg 2 is the key (An array of numbers/objects being columns to group by)
column: 0, type: 'string'
}],
[{ 'column': 1, 'aggregation': google.visualization.data.avg, 'type': 'number' }]
);//group. col 1 = score
//*****************
groupedCategoryData.addColumn({ type: 'string', role: 'style' });
for (var i = 0; i < groupedCategoryData.length; i++) {
groupedCategoryData[i][2] = 'color: gold';
}//for
//*****************
var stacked01_options = {
width: 500,
height: 300
};//options
var stacked01 = new google.visualization.ColumnChart(document.getElementById('stackedChart01_div'));
stacked01.draw(groupedCategoryData, stacked01_options);
The result is a chart whose bars are all default blue. I admit this is my first foray into javascript. any help would be appreciated.
Yep, that did it. thanks WhiteHat. working code:
//include the bar color data
var colorsGreen = [
[0, 1, '#6AB293'],
[1, 2, '#449371'],
[2, 3, '#277553'],
[3, 4, '#115639'],
[4, 5, '#043822']
];
groupedCategoryData.addColumn('string', 'barColor');
var groupedCategoryDataView = new google.visualization.DataView(groupedCategoryData);
groupedCategoryDataView.setColumns([0, 1, {
calc: function (dt, row) {
var rowValue = dt.getValue(row, 1);
var color;
colorsGreen.forEach(function (range, index) {
if ((rowValue >= range[0]) && ((rowValue < range[1]) || (range[1] === null))) {
color = range[2];
}
});
return color;
},
role: 'style',
type: 'string'
}]);
var stacked01_options = {
width: 500,
height: 300
};//options
var stacked01 = new google.visualization.ColumnChart(document.getElementById('stackedChart01_div'));
stacked01.draw(groupedCategoryDataView, stacked01_options);
}
so browsers throw
warning about using momentJS incorrectly.
Deprecation warning: value provided is not in a recognized ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.
Arguments:
[0] _isAMomentObject: true, _isUTC: false, _useUTC: false, _l: undefined, _i: 12.30, _f: false, _strict: undefined, _locale: [object Object]
Error
So i looked at my code
data: {
labels: ['01.01', '02.01', '03.01', '04.01', '05.01', '06.01', '07.01', '08.01', '09.01', '10.01', '11.01', '12.01'],
datasets: createChatterData(data, this)
},
And read that I should provide a format when dealing with non iso strings.
labels: [moment('01.01', 'MM.DD'), moment('02.01', 'MM.DD'), ...];
Ok that removed first deprecation.
But my datasets data also contains of date
dataset.data.pushObject({
x: moment(datum).format('MM.DD'),
y: parseInt(moment(datum).format('YYYY'))
});
So I tried different variations to that (premodified ambigious datetime)
x: moment(date, 'YYYY.MM.DD').format('MM.DD')
and
x: moment(date, 'MM.DD')
But my graph doesnt map correctly anymore.
Example of codepen chart working in chrome: http://codepen.io/kristjanrein/pen/wJrQLE
Does not display in firefox/opera
I see a couple of issues here.
1) Since you want your X axis to be a time scale, then you should leave your X data value as a moment object. Your current implementation is creating a moment object from a date string and then formatting it back to a string. When you do this, chart.js then takes the string and tries to create a moment object internally when it builds the chart.
Therefore, It is best to keep the data as either a Date or Moment object and use the time scale configuration properties to determine how the data is displayed on the chart. This prevents chart.js from having to construct the moment object and guess at the string format.
2) You are using the pre-2.0 way to create a chart when you use Chart.Scatter. Instead you should use the new style (new Chart()) and pass in a type property.
Here is a modified version of you code that results in no browser warnings and works in Chrome and Firefox (I did not test in Opera).
var getData = function() {
var dummyDataset = [
'2007-11-09T00:00:00.000Z',
'2006-08-04T00:00:00.000Z',
'2006-08-06T00:00:00.000Z',
'2008-01-10T00:00:00.000Z'
];
return dummyDataset.map(function(datum) {
var myMoment = moment(datum);
return {
x: myMoment,
y: parseInt(myMoment.format('YYYY')),
};
});
};
var ctx = document.getElementById("chart1").getContext("2d");
var myScatter = new Chart(ctx, {
type: 'line',
data: {
datasets: [{
label: "My First dataset",
borderColor: 'rgb(255, 99, 132)',
fill: false,
pointRadius: 4,
pointHoverRadius: 8,
showLine: false,
data: getData()
}]
},
options: {
responsive: true,
title: {
display: true,
text: 'Random Data'
},
legend: {
display: true,
labels: {
fontSize: 10,
boxWidth: 20
}
},
elements: {
point: {
pointStyle: 'rect'
}
},
hover: {
mode: 'nearest'
},
scales: {
xAxes: [{
type: 'time',
position: 'bottom',
scaleLabel: {
display: true,
labelString: 'Months'
},
time: {
unit: 'month',
displayFormats: {
month: 'MM'
},
}
}],
yAxes: [ {
type: 'linear',
ticks: {
min: 2005,
max: 2015,
stepSize: 1
},
scaleLabel: {
display: true,
labelString: 'Year'
}
}]
}
}
});
You can see it in action at this forked codepen.
One other thing to keep in mind is that because your data spans multiple years, you will see duplicate months on the X axis. Remember, a time scale is used to plot dates so even if you only display the months, a data point with the same month but with different years will not be plotted at the same location.
If you are actually only wanting to show month string/number values in the X axis, then you should not use the time scale at all and use the linear scale instead. Then when you build your data values, you would extract the month from the data (the same way you are already doing for your Y value).
var getData = function() {
var dummyDataset = [
'2007-11-09T00:00:00.000Z',
'2006-08-04T00:00:00.000Z',
'2006-08-06T00:00:00.000Z',
'2008-01-10T00:00:00.000Z'
];
return dummyDataset.map(function(datum) {
var myMoment = moment(datum);
return {
x: parseInt(myMoment.format('MM')),
y: parseInt(myMoment.format('YYYY')),
};
});
};
So in addition to jordan's answer
I changed my labels and x axis from
['01.01', '02.01', ...] to [1,2,...]
and
from type: 'time' to type: 'linear'
And to make it map not only by month but also by day. I had to make date objects to correct floats. 05.20 to 5.66
const date = datum.key;
const day = parseInt(moment(date).format('DD')) / 30 * 100;
const fullDate = parseFloat(moment(date).format('MM') + '.' + Math.round(day))
// 05.10 would be 5.3 (10 of 30 is 33%)
{
x: fullDate,
y: parseInt(moment(date).format('YYYY'))
date: date, // for tooltip
count: count // for tooltip
}
And i also had to make corrections to my tooltips
callbacks: {
title: function([tooltipItem], data) {
const tooltipInfo = getTooltip(tooltipItem, data.datasets);
return tooltipInfo.date;
},
label: function(tooltipItem, data) {
const tooltipInfo = getTooltip(tooltipItem, data.datasets);
return i18n.t('chart.count') + ': ' + tooltipInfo.count;
},
}
corresponding tooltip dataset
function getTooltip(tooltipItem, datasets) {
return datasets[tooltipItem.datasetIndex].data.find(datum => {
return datum.x === tooltipItem.xLabel && datum.y === tooltipItem.yLabel;
});
}
I would like to know if it's possible to have line chart series names divided in two rows, with a label in addition (Group1 and Group2 from the photo). On the picture below you can see what I want to create.
If not, is it at least possible to divide series names in two rows (without labels)?
Here is the photo:
This is an example from a kendo ui homepage, here you can find the source code: link
I think you would need to play around with the legend width and the legend item visual:
DEMO
legend: {
position: "bottom",
width: 360,
item: {
visual: function (e) {
console.log(e);
var group = "";
var rect = new kendo.geometry.Rect([0, 0], [140, 50]);
if (e.series.name == "1. GOOG (close)"){
group = "Group 1: ";
rect = new kendo.geometry.Rect([0, 0], [200, 50]);
} else if (e.series.name == "3. AMZN (close)"){
group = "Group 2: ";
rect = new kendo.geometry.Rect([0, 0], [200, 50]);
}
var color = e.options.markers.background;
var labelColor = e.options.labels.color;
var layout = new kendo.drawing.Layout(rect, {
spacing: 5,
alignItems: "center"
});
var grplabel = new kendo.drawing.Text(group, [0, 0], {
fill: {
color: "#000"
}
});
var marker = new kendo.drawing.Path({
fill: {
color: color
},
stroke : {
color: color
}
}).moveTo(10, 0).lineTo(10, 10).lineTo(0, 10).lineTo(0, 0).close();
var label = new kendo.drawing.Text(e.series.name, [0, 0], {
fill: {
color: labelColor
}
});
layout.append(grplabel, marker, label);
layout.reflow()
return layout;
}
}
},
In the demo, I am checking the series name and adding the group label to the first and third series. The the legend width is set so that it wraps to a second line. NOTE: there is some trial and error to make this work with your data...
My problem is that the datagrid does not appear I need it to be empty so I can add items to do a relation with a existing FilteringSelect Formatter.
function formatter1() {
var x = new FilteringSelect({
name: "Account Select",
//value: "1",
store: remoteData,
searchAttr: "name",
onChange: function () {
console.log("EI");
}
});
x._destroyOnRemove=true;
return x;
}
// Relations data grid
var DataRelations = { identifier: "id", items: [] };
storeRelations = new Write({data: DataRelations, clearOnClose: true });
var layoutRelations = [
{'name': "Words", field: "word", width: 40 },
{'name': "Account", field: "id", width: 40, formatter: formatter1 }
//,{'name': "Accounts Available", field: "AccountsAvailable", width: 20, formatter: formatter1}
];
var gridRelations = new DataGrid({
id: 'gridRelations',
store: storeRelations,
structure: layoutRelations,
rowSelector: '10px'
});
/*append the new grid to the div*/
gridRelations.placeAt("gridDivRelations");
/*Call startup() to render the grid*/
gridRelations.startup();
here is a working jsfiddle based on your code:
http://jsfiddle.net/LFk8Z/
You need to specify a width and a height for the DIV container of the grid. Maybe that was the initial problem. Also you need to load the grid css resources. Your formatter function did not have a paramater, but you need to specify one:
function formatter1(x) {
// Format cell value (which is in x) in here.
}