148 chart data table
In [ ]:
Copied!
# %pip install -U geemap
# %pip install -U geemap
Import libraries¶
In [ ]:
Copied!
import ee
import geemap
from geemap import chart
import pandas as pd
import ee
import geemap
from geemap import chart
import pandas as pd
In [ ]:
Copied!
geemap.ee_initialize()
geemap.ee_initialize()
Manual DataTable chart¶
In [ ]:
Copied!
data = {
"State": ["CA", "NY", "IL", "MI", "OR"],
"Population": [37253956, 19378102, 12830632, 9883640, 3831074],
}
df = pd.DataFrame(data)
df
data = {
"State": ["CA", "NY", "IL", "MI", "OR"],
"Population": [37253956, 19378102, 12830632, 9883640, 3831074],
}
df = pd.DataFrame(data)
df
In [ ]:
Copied!
fig = chart.Chart(
df,
x_cols=["State"],
y_cols=["Population"],
chart_type="ColumnChart",
colors=["#1d6b99"],
title="State Population (US census, 2010)",
x_label="State",
y_label="Population",
)
fig
fig = chart.Chart(
df,
x_cols=["State"],
y_cols=["Population"],
chart_type="ColumnChart",
colors=["#1d6b99"],
title="State Population (US census, 2010)",
x_label="State",
y_label="Population",
)
fig
Computed DataTable chart¶
In [ ]:
Copied!
# Import the example feature collection and subset the forest feature.
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.
veg_indices = (
ee.ImageCollection("MODIS/061/MOD13A1")
.filter(ee.Filter.date("2010-01-01", "2020-01-01"))
.select(["NDVI", "EVI"])
)
# Build a feature collection where each feature has a property that represents
# a DataFrame row.
def aggregate(img):
# Reduce the image to the mean of pixels intersecting the forest ecoregion.
stat = img.reduceRegion(
**{"reducer": ee.Reducer.mean(), "geometry": forest, "scale": 500}
)
# Extract the reduction results along with the image date.
date = geemap.image_date(img)
evi = stat.get("EVI")
ndvi = stat.get("NDVI")
# Make a list of observation attributes to define a row in the DataTable.
row = ee.List([date, evi, ndvi])
# Return the row as a property of an ee.Feature.
return ee.Feature(None, {"row": row})
reduction_table = veg_indices.map(aggregate)
# Aggregate the 'row' property from all features in the new feature collection
# to make a server-side 2-D list (DataTable).
data_table_server = reduction_table.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.
column_header = ee.List([["Date", "EVI", "NDVI"]])
# Concatenate the column header to the table.
data_table_server = column_header.cat(data_table_server)
# Import the example feature collection and subset the forest feature.
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.
veg_indices = (
ee.ImageCollection("MODIS/061/MOD13A1")
.filter(ee.Filter.date("2010-01-01", "2020-01-01"))
.select(["NDVI", "EVI"])
)
# Build a feature collection where each feature has a property that represents
# a DataFrame row.
def aggregate(img):
# Reduce the image to the mean of pixels intersecting the forest ecoregion.
stat = img.reduceRegion(
**{"reducer": ee.Reducer.mean(), "geometry": forest, "scale": 500}
)
# Extract the reduction results along with the image date.
date = geemap.image_date(img)
evi = stat.get("EVI")
ndvi = stat.get("NDVI")
# Make a list of observation attributes to define a row in the DataTable.
row = ee.List([date, evi, ndvi])
# Return the row as a property of an ee.Feature.
return ee.Feature(None, {"row": row})
reduction_table = veg_indices.map(aggregate)
# Aggregate the 'row' property from all features in the new feature collection
# to make a server-side 2-D list (DataTable).
data_table_server = reduction_table.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.
column_header = ee.List([["Date", "EVI", "NDVI"]])
# Concatenate the column header to the table.
data_table_server = column_header.cat(data_table_server)
In [ ]:
Copied!
data_table = chart.DataTable(data_table_server, date_column="Date")
data_table.head()
data_table = chart.DataTable(data_table_server, date_column="Date")
data_table.head()
In [ ]:
Copied!
fig = chart.Chart(
data_table,
chart_type="LineChart",
x_cols="Date",
y_cols=["EVI", "NDVI"],
colors=["#e37d05", "#1d6b99"],
title="Average Vegetation Index Value by Date for Forest",
x_label="Date",
y_label="Vegetation index (x1e4)",
stroke_width=3,
legend_location="right",
)
fig
fig = chart.Chart(
data_table,
chart_type="LineChart",
x_cols="Date",
y_cols=["EVI", "NDVI"],
colors=["#e37d05", "#1d6b99"],
title="Average Vegetation Index Value by Date for Forest",
x_label="Date",
y_label="Vegetation index (x1e4)",
stroke_width=3,
legend_location="right",
)
fig
Interval chart¶
In [ ]:
Copied!
# Define a point to extract an NDVI time series for.
geometry = ee.Geometry.Point([-121.679, 36.479])
# Define a band of interest (NDVI), import the MODIS vegetation index dataset,
# and select the band.
band = "NDVI"
ndvi_col = ee.ImageCollection("MODIS/061/MOD13Q1").select(band)
# Map over the collection to add a day of year (doy) property to each image.
def set_doy(img):
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))
ndvi_col = ndvi_col.map(set_doy)
# Join all coincident day of year observations into a set of image collections.
distinct_doy = ndvi_col.filterDate("2013-01-01", "2014-01-01")
filter = ee.Filter.equals(**{"leftField": "doy", "rightField": "doy"})
join = ee.Join.saveAll("doy_matches")
join_col = ee.ImageCollection(join.apply(distinct_doy, ndvi_col, 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.
def cal_percentiles(img):
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")})
comp = ee.ImageCollection(join_col.map(cal_percentiles))
# 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.
def order_percentiles(img):
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).
row = ee.List(
[
img.get("doy"),
stats.get(band + "_p50"),
stats.get(band + "_p0"),
stats.get(band + "_p25"),
stats.get(band + "_p75"),
stats.get(band + "_p100"),
]
)
# Return the row as a property of an ee.Feature.
return ee.Feature(None, {"row": row})
reduction_table = comp.map(order_percentiles)
# Aggregate the 'row' properties to make a server-side 2-D array (DataTable).
data_table_server = reduction_table.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.
column_header = ee.List([["DOY", "median", "p0", "p25", "p75", "p100"]])
# Concatenate the column header to the table.
data_table_server = column_header.cat(data_table_server)
# Define a point to extract an NDVI time series for.
geometry = ee.Geometry.Point([-121.679, 36.479])
# Define a band of interest (NDVI), import the MODIS vegetation index dataset,
# and select the band.
band = "NDVI"
ndvi_col = ee.ImageCollection("MODIS/061/MOD13Q1").select(band)
# Map over the collection to add a day of year (doy) property to each image.
def set_doy(img):
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))
ndvi_col = ndvi_col.map(set_doy)
# Join all coincident day of year observations into a set of image collections.
distinct_doy = ndvi_col.filterDate("2013-01-01", "2014-01-01")
filter = ee.Filter.equals(**{"leftField": "doy", "rightField": "doy"})
join = ee.Join.saveAll("doy_matches")
join_col = ee.ImageCollection(join.apply(distinct_doy, ndvi_col, 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.
def cal_percentiles(img):
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")})
comp = ee.ImageCollection(join_col.map(cal_percentiles))
# 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.
def order_percentiles(img):
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).
row = ee.List(
[
img.get("doy"),
stats.get(band + "_p50"),
stats.get(band + "_p0"),
stats.get(band + "_p25"),
stats.get(band + "_p75"),
stats.get(band + "_p100"),
]
)
# Return the row as a property of an ee.Feature.
return ee.Feature(None, {"row": row})
reduction_table = comp.map(order_percentiles)
# Aggregate the 'row' properties to make a server-side 2-D array (DataTable).
data_table_server = reduction_table.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.
column_header = ee.List([["DOY", "median", "p0", "p25", "p75", "p100"]])
# Concatenate the column header to the table.
data_table_server = column_header.cat(data_table_server)
In [ ]:
Copied!
df = chart.DataTable(data_table_server)
df.head()
df = chart.DataTable(data_table_server)
df.head()
In [ ]:
Copied!
fig = chart.Chart(
df,
chart_type="IntervalChart",
x_cols="DOY",
y_cols=["p0", "p25", "median", "p75", "p100"],
title="Annual NDVI Time Series with Inter-Annual Variance",
x_label="Day of Year",
y_label="Vegetation index (x1e4)",
stroke_width=1,
fill="between",
fill_colors=["#b6d1c6", "#83b191", "#83b191", "#b6d1c6"],
fill_opacities=[0.6] * 4,
labels=["p0", "p25", "median", "p75", "p100"],
display_legend=True,
legend_location="top-right",
ylim=(0, 10000),
)
fig
fig = chart.Chart(
df,
chart_type="IntervalChart",
x_cols="DOY",
y_cols=["p0", "p25", "median", "p75", "p100"],
title="Annual NDVI Time Series with Inter-Annual Variance",
x_label="Day of Year",
y_label="Vegetation index (x1e4)",
stroke_width=1,
fill="between",
fill_colors=["#b6d1c6", "#83b191", "#83b191", "#b6d1c6"],
fill_opacities=[0.6] * 4,
labels=["p0", "p25", "median", "p75", "p100"],
display_legend=True,
legend_location="top-right",
ylim=(0, 10000),
)
fig