الرسوم البيانية لجدول البيانات

تعرِض الدالة ui.Chart الرسومات البيانية من عنصر JSON من جهة العميل يلي البنية نفسها لفئة DataTable في "رسومات Google"، ولكنه لا يتضمّن طرق DataTable وقابلية التغيير. وهو في الأساس جدولان عموديان يتضمّنان صفوفًا تمثّل الملاحظات وأعمدة تمثّل سمات الملاحظات. وتوفّر واجهة أساسية مرنة لإنشاء الرسوم البيانية في Earth Engine. وهو خيار جيد عند الحاجة إلى درجة عالية من تخصيص الرسم البياني.

مخطّط DataTable

هناك طريقتان لتعريف DataTable زائف في Earth Engine: مصفوفة ثنائية الأبعاد في JavaScript وعنصر حرفي في JavaScript. في معظم التطبيقات، سيكون إنشاء ملف مصفوفة ثنائية الأبعاد هو أبسط نهج. وفي كلتا الحالتَين، يجب أن يكون الجدول الذي تم تمريره إلى ui.Chart عنصرًا من جهة العميل. سيكون الجدول الذي تم ترميزه يدويًا من جهة العميل بشكلٍ أساسي، في حين يجب نقل العنصر المحسوب من جهة العميل باستخدام evaluate. يُرجى الاطّلاع على صفحة الاختلافات بين العميل والخادم لمزيد من المعلومات عن الفرق بين العناصر من جهة العميل ومن جهة الخادم.

صفيف JavaScript

يتكون DataTable ثنائي الأبعاد من صفيف من الصفوف والأعمدة. الصفوف هي الملاحظات والأعمدة هي السمات. يحدِّد العمود الأول قيم محور x، في حين تحدِّد الأعمدة الإضافية قيم سلسلة محور y. من المتوقّع أن يكون الصف الأول عنوان عمود. أبسط عنوان هو سلسلة من علامات الأعمدة، كما هو موضّح في الصفيف التالي DataTable الذي يربط عدد السكان بدول محدّدة.

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

يمكن اختياريًا تعيين دور للأعمدة غير تحديد النطاق (المحور x) والبيانات (سلسلة المحور y)، مثل التعليق التوضيحي أو الفواصل الزمنية أو نصائح التلميح أو النمط. في المثال التالي، يتم عرض صفيف العنوان كسلسلة من الكائنات، حيث يتم تحديد دور كل عمود بشكل صريح. يمكن العثور على أدوار عمود المقبولة لكل نوع من أنواع "رسومات Google البيانية" في مستنداتها ذات الصلة، مثل تنسيق بيانات الرسم البياني للأعمدة.

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

يتم تحديد خصائص الأعمدة على النحو التالي:

المَعلمة النوع التعريف
type سلسلة، يُنصح بها نوع بيانات العمود: 'string' أو 'number' أو 'boolean' أو 'date' أو 'datetime' أو 'timeofday'
label سلسلة، يُنصح بها تصنيف للعمود، تصنيف السلسلة في التسمية التوضيحية للرسم البياني
role سلسلة، يُنصح بها دور للعمود (مثل أدوار الرسم البياني العمودي)
pattern سلسلة، اختيارية سلسلة تنسيق رقم (أو تاريخ) تحدِّد كيفية عرض قيمة العمود

كائن JavaScript

يمكن تنسيق DataTable ككائن حرفي في JavaScript حيث يتم تقديم صفائف من كائنات الصف والعمود. اطّلِع على هذا الدليل للحصول على تعليمات حول تحديد مَعلمات الأعمدة والصفوف.

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

الرسم البياني اليدوي DataTable

لنفترض أنّ لديك كمية صغيرة من البيانات الثابتة التي تريد عرضها في رسم بياني. استخدِم مواصفات مصفوفة أو عنصر JavaScript لإنشاء إدخال لنقله إلى الدالة ui.Chart. في ما يلي، تم ترميز كثافة سكانية محدّدة في الولايات المتحدة من تعداد 2010 كصفيف JavaScript يحتوي على عناصر عناوين الأعمدة التي تحدّد سمات الأعمدة. يُرجى العِلم أنّه تم تخصيص العمود الثالث لدور 'annotation'، الذي يضيف عدد السكان كتعليق توضيحي لكل ملاحظة في الرسم البياني.

محرِّر الرموز البرمجية (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);

الرسم البياني المحسوب للموقع الجغرافيDataTable

يمكن إنشاء صفيف DataTable من صفيف ee.List ثنائي الأبعاد تم تمريره من الخادم إلى العميل من خلال evaluate. ومن السيناريوهات الشائعة تحويل سمات ee.FeatureCollection أو ee.ImageCollection أو تقليل كل عنصر من هذه السمات إلى DataTable. إنّ الاستراتيجية المطبّقة في الأمثلة التالية تربط بين دالّة وee.ImageCollection تقلّل العنصر المحدّد، ويجمعee.List من نتائج الاختزال، ويُرفِق القائمة كسمة تُسمى 'row' بالعنصر المعروض. يحتوي كل عنصر من عناصر المجموعة الجديدة على ee.List أحادي الأبعاد يمثّل صفًا في DataTable. تُستخدَم الدالة aggregate_array() لتجميع جميع سمات 'row' في ee.List رئيسي لإنشاء ee.List ثنائي الأبعاد من جهة الخادم بالشكل المطلوب لـ DataTable. يتم تسلسل عنوان عمود مخصّص مع الجدول ويتم نقل النتيجة إلى جانب العميل باستخدام evaluate، حيث يتم عرضها باستخدام الدالة ui.Chart.

السلاسل الزمنية حسب المنطقة

يعرض هذا المثال سلسلة زمنية لمؤشّري الغطاء النباتي NDVI وEVI المستمَدين من أداة MODIS لمنطقة إيكولوجية ذات غابات. يتم تقليل كل صورة في السلسلة حسب المنطقة البيئية ويتم تجميع نتائجها كموقع 'row' يتم تجميعه في DataTable لإرساله إلى العميل وإنشاء الرسوم البيانية باستخدام ui.Chart. يُرجى العِلم أنّ هذا المقتطف يُنشئ الرسم البياني نفسه الذي أنشأه مثال الرسم البياني ui.Chart.image.series.

محرِّر الرموز البرمجية (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);
});

الرسم البياني للفاصل

يستفيد هذا الرسم البياني من سمة عمود DataTable 'role' لإنشاء رسم بياني للفاصل الزمني. يوضّح الرسم البياني الملف الشخصي السنوي لمؤشر NDVI والتباين السنوي لوحدة بكسل بالقرب من مونتيري، كاليفورنيا. يتم عرض المتوسط السنوي على شكل خط، بينما يتم عرض النطاقَين المطلق وربع الانحراف المعياري على شكل أشرطة. يتم تحديد عمودَي الجدول اللذين يمثّلان كل فاصل زمني على هذا النحو من خلال ضبط سمة عمود 'role' على 'interval'. يتم رسم الأشرطة حول خط الوسط من خلال ضبط سمة الرسم البياني intervals.style على 'area'.

محرِّر الرموز البرمجية (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);
});

هناك العديد من الطرق لتمثيل الفواصل الزمنية. في المثال التالي، يتم استخدام المربّعات بدلاً من الأشرطة من خلال تغيير السمة intervals.style إلى 'boxes' مع تنسيق المربّع ذي الصلة.

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