Die Funktion ui.Chart
rendert Diagramme aus einem clientseitigen JSON-Objekt, das der Struktur der Google Charts-Klasse DataTable
folgt, aber keine DataTable
-Methoden und keine Mutabilität aufweist. Es handelt sich im Wesentlichen um eine 2D-Tabelle mit Zeilen, die Beobachtungen, und Spalten, die Beobachtungsattribute darstellen. Es bietet eine flexible Basisoberfläche für die Erstellung von Diagrammen in Earth Engine. Diese Option eignet sich gut, wenn das Diagramm stark angepasst werden soll.
DataTable
Schema
Es gibt zwei Möglichkeiten, ein Pseudo-DataTable
in Earth Engine zu definieren: ein JavaScript-2D-Array und ein JavaScript-Literalobjekt. Für die meisten Anwendungen ist das Erstellen eines 2D-Arrays der einfachste Ansatz. In beiden Fällen muss die an ui.Chart
übergebene Tabelle ein clientseitiges Objekt sein. Eine manuell codierte Tabelle ist von Natur aus clientseitig, während ein berechnetes Objekt clientseitig mit evaluate
übertragen werden muss. Weitere Informationen zum Unterschied zwischen server- und clientseitigen Objekten finden Sie auf der Seite Client und Server.
JavaScript-Array
Ein zweidimensionales DataTable
besteht aus einer Reihe von Zeilen und Spalten. Zeilen sind Beobachtungen und Spalten sind Attribute. In der ersten Spalte werden Werte für die x-Achse definiert, während zusätzliche Spalten Werte für Reihen der y-Achse definieren. Die erste Zeile sollte eine Spaltenüberschrift sein. Die einfachste Überschrift besteht aus einer Reihe von Spaltenlabels, wie im folgenden Array DataTable
zu sehen, das die Bevölkerung nach ausgewählten Bundesländern enthält.
var dataTable = [ ['State', 'Population'], ['CA', 37253956], ['NY', 19378102], ['IL', 12830632], ['MI', 9883640], ['OR', 3831074], ];
Optional können Spalten auch für andere Zwecke als die Definition der Domain (x-Achse) und der Daten (y-Achse) verwendet werden, z.B. für Anmerkungen, Intervalle, Kurzinfos oder Stil. Im folgenden Beispiel wird das Header-Array als Reihe von Objekten dargestellt, wobei die Rolle jeder Spalte explizit definiert ist. Zulässige Spaltenrollen für jeden Google-Diagrammtyp finden Sie in der jeweiligen Dokumentation, z.B. Datenformat für Säulendiagramme.
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'], ];
Spalteneigenschaften werden so angegeben:
Parameter | Typ | Definition |
---|---|---|
type |
String, empfohlen | Spaltendatentyp: 'string' , 'number' , 'boolean' , 'date' , 'datetime' oder 'timeofday' |
label |
String, empfohlen | Ein Label für die Spalte, das Reihenlabel in der Diagrammlegende. |
role |
String, empfohlen | Eine Rolle für die Spalte (z.B. Rollen für Säulendiagramme). |
pattern |
String, optional | Ein Zahlen- oder Datumsformatstring, der angibt, wie der Spaltenwert angezeigt werden soll. |
JavaScript-Objekt
Ein DataTable
kann als JavaScript-Literalobjekt formatiert werden, bei dem Arrays von Zeilen- und Spaltenobjekten bereitgestellt werden. Eine Anleitung zum Angeben von Spalten- und Zeilenparametern finden Sie in diesem Leitfaden.
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}]}] };
Manuelles DataTable
-Diagramm
Angenommen, Sie haben eine kleine Menge an statischen Daten, die Sie in einem Diagramm darstellen möchten.
Verwenden Sie entweder die JavaScript-Spezifikationen für Arrays oder Objekte, um eine Eingabe zu erstellen, die an die ui.Chart
-Funktion übergeben werden soll. Hier werden die Bevölkerungszahlen ausgewählter US-Bundesstaaten aus der Volkszählung 2010 als JavaScript-Array mit Spaltenüberschriftenobjekten codiert, die Spalteneigenschaften definieren. Die dritte Spalte hat die Rolle 'annotation'
. Dadurch wird die Population jeder Beobachtung im Diagramm als Anmerkung hinzugefügt.
// 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);
Berechnetes DataTable
-Diagramm
Ein DataTable
-Array kann aus einem 2D-ee.List
erstellt werden, das vom Server über evaluate
an den Client übergeben wird. Ein häufiges Szenario ist die Umwandlung von Properties einer ee.FeatureCollection
, ee.ImageCollection
oder einer elementweisen Reduzierung dieser in eine DataTable
. Bei der in den folgenden Beispielen angewendeten Strategie wird eine Funktion auf ein ee.ImageCollection
angewendet, um das angegebene Element zu reduzieren. Anschließend wird eine ee.List
aus den Ergebnissen der Reduzierung zusammengestellt und die Liste als Eigenschaft namens 'row'
an das zurückgegebene Element angehängt. Jedes Element der neuen Sammlung hat ein eindimensionales ee.List
, das eine Zeile in einer DataTable
darstellt.
Mit der Funktion aggregate_array()
werden alle 'row'
-Properties in einem übergeordneten ee.List
zusammengefasst, um eine serverseitige 2D-ee.List
in der für DataTable
erforderlichen Form zu erstellen. Eine benutzerdefinierte Spaltenüberschrift wird mit der Tabelle verknüpft und das Ergebnis wird clientseitig mit evaluate
übertragen, wo es mit der Funktion ui.Chart
gerendert wird.
Zeitreihen nach Region
Dieses Beispiel zeigt eine Zeitreihe von MODIS-abgeleiteten Vegetationsindices NDVI und EVI für eine bewaldete Ökoregion. Jedes Bild in der Reihe wird auf die Ökoregion reduziert und die Ergebnisse werden als 'row'
-Property zusammengestellt, die in einer DataTable
zusammengefasst wird, um an den Client übergeben und mit ui.Chart
in Diagrammen dargestellt zu werden. Hinweis: Dieses Snippet erzeugt dasselbe Diagramm wie das ui.Chart.image.series
-Diagrammbeispiel.
// 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); });
Intervalldiagramm
In diesem Diagramm wird die Spalteneigenschaft DataTable
'role'
verwendet, um ein Intervalldiagramm zu generieren.
Das Diagramm stellt das jährliche NDVI-Profil und die jahresübergreifende Varianz für ein Pixel in der Nähe von Monterey, Kalifornien, dar.
Der Median für mehrere Jahre wird als Linie dargestellt, während die absoluten und interquartilen Bereiche als Bänder angezeigt werden. Tabellenspalten, die die einzelnen Intervalle darstellen, werden entsprechend zugewiesen, indem die Spalteneigenschaft 'role'
auf 'interval'
festgelegt wird. Wenn Sie die Diagrammeigenschaft intervals.style
auf 'area'
festlegen, werden Bereiche um die Medianlinie herum gezeichnet.
// 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); });
Intervalle lassen sich auf viele Arten darstellen. Im folgenden Beispiel werden statt Streifen Kästchen verwendet. Dazu wird die Property intervals.style
in 'boxes'
geändert und das entsprechende Kästchen-Styling angewendet.
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); });