La función ui.Chart
renderiza gráficos a partir de un objeto JSON del cliente que sigue la misma estructura que la clase DataTable
de Google Charts, pero carece de métodos y mutabilidad de DataTable
. Básicamente, es una tabla 2D con filas que representan observaciones y columnas que representan atributos de observación. Proporciona una interfaz base y flexible para la creación de gráficos en Earth Engine. Es una buena opción cuando se requiere un alto grado de personalización de los gráficos.
DataTable
esquema
Existen dos maneras de definir un pseudo-DataTable
en Earth Engine: un array 2D de JavaScript y un objeto literal de JavaScript. Para la mayoría de las aplicaciones, el enfoque más sencillo será construir un array 2D. En ambos casos, la tabla que se pasa a ui.Chart
debe ser un objeto del cliente. Una tabla codificada de forma manual será inherentemente del cliente, mientras que un objeto calculado deberá transferirse del cliente con evaluate
. Consulta la página Cliente frente a servidor para obtener más información sobre la distinción entre objetos del cliente y del servidor.
Array de JavaScript
Un DataTable
de 2D se compone de un array de filas y columnas. Las filas son observaciones y las columnas son atributos. La primera columna define los valores del
eje X, mientras que las columnas adicionales definen los valores de las series del eje Y. Se espera que la primera fila sea un encabezado de columna. El encabezado más simple es una serie de etiquetas de columna, que se muestra en el siguiente array DataTable
que relaciona la población por estados seleccionados.
var dataTable = [ ['State', 'Population'], ['CA', 37253956], ['NY', 19378102], ['IL', 12830632], ['MI', 9883640], ['OR', 3831074], ];
De manera opcional, las columnas se pueden asignar a un rol distinto de definir el dominio (eje x) y los datos (serie del eje y), p.ej., anotación, intervalos, información sobre herramientas o estilo. En el siguiente ejemplo, el array de encabezados se presenta como una serie de objetos, en los que se define explícitamente el rol de cada columna. Los roles de columna aceptables para cada tipo de gráfico de Google se pueden encontrar en su documentación respectiva, p.ej., Formato de datos del gráfico de columnas.
var dataTable = [ [{role: 'domain'}, {role: 'data'}, {role: 'annotation'}], ['CA', 37253956, '37.2e6'], ['NY', 19378102, '19.3e6'], ['IL', 12830632, '12.8e6'], ['MI', 9883640, '9.8e6'], ['OR', 3831074, '3.8e6'], ];
Las propiedades de las columnas se especifican de la siguiente manera:
Parámetro | Tipo | Definición |
---|---|---|
type |
cadena, recomendada | Tipo de datos de la columna: 'string' , 'number' , 'boolean' , 'date' , 'datetime' o 'timeofday' . |
label |
cadena, recomendada | Es una etiqueta para la columna, la etiqueta de la serie en la leyenda del gráfico. |
role |
cadena, recomendada | Un rol para la columna (p.ej., roles para el gráfico de columnas). |
pattern |
cadena, opcional | Es una cadena de formato de número (o fecha) que especifica cómo se mostrará el valor de la columna. |
Objeto de JavaScript
Un DataTable
puede tener el formato de un objeto literal de JavaScript en el que se proporcionan arreglos de objetos de fila y columna. Consulta esta
guía
para obtener instrucciones sobre cómo especificar parámetros de columnas y filas.
var dataTable = { cols: [{id: 'name', label: 'State', type: 'string'}, {id: 'pop', label: 'Population', type: 'number'}], rows: [{c: [{v: 'CA'}, {v: 37253956}]}, {c: [{v: 'NY'}, {v: 19378102}]}, {c: [{v: 'IL'}, {v: 12830632}]}, {c: [{v: 'MI'}, {v: 9883640}]}, {c: [{v: 'OR'}, {v: 3831074}]}] };
Gráfico manual de DataTable
Supongamos que tienes una pequeña cantidad de datos estáticos que deseas mostrar en un gráfico.
Usa las especificaciones del array o del objeto de JavaScript para crear una entrada que se pasará a la función ui.Chart
. Aquí, las poblaciones estatales seleccionadas del censo de EE.UU. de 2010 se codifican como un array de JavaScript con objetos de encabezado de columna que definen las propiedades de la columna. Ten en cuenta que la tercera columna está designada al rol de 'annotation'
, que agrega la propagación como una anotación a cada observación en el gráfico.
Editor de código (JavaScript)
// Define a DataTable using a JavaScript array with a column property header. var dataTable = [ [ {label: 'State', role: 'domain', type: 'string'}, {label: 'Population', role: 'data', type: 'number'}, {label: 'Pop. annotation', role: 'annotation', type: 'string'} ], ['CA', 37253956, '37.2e6'], ['NY', 19378102, '19.3e6'], ['IL', 12830632, '12.8e6'], ['MI', 9883640, '9.8e6'], ['OR', 3831074, '3.8e6'] ]; // Define the chart and print it to the console. var chart = ui.Chart(dataTable).setChartType('ColumnChart').setOptions({ title: 'State Population (US census, 2010)', legend: {position: 'none'}, hAxis: {title: 'State', titleTextStyle: {italic: false, bold: true}}, vAxis: {title: 'Population', titleTextStyle: {italic: false, bold: true}}, colors: ['1d6b99'] }); print(chart);
Gráfico DataTable
calculado
Se puede crear un array DataTable
a partir de un ee.List
2D que se pasa del servidor al cliente a través de evaluate
. Una situación común es convertir las propiedades de un ee.FeatureCollection
, ee.ImageCollection
o una reducción por elemento de estos en un DataTable
. La estrategia que se aplica en los siguientes ejemplos asigna una función a un ee.ImageCollection
que reduce el elemento determinado, ensambla un ee.List
a partir de los resultados de la reducción y adjunta la lista como una propiedad llamada 'row'
al elemento que se muestra. Cada elemento de la nueva recopilación tiene un ee.List
de 1 dimensión que representa una fila en un DataTable
.
La función aggregate_array()
se usa para agregar todas las propiedades 'row'
en un ee.List
superior para crear un ee.List
2D del servidor en la forma requerida para DataTable
. Se concatena un encabezado de columna personalizado a la tabla y el resultado se transfiere al cliente con evaluate
, donde se renderiza con la función ui.Chart
.
Series temporales por región
En este ejemplo, se muestra una serie temporal de índices de vegetación NDVI y EVI derivados de MODIS para una ecoregión boscosa. Cada imagen de la serie se reduce por la ecorregión y sus resultados se ensamblan como una propiedad 'row'
que se agrega a un DataTable
para pasar al cliente y crear gráficos con ui.Chart
. Ten en cuenta que este fragmento produce el mismo gráfico que genera el ejemplo de gráfico ui.Chart.image.series
.
Editor de código (JavaScript)
// Import the example feature collection and subset the forest feature. var forest = ee.FeatureCollection('projects/google/charts_feature_example') .filter(ee.Filter.eq('label', 'Forest')); // Load MODIS vegetation indices data and subset a decade of images. var vegIndices = ee.ImageCollection('MODIS/061/MOD13A1') .filter(ee.Filter.date('2010-01-01', '2020-01-01')) .select(['NDVI', 'EVI']); // Define a function to format an image timestamp as a JavaScript Date string. function formatDate(img) { var millis = img.date().millis().format(); return ee.String('Date(').cat(millis).cat(')'); } // Build a feature collection where each feature has a property that represents // a DataFrame row. var reductionTable = vegIndices.map(function(img) { // Reduce the image to the mean of pixels intersecting the forest ecoregion. var stat = img.reduceRegion( {reducer: ee.Reducer.mean(), geometry: forest, scale: 500}); // Extract the reduction results along with the image date. var date = formatDate(img); // x-axis values. var evi = stat.get('EVI'); // y-axis series 1 values. var ndvi = stat.get('NDVI'); // y-axis series 2 values. // Make a list of observation attributes to define a row in the DataTable. var row = ee.List([date, evi, ndvi]); // Return the row as a property of an ee.Feature. return ee.Feature(null, {'row': row}); }); // Aggregate the 'row' property from all features in the new feature collection // to make a server-side 2-D list (DataTable). var dataTableServer = reductionTable.aggregate_array('row'); // Define column names and properties for the DataTable. The order should // correspond to the order in the construction of the 'row' property above. var columnHeader = ee.List([[ {label: 'Date', role: 'domain', type: 'date'}, {label: 'EVI', role: 'data', type: 'number'}, {label: 'NDVI', role: 'data', type: 'number'} ]]); // Concatenate the column header to the table. dataTableServer = columnHeader.cat(dataTableServer); // Use 'evaluate' to transfer the server-side table to the client, define the // chart and print it to the console. dataTableServer.evaluate(function(dataTableClient) { var chart = ui.Chart(dataTableClient).setOptions({ title: 'Average Vegetation Index Value by Date for Forest', hAxis: { title: 'Date', titleTextStyle: {italic: false, bold: true}, }, vAxis: { title: 'Vegetation index (x1e4)', titleTextStyle: {italic: false, bold: true} }, lineWidth: 5, colors: ['e37d05', '1d6b99'], curveType: 'function' }); print(chart); });
Gráfico de intervalos
Este gráfico aprovecha la propiedad 'role'
de la columna DataTable
para generar un gráfico de intervalo.
El gráfico relaciona el perfil anual de NDVI y la varianza interanual de un píxel cerca de Monterey, California.
La mediana interanual se presenta como una línea, mientras que los intervalos absolutos y del cuartil se muestran como bandas. Las columnas de la tabla que representan cada intervalo se asignan como tales configurando la propiedad de la columna 'role'
como 'interval'
. Para dibujar bandas alrededor de la línea media, configura la propiedad del gráfico intervals.style
como 'area'
.
Editor de código (JavaScript)
// Define a point to extract an NDVI time series for. var geometry = ee.Geometry.Point([-121.679, 36.479]); // Define a band of interest (NDVI), import the MODIS vegetation index dataset, // and select the band. var band = 'NDVI'; var ndviCol = ee.ImageCollection('MODIS/006/MOD13Q1').select(band); // Map over the collection to add a day of year (doy) property to each image. ndviCol = ndviCol.map(function(img) { var doy = ee.Date(img.get('system:time_start')).getRelative('day', 'year'); // Add 8 to day of year number so that the doy label represents the middle of // the 16-day MODIS NDVI composite. return img.set('doy', ee.Number(doy).add(8)); }); // Join all coincident day of year observations into a set of image collections. var distinctDOY = ndviCol.filterDate('2013-01-01', '2014-01-01'); var filter = ee.Filter.equals({leftField: 'doy', rightField: 'doy'}); var join = ee.Join.saveAll('doy_matches'); var joinCol = ee.ImageCollection(join.apply(distinctDOY, ndviCol, filter)); // Calculate the absolute range, interquartile range, and median for the set // of images composing each coincident doy observation group. The result is // an image collection with an image representative per unique doy observation // with bands that describe the 0, 25, 50, 75, 100 percentiles for the set of // coincident doy images. var comp = ee.ImageCollection(joinCol.map(function(img) { var doyCol = ee.ImageCollection.fromImages(img.get('doy_matches')); return doyCol .reduce(ee.Reducer.percentile( [0, 25, 50, 75, 100], ['p0', 'p25', 'p50', 'p75', 'p100'])) .set({'doy': img.get('doy')}); })); // Extract the inter-annual NDVI doy percentile statistics for the // point of interest per unique doy representative. The result is // is a feature collection where each feature is a doy representative that // contains a property (row) describing the respective inter-annual NDVI // variance, formatted as a list of values. var reductionTable = comp.map(function(img) { var stats = ee.Dictionary(img.reduceRegion( {reducer: ee.Reducer.first(), geometry: geometry, scale: 250})); // Order the percentile reduction elements according to how you want columns // in the DataTable arranged (x-axis values need to be first). var row = ee.List([ img.get('doy'), // x-axis, day of year. stats.get(band + '_p50'), // y-axis, median. stats.get(band + '_p0'), // y-axis, min interval. stats.get(band + '_p25'), // y-axis, 1st quartile interval. stats.get(band + '_p75'), // y-axis, 3rd quartile interval. stats.get(band + '_p100') // y-axis, max interval. ]); // Return the row as a property of an ee.Feature. return ee.Feature(null, {row: row}); }); // Aggregate the 'row' properties to make a server-side 2-D array (DataTable). var dataTableServer = reductionTable.aggregate_array('row'); // Define column names and properties for the DataTable. The order should // correspond to the order in the construction of the 'row' property above. var columnHeader = ee.List([[ {label: 'Day of year', role: 'domain'}, {label: 'Median', role: 'data'}, {label: 'p0', role: 'interval'}, {label: 'p25', role: 'interval'}, {label: 'p75', role: 'interval'}, {label: 'p100', role: 'interval'} ]]); // Concatenate the column header to the table. dataTableServer = columnHeader.cat(dataTableServer); // Use 'evaluate' to transfer the server-side table to the client, define the // chart and print it to the console. dataTableServer.evaluate(function(dataTableClient) { var chart = ui.Chart(dataTableClient).setChartType('LineChart').setOptions({ title: 'Annual NDVI Time Series with Inter-Annual Variance', intervals: {style: 'area'}, hAxis: { title: 'Day of year', titleTextStyle: {italic: false, bold: true}, }, vAxis: {title: 'NDVI (x1e4)', titleTextStyle: {italic: false, bold: true}}, colors: ['0f8755'], legend: {position: 'none'} }); print(chart); });
Hay muchas formas de representar intervalos. En el siguiente ejemplo, se usan cajas en lugar de bandas cambiando la propiedad intervals.style
a 'boxes'
con el diseño de cuadro correspondiente.
dataTableServer.evaluate(function(dataTableClient) { var chart = ui.Chart(dataTableClient).setChartType('LineChart').setOptions({ title: 'Annual NDVI Time Series with Inter-Annual Variance', intervals: {style: 'boxes', barWidth: 1, boxWidth: 1, lineWidth: 0}, hAxis: { title: 'Day of year', titleTextStyle: {italic: false, bold: true}, }, vAxis: {title: 'NDVI (x1e4)', titleTextStyle: {italic: false, bold: true}}, colors: ['0f8755'], legend: {position: 'none'} }); print(chart); });