Biểu đồ DataTable

Hàm ui.Chart hiển thị biểu đồ từ đối tượng JSON phía máy khách theo cấu trúc tương tự như lớp DataTable của Google Charts, nhưng thiếu các phương thức DataTable và khả năng thay đổi. Về cơ bản, đây là một bảng 2D với các hàng đại diện cho các quan sát và các cột đại diện cho các thuộc tính quan sát. Thư viện này cung cấp một giao diện cơ sở linh hoạt để lập biểu đồ trong Earth Engine. Đây là một lựa chọn phù hợp khi bạn cần tuỳ chỉnh biểu đồ ở mức độ cao.

Giản đồ DataTable

Có hai cách để xác định DataTable giả trong Earth Engine: một mảng 2D JavaScript và một đối tượng cố định JavaScript. Đối với hầu hết các ứng dụng, việc tạo một mảng 2D sẽ là phương pháp đơn giản nhất. Trong cả hai trường hợp, bảng được truyền đến ui.Chart phải là đối tượng phía máy khách. Bảng được mã hoá theo cách thủ công sẽ thuộc phía máy khách, trong khi đối tượng được tính toán sẽ cần được chuyển sang phía máy khách bằng evaluate. Vui lòng xem trang Máy khách so với máy chủ để biết thêm thông tin về sự khác biệt giữa các đối tượng phía máy chủ và phía máy khách.

Mảng JavaScript

DataTable 2D bao gồm một mảng các hàng và cột. Hàng là các quan sát và cột là các thuộc tính. Cột đầu tiên xác định giá trị cho trục x, trong khi các cột bổ sung xác định giá trị cho chuỗi trục y. Hàng đầu tiên dự kiến sẽ là tiêu đề cột. Tiêu đề đơn giản nhất là một loạt nhãn cột, được minh hoạ trong mảng DataTable sau đây liên quan đến dân số theo các tiểu bang đã chọn.

var dataTable = [
  ['State', 'Population'],
  ['CA', 37253956],
  ['NY', 19378102],
  ['IL', 12830632],
  ['MI', 9883640],
  ['OR', 3831074],
];

Nếu muốn, bạn có thể chỉ định cột cho một vai trò khác ngoài việc xác định miền (trục x) và dữ liệu (chuỗi trục y), ví dụ: chú thích, khoảng thời gian, chú giải công cụ hoặc kiểu. Trong ví dụ sau, mảng tiêu đề được trình bày dưới dạng một loạt các đối tượng, trong đó vai trò của từng cột được xác định rõ ràng. Bạn có thể xem các vai trò cột được chấp nhận cho từng loại Biểu đồ Google trong tài liệu tương ứng, ví dụ: Định dạng dữ liệu Biểu đồ cột.

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'],
];

Các thuộc tính của cột được chỉ định như sau:

Thông số Loại Định nghĩa
type chuỗi, nên dùng Kiểu dữ liệu cột: 'string', 'number', 'boolean', 'date', 'datetime' hoặc 'timeofday'.
label chuỗi, nên dùng Nhãn cho cột, nhãn chuỗi trong chú giải biểu đồ.
role chuỗi, nên dùng Vai trò của cột (ví dụ: vai trò của Biểu đồ cột).
pattern chuỗi, không bắt buộc Chuỗi định dạng số (hoặc ngày) chỉ định cách hiển thị giá trị cột.

Đối tượng JavaScript

Bạn có thể định dạng DataTable dưới dạng đối tượng cố định JavaScript, trong đó cung cấp các mảng đối tượng hàng và cột. Hãy xem hướng dẫn này để biết hướng dẫn về cách chỉ định tham số cột và hàng.

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}]}]
};

Biểu đồ DataTable thủ công

Giả sử bạn có một lượng nhỏ dữ liệu tĩnh mà bạn muốn hiển thị trên biểu đồ. Sử dụng thông số kỹ thuật mảng hoặc đối tượng JavaScript để tạo dữ liệu đầu vào truyền vào hàm ui.Chart. Ở đây, số dân của các tiểu bang được chọn trong cuộc điều tra dân số năm 2010 ở Hoa Kỳ được mã hoá dưới dạng một mảng JavaScript với các đối tượng tiêu đề cột xác định các thuộc tính cột. Xin lưu ý rằng cột thứ ba được chỉ định cho vai trò của 'annotation'. Cột này sẽ thêm tổng số quan sát dưới dạng chú thích vào mỗi quan sát trong biểu đồ.

Trình soạn thảo mã (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);

Biểu đồ DataTable đã tính toán

Bạn có thể tạo mảng DataTable từ ee.List 2D được truyền từ máy chủ đến ứng dụng qua evaluate. Một trường hợp phổ biến là chuyển đổi các thuộc tính của ee.FeatureCollection, ee.ImageCollection hoặc giảm theo phần tử của các thuộc tính này thành DataTable. Chiến lược được áp dụng trong các ví dụ sau ánh xạ một hàm trên ee.ImageCollection giúp giảm phần tử đã cho, tập hợp ee.List từ kết quả giảm và đính kèm danh sách dưới dạng một thuộc tính có tên là 'row' vào phần tử được trả về. Mỗi phần tử của bộ sưu tập mới có một ee.List 1 chiều đại diện cho một hàng trong DataTable. Hàm aggregate_array() dùng để tổng hợp tất cả các thuộc tính 'row' vào một ee.List mẹ để tạo một ee.List 2D phía máy chủ theo hình dạng cần thiết cho DataTable. Tiêu đề cột tuỳ chỉnh được nối với bảng và kết quả được chuyển sang phía máy khách bằng evaluate, nơi kết quả được hiển thị bằng hàm ui.Chart.

Chuỗi thời gian theo khu vực

Ví dụ này cho thấy một chuỗi thời gian của các chỉ số thảm thực vật NDVI và EVI bắt nguồn từ MODIS cho một khu sinh thái có rừng. Mỗi hình ảnh trong chuỗi được giảm theo vùng sinh thái và kết quả của hình ảnh được tập hợp dưới dạng thuộc tính 'row' được tổng hợp thành DataTable để truyền đến ứng dụng và lập biểu đồ bằng ui.Chart. Xin lưu ý rằng đoạn mã này tạo ra cùng một biểu đồ do ví dụ về biểu đồ ui.Chart.image.series tạo ra.

Trình soạn thảo mã (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);
});

Biểu đồ khoảng thời gian

Biểu đồ này tận dụng thuộc tính 'role' của cột DataTable để tạo biểu đồ khoảng thời gian. Biểu đồ này liên quan đến hồ sơ NDVI hằng năm và độ biến thiên giữa các năm cho một pixel gần Monterey, California. Trung vị giữa các năm được trình bày dưới dạng một đường kẻ, trong khi dải tuyệt đối và dải tứ phân vị được trình bày dưới dạng dải. Các cột trong bảng đại diện cho từng khoảng thời gian được gán như vậy bằng cách đặt thuộc tính cột 'role' thành 'interval'. Các dải được vẽ xung quanh đường trung vị bằng cách đặt thuộc tính biểu đồ intervals.style thành 'area'.

Trình soạn thảo mã (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);
});

Có nhiều cách để biểu thị khoảng thời gian. Trong ví dụ sau, các hộp được sử dụng thay vì dải bằng cách thay đổi thuộc tính intervals.style thành 'boxes' với kiểu hộp tương ứng.

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);
});