Visualize classified time series data with interactive Sankey plots in Google Earth Engine

Overview

sankee

conda-forge link conda-forge link license link

Visualize changes in classified time series data with interactive Sankey plots in Google Earth Engine

Sankee example showing grassland expansion in the Nile Delta

Contents

Description

sankee provides a dead-simple API that combines the power of GEE and Plotly to visualize changes in land cover, plant health, burn severity, or any other classified imagery over a time series in a region of interst using interactive Sankey plots. Use a library of built-in datasets like NLCD, MODIS Land Cover, or CGLS for convenience or define your own custom datasets for flexibility.

sankee works by randomly sampling points in a time series of classified imagery to visualize how cover types changed over time.

Installation

Using Pip

pip install sankee

Using Conda

sankee can be downloaded through conda-forge within a Conda environment.

conda create -n sankee
conda activate sankee
conda install -c conda-forge sankee

Requirements

Quick Start

Using a Premade Dataset

Datasets in sankee are used to apply labels and colors to classified imagery (eg. a value of 42 in an NLCD 2016 image should be labeled "Evergeen forest" and colored green). sankee includes premade Dataset objects for common classified datasets in GEE like NLCD, MODIS land cover, and CGLS. See datasets for a detailed explanation.

import ee
import sankee

ee.Initialize()

# Choose a premade dataset object that contains band, label, and palette information for NLCD
dataset = sankee.datasets.NLCD2016

# Build a list of images
img_list = [ee.Image(f"USGS/NLCD/NLCD2001"), ee.Image(f"USGS/NLCD/NLCD2016")]
# Build a matching list of labels for the images (optional)
label_list = ["2001", "2016"]

# Define an area of interest
vegas = ee.Geometry.Polygon(
        [[[-115.4127152226893, 36.29589873319828],
          [-115.4127152226893, 36.12082334399102],
          [-115.3248245976893, 36.12082334399102],
          [-115.3248245976893, 36.29589873319828]]])

# Choose a title to display over your plot (optional)
title = "Las Vegas Urban Sprawl, 2001 - 2016"

# Generate your Sankey plot
plot = sankee.sankify(img_list, vegas, label_list, dataset, max_classes=4, title=title)
plot

NLCD Las Vegas urbanization example Sankey plot

Using a Custom Dataset

Datasets can also be manually defined for custom images. In this example, we'll classify 1-year and 5-year post-fire Landsat imagery using NDVI and visualize plant recovery using sankee.

import ee
import sankee

ee.Initialize()

# Load fire perimeters from MTBS data
fires = ee.FeatureCollection("users/aazuspan/fires/mtbs_1984_2018")
# Select the 2014 Happy Camp Complex fire perimeter in California
fire = fires.filterMetadata("Fire_ID", "equals", "CA4179612337420140814")

# Load imagery 1 year after fire and 5 years after fire
immediate = ee.Image("LANDSAT/LC08/C01/T1_TOA/LC08_045031_20150718")
recovery = ee.Image("LANDSAT/LC08/C01/T1_TOA/LC08_046031_20200807")

# Calculate NDVI
immediate_NDVI = immediate.normalizedDifference(["B5", "B4"])
recovery_NDVI = recovery.normalizedDifference(["B5", "B4"])

# Reclassify continuous NDVI values into classes of plant health
immediate_class = ee.Image(1) \
  .where(immediate_NDVI.lt(0.3), 0) \
  .where(immediate_NDVI.gt(0.5), 2) \
  .rename("health")

recovery_class = ee.Image(1) \
  .where(recovery_NDVI.lt(0.3), 0) \
  .where(recovery_NDVI.gt(0.5), 2) \
  .rename("health")

# Specify the band name for the image
band = "health"

# Assign labels to the pixel values defined above
labels = {
    0: "Unhealthy",
    1: "Moderate",
    2: "Healthy"
}
# Assign colors to the pixel values defined above
palette = {
    0: "#e5f5f9",
    1: "#99d8c9",
    2: "#2ca25f"
}

# Define the images to use and create labels to describe them
img_list = [immediate_class, recovery_class]
label_list = ["Immediate", "Recovery"]

# Generate your Sankey plot
plot = sankee.sankify(img_list, fire, label_list, band=band, labels=labels, palette=palette, scale=20)
plot

NDVI post-fire recovery example Sankey plot

Features

Modular Datasets

Datasets in sankee define how classified image values are labeled and colored when plotting. label and palette arguments for sankee functions can be manually provided as dictionaries where pixel values are keys and labels and colors are values. Every value in the image must have a corresponding color and label. Datasets also define the band name in the image in which classified values are found.

Any classified image can be visualized by manually defining a band, palette, and label. However, premade datasets are included for convenience in the sankee.datasets module. To access a dataset, use its name, such as sankee.datasets.NLCD2016. To get a list of all dataset names, run sankee.datasets.names(). Datasets can also be accessed using sankee.datasets.get() which returns a list of Dataset objects that can be selecting by indexing.

# List all sankee built-in datasets
sankee.datasets.names()

>> ['NLCD2016',
    'MODIS_LC_TYPE1',
    'MODIS_LC_TYPE2',
    'MODIS_LC_TYPE3',
    'CGLS_LC100']

# Preview a list of available images belonging to one dataset
sankee.datasets.CGLS_LC100.get_images(3)

>> ['COPERNICUS/Landcover/100m/Proba-V-C3/Global/2015',
    'COPERNICUS/Landcover/100m/Proba-V-C3/Global/2016',
    'COPERNICUS/Landcover/100m/Proba-V-C3/Global/2017',
    '...']

Flexible Time Series

sankee can handle any length of time series. The number of images will determine the number of time steps in the series. The example below shows a three-image time series.

MODIS glacier loss example Sankey plot

Integration with geemap

geemap is a great tool for exploring changes in GEE imagery before creating plots with sankee. Integration is quick and easy. Just use geemap like you normally would, and pass the images and feature geometries to sankee for plotting. The example at the top of the page shows sankee can be used with geemap.

API

Core function

sankee.sankify(image_list, region, label_list, dataset, band, labels, palette, exclude, max_classes, n, title, scale, seed, dropna)

Generate n random samples points within a region and extract classified pixel values from each image in an image list. Arrange the sample data into a Sankey plot that can be used to visualize changes in image classifications.

Arguments

  • image_list (list)

    • An ordered list of images representing a time series of classified data. Each image will be sampled to generate the Sankey plot. Any length of list is allowed, but lists with more than 3 or 4 images may produce unusable plots.
  • region (ee.Geometry)

    • A region to generate samples within.
  • label_list (list, default: None)

    • An ordered list of labels corresponding to the images. The list must be the same length as image_list. If none is provided, sequential numeric labels will be automatically assigned starting at 0. Labels are displayed on-hover on the Sankey nodes.
  • dataset (sankee.datasets.Dataset, default: None)

    • A premade dataset that defines the band, labels, and palette for all images in image_list. If a custom dataset is being used, provide band, labels, and palette instead.
  • band (str, default: None)

    • The name of the band in all images of image_list that contains classified data. If none is provided, dataset must be provided instead.
  • labels (dict, default: None)

    • The labels associated with each value of all images in image_list. Every value in the images must be included as a key in the labels dictionary. If none is provided, dataset must be provided instead.
  • palette (dict, default: None)

    • The colors associated with each value of all images in image_list. Every value in the images must be included as a key in the palette dictionary. If none is provided, dataset must be provided instead. Colors must be supported by Plotly.
  • exclude (list, default: None)

    • An optional list of pixel values to exclude from the plot. Excluded values must be raw pixel values rather than class labels. This can be helpful if the region is dominated by one or more unchanging classes and the goal is to visualize changes in smaller classes.
  • max_classes (int, default: None)

    • If a value is provided, small classes will be removed until max_classes remain. Class size is calculated based on total times sampled in the time series.
  • n (int, default: 100)

    • The number of samples points to randomly generate for characterizing all images. More samples will provide more representative data but will take longer to process.
  • title (str, default: None)

    • An optional title that will be displayed above the Sankey plot.
  • scale (int, default: None)

    • The scale in image units to perform sampling at. If none is provided, GEE will attempt to use the image's nominal scale, which may cause errors depending on the image projection.
  • seed (int, default: 0)

    • The seed value used to generate repeatable results during random sampling.
  • dropna (bool, default: True)

    • If the region extends into areas that contain no data in any image, some samples may have null values. If dropna is True, those samples will be dropped. This may lead to fewer samples being returned than were requested by n.

Returns

  • A Plotly Sankey plot object.

Dataset functions

sankee.datasets.names()

Get a list of supported dataset names. Names can be used to access datasets using sankee.datasets.{dataset_name}.

Arguments

  • None

Returns (list)

  • A list of strings for supported dataset names.

Example

sankee.datasets.names()

>> ['NLCD2016', 'MODIS_LC_TYPE1', 'MODIS_LC_TYPE2', 'MODIS_LC_TYPE3', 'CGLS_LC100']

sankee.datasets.get(i)

Get a list of supported sankee.datasets.Dataset objects.
Arguments

  • i (int, default: None)
    • An optional index to retrieve a specific dataset.

Returns (list)

  • A list of supported sankee.datasets.Dataset objects. If i is provided, only one object is returned.

Example

# Get the first Dataset object
sankee.datasets.get(0)

>> <sankee.datasets.Dataset> NLCD: USGS National Land Cover Database

sankee.datasets.Dataset.get_images(max_images)

Get a list of image names in the collection of a specific dataset.
Arguments

  • max_images (int, default: 20)
    • The max number of images to return.

Returns (list)

  • A list of image names that can be used to load ee.Image objects.

Example

sankee.datasets.NLCD2016.get_images(3)

>> ['USGS/NLCD/NLCD1992', 'USGS/NLCD/NLCD2001', 'USGS/NLCD/NLCD2001_AK', '...']

Dataset properties and attributes

sankee.datasets.Dataset.collection

  • Return the image collection associated with the dataset as an Earth Engine object.

sankee.datasets.Dataset.df

  • Return a Pandas dataframe describing the classes, labels, and colors associated with the dataset.

sankee.datasets.Dataset.id

  • Return the system ID of the image collection.

Contributing

If you find bugs or have feature requests, please open an issue!


Top

Comments
  • Custom dataset mtbs_1984_2018 not found

    Custom dataset mtbs_1984_2018 not found

    I was testing the custom dataset example, and it seems the asset 'users/aazuspan/fires/mtbs_1984_2018' is not accessible. Would you mind sharing this dataset? Thanks.

    image

    opened by giswqs 5
  • Customize plot size

    Customize plot size

    I am trying to display the sankee plot directly within the map. As can be seen from the screenshot below, only a portion of the plot is visible due to the limited size of the hosting widget. It would be great if sankee can support customizing plot size so that it can fit into the hosting widget.

    image

    opened by giswqs 4
  • Making sankee available on conda-forge

    Making sankee available on conda-forge

    Thank you for developing this nice package! Have you considered making it available on conda-forge channel? I would love to incorporate sankee into the geemap toolbar and develop an interactive GUI for this so that users can create sankee plots without coding. Pull request is also welcome.

    Here is a tutorial for publishing a Python package on conda-forge. I would be happy to help if needed.

    opened by giswqs 2
  • Fix CCAP projection to allow plotting without specifying `scale` (#29)

    Fix CCAP projection to allow plotting without specifying `scale` (#29)

    Close #29

    Projection information is lost when the CCAP images are mosaiced, which prevents reduceRegion from running unless scale is specified. Explicitly setting the default projection fixes that. EPSG:5070 is a reasonable choice since CCAP is a CONUS dataset.

    bug 
    opened by aazuspan 1
  • Issue with sankee.Dataset()

    Issue with sankee.Dataset()

    I am running one of the examples on Google Colab and encountered this problem:

    AttributeError Traceback (most recent call last) in () ----> 1 dataset = sankee.Dataset(collection_name="custom", band=band, labels=labels, palette=palette)

    AttributeError: module 'sankee' has no attribute 'Dataset'

    image

    bug 
    opened by Daniel-Trung-Nguyen 1
  • `sankify` fails with `CCAP_LC30` dataset unless `scale` is specified

    `sankify` fails with `CCAP_LC30` dataset unless `scale` is specified

    The CCAP_LC30 dataset mosaics multiple images when you retrieve a year, which resets projection information. To allow reduceRegion to run without specifying a scale, the projection will need to be redefined after mosaicing.

    bug 
    opened by aazuspan 0
  • Store `samples` attribute in `SankeyPlot` (#25)

    Store `samples` attribute in `SankeyPlot` (#25)

    Close #25.

    This refactors the sampling module, combining the functions into a single function that returns both the formatted data and the sampled FeatureCollection, which can now be used when initializing a SankeyPlot.

    enhancement 
    opened by aazuspan 0
  • `example_data` module can't be loaded before initialization

    `example_data` module can't be loaded before initialization

    Because the example regions are class attributes, they get instantiated on import, which fails if Earth Engine hasn't been initialized. Need to redesign accordingly.

    bug 
    opened by aazuspan 0
  • Store sampled points in `SankeyPlot`

    Store sampled points in `SankeyPlot`

    Being able to access the points that were used to sample the Sankey data might be useful (or at least interesting), and wouldn't require much work. Just need to refactor to generate the random points outside of the sampling function and pass them in. That change would also make it trivial to allow user-defined points, which could be worth adding in the future.

    enhancement 
    opened by aazuspan 0
  • Explicit cast to int to avoid KeyErrors #22

    Explicit cast to int to avoid KeyErrors #22

    Fix #22

    If null values are sampled in one time step (e.g. nodata classes or masked areas), the resulting dataframe column will be cast to float before the nans can be dropped. When value_counts is run, you'll get a dataframe with a float index. Slicing that dataframe with an int index will throw a KeyError.

    Explicitly casting to int after dropping nans avoids the float index problem and solves the issue.

    bug 
    opened by aazuspan 0
  • `KeyError` during data collection caused by mixed data types

    `KeyError` during data collection caused by mixed data types

    Currently, the second example in the readme (code below) throws a KeyError when the max_classes are filtered

    # Load a set of classified images
    img_list = [
        ee.Image("GOOGLE/DYNAMICWORLD/V1/20210616T185919_20210616T190431_T10TEQ"),
        ee.Image("GOOGLE/DYNAMICWORLD/V1/20210706T185919_20210706T190638_T10TEQ")
    ]
    
    # Which band contains the classified data?
    band = "label"
    
    # What labels correspond to which pixel values?
    labels = {
        0: "Water", 1: "Trees", 2: "Grass", 3: "Flooded", 4: "Crops",
        5: "Shrub / Scrub", 6: "Build", 7: "Bare", 8: "Snow / Ice",
    }
    
    # What colors should be applied to which pixel values?
    palette = {
        0: "#419BDF", 1: "#397D49", 2: "#88B053", 3: "#7A87C6", 4: "#E49635",
        5: "#DFC35A", 6: "#C4281B", 7: "#A59B8F", 8: "#B39FE1"
    }
    
    plot = sankee.sankify(
        image_list=img_list, 
        band=band, 
        labels=labels,
        palette=palette,
        region=ee.Geometry.Point([-121.80183, 44.67655]).buffer(3000), 
        max_classes=3,
        title="Mt. Jefferson Snow Loss - June 2021"
    )
    

    The root cause seems to be that sampling.collect_sankee_data returns mixed datatypes due to NaN sampled values. Casting to int after removing NaNs should resolve this.

    bug 
    opened by aazuspan 0
  • Contingency tables

    Contingency tables

    Really loving how easy to use Sankee is - great work sir!

    I was previously hacking around producing a frequencyHistogram() of pixel counts per landuse class to describe the changes between two images. Then using the R package OpenLand to produce a sankee diagram from the resulting featurecollection. Needless to say this was many more lines of code than I now need with sankee!

    If I had to request a feature though it would be to be able to output a contingency table (data.frame) of the actual aggregate values i.e. either sum of pixel counts and/or areas (km2) of the transitions from one land use class to another between images. Would that be an easy addition?

    enhancement 
    opened by martyclark 1
  • Non-transparent plot background

    Non-transparent plot background

    The switch from go.Figure to go.FigureWidget to include interactive buttons caused an unintended side effect of changing plot background color from transparent to white. This is caused by an inconsistency between the two classes (see https://github.com/plotly/plotly.py/issues/3811).

    If there's not a workaround or fix, we may just have to live with an opaque background. I guess there are worse things.

    bug 
    opened by aazuspan 0
  • Additional LULC datasets

    Additional LULC datasets

    opened by aazuspan 0
  • All available datasets in the GEE Catalog? :)

    All available datasets in the GEE Catalog? :)

    Hi, @aazuspan!

    I was using sankee and it is amazing!

    I was thinking that maybe it could be possible to add all datasets in the GEE Catalog that are Land Cover Classifications, or at least discrete products. Here is the idea!

    If we take the Copernicus CORINE Land Cover Product as an example and get the STAC info, we can see that in the summaries property there is a eo:bands property. This property describes all the bands of the collection. If the band is a discrete band, it will have a gee:classes property explaining the color, the description and the value!

    import ee, eemont
    
    ee.Initialize()
    
    ee.ImageCollection("COPERNICUS/CORINE/V20/100m").getSTAC()["summaries"]["eo:bands"]
    
    [{'description': 'Land cover',
      'gee:classes': [{'color': 'E6004D',
        'description': 'Artificial surfaces > Urban fabric > Continuous urban fabric',
        'value': 111},
       {'color': 'FF0000',
        'description': 'Artificial surfaces > Urban fabric > Discontinuous urban fabric',
        'value': 112},
       {'color': 'CC4DF2',
        'description': 'Artificial surfaces > Industrial, commercial, and transport units > Industrial or commercial units',
        'value': 121},
       {'color': 'CC0000',
        'description': 'Artificial surfaces > Industrial, commercial, and\ntransport units > Road and rail networks and associated land\n',
        'value': 122},
       {'color': 'E6CCCC',
        'description': 'Artificial surfaces > Industrial, commercial, and transport units > Port areas',
        'value': 123},
       {'color': 'E6CCE6',
        'description': 'Artificial surfaces > Industrial, commercial, and transport units > Airports',
        'value': 124},
       {'color': 'A600CC',
        'description': 'Artificial surfaces > Mine, dump, and construction sites > Mineral extraction sites',
        'value': 131},
       {'color': 'A64DCC',
        'description': 'Artificial surfaces > Mine, dump, and construction sites > Dump sites',
        'value': 132},
       {'color': 'FF4DFF',
        'description': 'Artificial surfaces > Mine, dump, and construction sites > Construction sites',
        'value': 133},
       {'color': 'FFA6FF',
        'description': 'Artificial surfaces > Artificial, non-agricultural vegetated areas > Green urban areas',
        'value': 141},
       {'color': 'FFE6FF',
        'description': 'Artificial surfaces > Artificial, non-agricultural vegetated areas > Sport and leisure facilities',
        'value': 142},
       {'color': 'FFFFA8',
        'description': 'Agricultural areas > Arable land > Non-irrigated arable land',
        'value': 211},
       {'color': 'FFFF00',
        'description': 'Agricultural areas > Arable land > Permanently irrigated land',
        'value': 212},
       {'color': 'E6E600',
        'description': 'Agricultural areas > Arable land > Rice fields',
        'value': 213},
       {'color': 'E68000',
        'description': 'Agricultural areas > Permanent crops > Vineyards',
        'value': 221},
       {'color': 'F2A64D',
        'description': 'Agricultural areas > Permanent crops > Fruit trees and berry plantations',
        'value': 222},
       {'color': 'E6A600',
        'description': 'Agricultural areas > Permanent crops > Olive groves',
        'value': 223},
       {'color': 'E6E64D',
        'description': 'Agricultural areas > Pastures > Pastures',
        'value': 231},
       {'color': 'FFE6A6',
        'description': 'Agricultural areas > Heterogeneous agricultural areas > Annual crops associated with permanent crops',
        'value': 241},
       {'color': 'FFE64D',
        'description': 'Agricultural areas > Heterogeneous agricultural areas > Complex cultivation patterns',
        'value': 242},
       {'color': 'E6CC4D',
        'description': 'Agricultural areas > Heterogeneous agricultural areas >\nLand principally occupied by agriculture, with significant areas of\nnatural vegetation\n',
        'value': 243},
       {'color': 'F2CCA6',
        'description': 'Agricultural areas > Heterogeneous agricultural areas > Agro-forestry areas',
        'value': 244},
       {'color': '80FF00',
        'description': 'Forest and semi natural areas > Forests > Broad-leaved forest',
        'value': 311},
       {'color': '00A600',
        'description': 'Forest and semi natural areas > Forests > Coniferous forest',
        'value': 312},
       {'color': '4DFF00',
        'description': 'Forest and semi natural areas > Forests > Mixed forest',
        'value': 313},
       {'color': 'CCF24D',
        'description': 'Forest and semi natural areas > Scrub and/or herbaceous vegetation associations > Natural grasslands',
        'value': 321},
       {'color': 'A6FF80',
        'description': 'Forest and semi natural areas > Scrub and/or herbaceous vegetation associations > Moors and heathland',
        'value': 322},
       {'color': 'A6E64D',
        'description': 'Forest and semi natural areas > Scrub and/or herbaceous\nvegetation associations > Sclerophyllous vegetation\n',
        'value': 323},
       {'color': 'A6F200',
        'description': 'Forest and semi natural areas > Scrub and/or herbaceous\nvegetation associations > Transitional woodland-shrub\n',
        'value': 324},
       {'color': 'E6E6E6',
        'description': 'Forest and semi natural areas > Open spaces with little or no vegetation > Beaches, dunes, sands',
        'value': 331},
       {'color': 'CCCCCC',
        'description': 'Forest and semi natural areas > Open spaces with little or no vegetation > Bare rocks',
        'value': 332},
       {'color': 'CCFFCC',
        'description': 'Forest and semi natural areas > Open spaces with little or no vegetation > Sparsely vegetated areas',
        'value': 333},
       {'color': '000000',
        'description': 'Forest and semi natural areas > Open spaces with little or no vegetation > Burnt areas',
        'value': 334},
       {'color': 'A6E6CC',
        'description': 'Forest and semi natural areas > Open spaces with little or no vegetation > Glaciers and perpetual snow',
        'value': 335},
       {'color': 'A6A6FF',
        'description': 'Wetlands > Inland wetlands > Inland marshes',
        'value': 411},
       {'color': '4D4DFF',
        'description': 'Wetlands > Inland wetlands > Peat bogs',
        'value': 412},
       {'color': 'CCCCFF',
        'description': 'Wetlands > Maritime wetlands > Salt marshes',
        'value': 421},
       {'color': 'E6E6FF',
        'description': 'Wetlands > Maritime wetlands > Salines',
        'value': 422},
       {'color': 'A6A6E6',
        'description': 'Wetlands > Maritime wetlands > Intertidal flats',
        'value': 423},
       {'color': '00CCF2',
        'description': 'Water bodies > Inland waters > Water courses',
        'value': 511},
       {'color': '80F2E6',
        'description': 'Water bodies > Inland waters > Water bodies',
        'value': 512},
       {'color': '00FFA6',
        'description': 'Water bodies > Marine waters > Coastal lagoons',
        'value': 521},
       {'color': 'A6FFE6',
        'description': 'Water bodies > Marine waters > Estuaries',
        'value': 522},
       {'color': 'E6F2FF',
        'description': 'Water bodies > Marine waters > Sea and ocean',
        'value': 523}],
      'name': 'landcover'}]
    

    Check it now for MODIS:

    ee.ImageCollection("MODIS/006/MCD12Q1").getSTAC()["summaries"]["eo:bands"]
    
    [{'description': 'Land Cover Type 1: Annual International Geosphere-Biosphere Programme (IGBP) classification',
      'gee:classes': [{'color': '05450a',
        'description': 'Evergreen Needleleaf Forests: dominated by evergreen\nconifer trees (canopy >2m). Tree cover >60%.',
        'value': 1},
       {'color': '086a10',
        'description': 'Evergreen Broadleaf Forests: dominated by evergreen\nbroadleaf and palmate trees (canopy >2m). Tree cover >60%.\n',
        'value': 2},
       {'color': '54a708',
        'description': 'Deciduous Needleleaf Forests: dominated by deciduous\nneedleleaf (larch) trees (canopy >2m). Tree cover >60%.\n',
        'value': 3},
       {'color': '78d203',
        'description': 'Deciduous Broadleaf Forests: dominated by deciduous\nbroadleaf trees (canopy >2m). Tree cover >60%.',
        'value': 4},
       {'color': '009900',
        'description': 'Mixed Forests: dominated by neither deciduous nor\nevergreen (40-60% of each) tree type (canopy >2m). Tree cover >60%.\n',
        'value': 5},
       {'color': 'c6b044',
        'description': 'Closed Shrublands: dominated by woody perennials\n(1-2m height) >60% cover.',
        'value': 6},
       {'color': 'dcd159',
        'description': 'Open Shrublands: dominated by woody perennials\n(1-2m height) 10-60% cover.',
        'value': 7},
       {'color': 'dade48',
        'description': 'Woody Savannas: tree cover 30-60% (canopy >2m).',
        'value': 8},
       {'color': 'fbff13',
        'description': 'Savannas: tree cover 10-30% (canopy >2m).',
        'value': 9},
       {'color': 'b6ff05',
        'description': 'Grasslands: dominated by herbaceous annuals (<2m).',
        'value': 10},
       {'color': '27ff87',
        'description': 'Permanent Wetlands: permanently inundated lands with\n30-60% water cover and >10% vegetated cover.',
        'value': 11},
       {'color': 'c24f44',
        'description': 'Croplands: at least 60% of area is cultivated\ncropland.',
        'value': 12},
       {'color': 'a5a5a5',
        'description': 'Urban and Built-up Lands: at least 30% impervious\nsurface area including building materials, asphalt and vehicles.\n',
        'value': 13},
       {'color': 'ff6d4c',
        'description': 'Cropland/Natural Vegetation Mosaics: mosaics of\nsmall-scale cultivation 40-60% with natural tree, shrub, or herbaceous\nvegetation.\n',
        'value': 14},
       {'color': '69fff8',
        'description': 'Permanent Snow and Ice: at least 60% of area is covered\nby snow and ice for at least 10 months of the year.\n',
        'value': 15},
       {'color': 'f9ffa4',
        'description': 'Barren: at least 60% of area is non-vegetated barren\n(sand, rock, soil) areas with less than 10% vegetation.\n',
        'value': 16},
       {'color': '1c0dff',
        'description': 'Water Bodies: at least 60% of area is covered by\npermanent water bodies.',
        'value': 17}],
      'name': 'LC_Type1'},
     {'description': 'Land Cover Type 2: Annual University of Maryland (UMD) classification',
      'gee:classes': [{'color': '1c0dff',
        'description': 'Water Bodies: at least 60% of area is covered by\npermanent water bodies.',
        'value': 0},
       {'color': '05450a',
        'description': 'Evergreen Needleleaf Forests: dominated by evergreen\nconifer trees (canopy >2m). Tree cover >60%.',
        'value': 1},
       {'color': '086a10',
        'description': 'Evergreen Broadleaf Forests: dominated by evergreen\nbroadleaf and palmate trees (canopy >2m). Tree cover >60%.\n',
        'value': 2},
       {'color': '54a708',
        'description': 'Deciduous Needleleaf Forests: dominated by deciduous\nneedleleaf (larch) trees (canopy >2m). Tree cover >60%.\n',
        'value': 3},
       {'color': '78d203',
        'description': 'Deciduous Broadleaf Forests: dominated by deciduous\nbroadleaf trees (canopy >2m). Tree cover >60%.',
        'value': 4},
       {'color': '009900',
        'description': 'Mixed Forests: dominated by neither deciduous nor\nevergreen (40-60% of each) tree type (canopy >2m). Tree cover >60%.\n',
        'value': 5},
       {'color': 'c6b044',
        'description': 'Closed Shrublands: dominated by woody perennials\n(1-2m height) >60% cover.',
        'value': 6},
       {'color': 'dcd159',
        'description': 'Open Shrublands: dominated by woody perennials\n(1-2m height) 10-60% cover.',
        'value': 7},
       {'color': 'dade48',
        'description': 'Woody Savannas: tree cover 30-60% (canopy >2m).',
        'value': 8},
       {'color': 'fbff13',
        'description': 'Savannas: tree cover 10-30% (canopy >2m).',
        'value': 9},
       {'color': 'b6ff05',
        'description': 'Grasslands: dominated by herbaceous annuals (<2m).',
        'value': 10},
       {'color': '27ff87',
        'description': 'Permanent Wetlands: permanently inundated lands with\n30-60% water cover and >10% vegetated cover.',
        'value': 11},
       {'color': 'c24f44',
        'description': 'Croplands: at least 60% of area is cultivated\ncropland.',
        'value': 12},
       {'color': 'a5a5a5',
        'description': 'Urban and Built-up Lands: at least 30% impervious\nsurface area including building materials, asphalt and vehicles.\n',
        'value': 13},
       {'color': 'ff6d4c',
        'description': 'Cropland/Natural Vegetation Mosaics: mosaics of\nsmall-scale cultivation 40-60% with natural tree, shrub, or herbaceous\nvegetation.\n',
        'value': 14},
       {'color': 'f9ffa4',
        'description': 'Non-Vegetated Lands: at least 60% of area is\nnon-vegetated barren (sand, rock, soil) or permanent snow and ice with\nless than 10% vegetation.\n',
        'value': 15}],
      'name': 'LC_Type2'},
     {'description': 'Land Cover Type 3: Annual Leaf Area Index (LAI) classification',
      'gee:classes': [{'color': '1c0dff',
        'description': 'Water Bodies: at least 60% of area is covered by permanent water bodies.',
        'value': 0},
       {'color': 'b6ff05',
        'description': 'Grasslands: dominated by herbaceous annuals (<2m) including cereal croplands.',
        'value': 1},
       {'color': 'dcd159',
        'description': 'Shrublands: shrub (1-2m) cover >10%.',
        'value': 2},
       {'color': 'c24f44',
        'description': 'Broadleaf Croplands: bominated by herbaceous annuals\n(<2m) that are cultivated with broadleaf crops.',
        'value': 3},
       {'color': 'fbff13',
        'description': 'Savannas: between 10-60% tree cover (>2m).',
        'value': 4},
       {'color': '086a10',
        'description': 'Evergreen Broadleaf Forests: dominated by evergreen\nbroadleaf and palmate trees (canopy >2m). Tree cover >60%.\n',
        'value': 5},
       {'color': '78d203',
        'description': 'Deciduous Broadleaf Forests: dominated by deciduous\nbroadleaf trees (canopy >2m). Tree cover >60%.',
        'value': 6},
       {'color': '05450a',
        'description': 'Evergreen Needleleaf Forests: dominated by evergreen\nconifer trees (canopy >2m). Tree cover >60%.',
        'value': 7},
       {'color': '54a708',
        'description': 'Deciduous Needleleaf Forests: dominated by deciduous\nneedleleaf (larch) trees (canopy >2m). Tree cover >60%.\n',
        'value': 8},
       {'color': 'f9ffa4',
        'description': 'Non-Vegetated Lands: at least 60% of area is\nnon-vegetated barren (sand, rock, soil) or permanent snow and ice with\nless than 10% vegetation.\n',
        'value': 9},
       {'color': 'a5a5a5',
        'description': 'Urban and Built-up Lands: at least 30% impervious\nsurface area including building materials, asphalt and vehicles.\n',
        'value': 10}],
      'name': 'LC_Type3'},
     {'description': 'Land Cover Type 4: Annual BIOME-Biogeochemical Cycles (BGC) classification',
      'gee:classes': [{'color': '1c0dff',
        'description': 'Water Bodies: at least 60% of area is covered by\npermanent water bodies.',
        'value': 0},
       {'color': '05450a',
        'description': 'Evergreen Needleleaf Vegetation: dominated by evergreen\nconifer trees and shrubs (>1m). Woody vegetation cover >10%.\n',
        'value': 1},
       {'color': '086a10',
        'description': 'Evergreen Broadleaf Vegetation: dominated by evergreen\nbroadleaf and palmate trees and shrubs (>1m). Woody vegetation cover\n>10%.\n',
        'value': 2},
       {'color': '54a708',
        'description': 'Deciduous Needleleaf Vegetation: dominated by deciduous\nneedleleaf (larch) trees and shrubs (>1m). Woody vegetation cover\n>10%.\n',
        'value': 3},
       {'color': '78d203',
        'description': 'Deciduous Broadleaf Vegetation: dominated by deciduous\nbroadleaf trees and shrubs (>1m). Woody vegetation cover >10%.\n',
        'value': 4},
       {'color': '009900',
        'description': 'Annual Broadleaf Vegetation: dominated by herbaceous\nannuals (<2m). At least 60% cultivated broadleaf crops.\n',
        'value': 5},
       {'color': 'b6ff05',
        'description': 'Annual Grass Vegetation: dominated by herbaceous\nannuals (<2m) including cereal croplands.',
        'value': 6},
       {'color': 'f9ffa4',
        'description': 'Non-Vegetated Lands: at least 60% of area is\nnon-vegetated barren (sand, rock, soil) or permanent snow/ice with\nless than 10% vegetation.\n',
        'value': 7},
       {'color': 'a5a5a5',
        'description': 'Urban and Built-up Lands: at least 30% impervious\nsurface area including building materials, asphalt, and vehicles.\n',
        'value': 8}],
      'name': 'LC_Type4'},
     {'description': 'Land Cover Type 5: Annual Plant Functional Types classification',
      'gee:classes': [{'color': '1c0dff',
        'description': 'Water Bodies: at least 60% of area is covered by permanent water bodies.',
        'value': 0},
       {'color': '05450a',
        'description': 'Evergreen Needleleaf Trees: dominated by evergreen\nconifer trees (>2m). Tree cover >10%.',
        'value': 1},
       {'color': '086a10',
        'description': 'Evergreen Broadleaf Trees: dominated by evergreen\nbroadleaf and palmate trees (>2m). Tree cover >10%.',
        'value': 2},
       {'color': '54a708',
        'description': 'Deciduous Needleleaf Trees: dominated by deciduous\nneedleleaf (larch) trees (>2m). Tree cover >10%.',
        'value': 3},
       {'color': '78d203',
        'description': 'Deciduous Broadleaf Trees: dominated by deciduous\nbroadleaf trees (>2m). Tree cover >10%.',
        'value': 4},
       {'color': 'dcd159',
        'description': 'Shrub: Shrub (1-2m) cover >10%.',
        'value': 5},
       {'color': 'b6ff05',
        'description': 'Grass: dominated by herbaceous annuals (<2m) that are\nnot cultivated.',
        'value': 6},
       {'color': 'dade48',
        'description': 'Cereal Croplands: dominated by herbaceous annuals\n(<2m). At least 60% cultivated cereal crops.',
        'value': 7},
       {'color': 'c24f44',
        'description': 'Broadleaf Croplands: dominated by herbaceous annuals\n(<2m). At least 60% cultivated broadleaf crops.',
        'value': 8},
       {'color': 'a5a5a5',
        'description': 'Urban and Built-up Lands: at least 30% impervious\nsurface area including building materials, asphalt, and vehicles.\n',
        'value': 9},
       {'color': '69fff8',
        'description': 'Permanent Snow and Ice: at least 60% of area is covered\nby snow and ice for at least 10 months of the year.\n',
        'value': 10},
       {'color': 'f9ffa4',
        'description': 'Non-Vegetated Lands: at least 60% of area is\nnon-vegetated barren (sand, rock, soil) with\nless than 10% vegetation.\n',
        'value': 11}],
      'name': 'LC_Type5'},
     {'description': 'LCCS1 land cover layer confidence',
      'gee:units': '%',
      'name': 'LC_Prop1_Assessment'},
     {'description': 'LCCS2 land use layer confidence',
      'gee:units': '%',
      'name': 'LC_Prop2_Assessment'},
     {'description': 'LCCS3 surface hydrology layer confidence',
      'gee:units': '%',
      'name': 'LC_Prop3_Assessment'},
     {'description': 'FAO-Land Cover Classification System 1 (LCCS1) land cover layer',
      'gee:classes': [{'color': 'f9ffa4',
        'description': 'Barren: at least of area 60% is non-vegetated barren\n(sand, rock, soil) or permanent snow/ice with less than 10%\nvegetation.\n',
        'value': 1},
       {'color': '69fff8',
        'description': 'Permanent Snow and Ice: at least 60% of area is covered\nby snow and ice for at least 10 months of the year.\n',
        'value': 2},
       {'color': '1c0dff',
        'description': 'Water Bodies: at least 60% of area is covered by\npermanent water bodies.',
        'value': 3},
       {'color': '05450a',
        'description': 'Evergreen Needleleaf Forests: dominated by evergreen\nconifer trees (>2m). Tree cover >60%.',
        'value': 11},
       {'color': '086a10',
        'description': 'Evergreen Broadleaf Forests: dominated by evergreen\nbroadleaf and palmate trees (>2m). Tree cover >60%.\n',
        'value': 12},
       {'color': '54a708',
        'description': 'Deciduous Needleleaf Forests: dominated by deciduous\nneedleleaf (larch) trees (>2m). Tree cover >60%.',
        'value': 13},
       {'color': '78d203',
        'description': 'Deciduous Broadleaf Forests: dominated by deciduous\nbroadleaf trees (>2m). Tree cover >60%.',
        'value': 14},
       {'color': '005a00',
        'description': 'Mixed Broadleaf/Needleleaf Forests: co-dominated\n(40-60%) by broadleaf deciduous and evergreen needleleaf tree (>2m)\ntypes. Tree cover >60%.\n',
        'value': 15},
       {'color': '009900',
        'description': 'Mixed Broadleaf Evergreen/Deciduous Forests:\nco-dominated (40-60%) by broadleaf evergreen and deciduous tree (>2m)\ntypes. Tree cover >60%.\n',
        'value': 16},
       {'color': '006c00',
        'description': 'Open Forests: tree cover 30-60% (canopy >2m).',
        'value': 21},
       {'color': '00d000',
        'description': 'Sparse Forests: tree cover 10-30% (canopy >2m).',
        'value': 22},
       {'color': 'b6ff05',
        'description': 'Dense Herbaceous: dominated by herbaceous annuals\n(<2m) at least 60% cover.',
        'value': 31},
       {'color': '98d604',
        'description': 'Sparse Herbaceous: dominated by herbaceous annuals\n(<2m) 10-60% cover.',
        'value': 32},
       {'color': 'dcd159',
        'description': 'Dense Shrublands: dominated by woody perennials (1-2m)\n>60% cover.',
        'value': 41},
       {'color': 'f1fb58',
        'description': 'Shrubland/Grassland Mosaics: dominated by woody\nperennials (1-2m) 10-60% cover with dense herbaceous annual\nunderstory.\n',
        'value': 42},
       {'color': 'fbee65',
        'description': 'Sparse Shrublands: dominated by woody perennials (1-2m)\n10-60% cover with minimal herbaceous understory.\n',
        'value': 43}],
      'name': 'LC_Prop1'},
     {'description': 'FAO-LCCS2 land use layer',
      'gee:classes': [{'color': 'f9ffa4',
        'description': 'Barren: at least of area 60% is non-vegetated barren\n(sand, rock, soil) or permanent snow/ice with less than 10%\nvegetation.\n',
        'value': 1},
       {'color': '69fff8',
        'description': 'Permanent Snow and Ice: at least 60% of area is covered\nby snow and ice for at least 10 months of the year.\n',
        'value': 2},
       {'color': '1c0dff',
        'description': 'Water Bodies: at least 60% of area is covered by\npermanent water bodies.',
        'value': 3},
       {'color': 'a5a5a5',
        'description': 'Urban and Built-up Lands: at least 30% of area is made\nup ofimpervious surfaces including building materials, asphalt, and\nvehicles.\n',
        'value': 9},
       {'color': '003f00',
        'description': 'Dense Forests: tree cover >60% (canopy >2m).',
        'value': 10},
       {'color': '006c00',
        'description': 'Open Forests: tree cover 10-60% (canopy >2m).',
        'value': 20},
       {'color': 'e3ff77',
        'description': 'Forest/Cropland Mosaics: mosaics of small-scale\ncultivation 40-60% with >10% natural tree cover.',
        'value': 25},
       {'color': 'b6ff05',
        'description': 'Natural Herbaceous: dominated by herbaceous annuals\n(<2m). At least 10% cover.',
        'value': 30},
       {'color': '93ce04',
        'description': 'Natural Herbaceous/Croplands Mosaics: mosaics of\nsmall-scale cultivation 40-60% with natural shrub or herbaceous\nvegetation.\n',
        'value': 35},
       {'color': '77a703',
        'description': 'Herbaceous Croplands: dominated by herbaceous annuals\n(<2m). At least 60% cover. Cultivated fraction >60%.\n',
        'value': 36},
       {'color': 'dcd159',
        'description': 'Shrublands: shrub cover >60% (1-2m).',
        'value': 40}],
      'name': 'LC_Prop2'},
     {'description': 'FAO-LCCS3 surface hydrology layer',
      'gee:classes': [{'color': 'f9ffa4',
        'description': 'Barren: at least of area 60% is non-vegetated barren\n(sand, rock, soil) or permanent snow/ice with less than 10%\nvegetation.\n',
        'value': 1},
       {'color': '69fff8',
        'description': 'Permanent Snow and Ice: at least 60% of area is covered\nby snow and ice for at least 10 months of the year.\n',
        'value': 2},
       {'color': '1c0dff',
        'description': 'Water Bodies: at least 60% of area is covered by\npermanent water bodies.',
        'value': 3},
       {'color': '003f00',
        'description': 'Dense Forests: tree cover >60% (canopy >2m).',
        'value': 10},
       {'color': '006c00',
        'description': 'Open Forests: tree cover 10-60% (canopy >2m).',
        'value': 20},
       {'color': '72834a',
        'description': 'Woody Wetlands: shrub and tree cover >10% (>1m).\nPermanently or seasonally inundated.',
        'value': 27},
       {'color': 'b6ff05',
        'description': 'Grasslands: dominated by herbaceous annuals (<2m) >10% cover.',
        'value': 30},
       {'color': 'c6b044',
        'description': 'Shrublands: shrub cover >60% (1-2m).',
        'value': 40},
       {'color': '3aba73',
        'description': 'Herbaceous Wetlands: dominated by herbaceous annuals\n(<2m) >10% cover. Permanently or seasonally inundated.\n',
        'value': 50},
       {'color': '1e9db3',
        'description': 'Tundra: tree cover <10%. Snow-covered for at least 8\nmonths of the year.',
        'value': 51}],
      'name': 'LC_Prop3'},
     {'description': 'Product quality flags',
      'gee:classes': [{'description': 'Classified land: has a classification label and is land\naccording to the water mask.',
        'value': 0},
       {'description': 'Unclassified land: not classified because of missing\ndata but land according to the water mask, labeled as barren.\n',
        'value': 1},
       {'description': 'Classified water: has a classification label and is\nwater according to the water mask.',
        'value': 2},
       {'description': 'Unclassified water: not classified because of missing\ndata but water according to the water mask.',
        'value': 3},
       {'description': 'Classified sea ice: classified as snow/ice but water\nmask says it is water and less than 100m elevation, switched to\nwater.\n',
        'value': 4},
       {'description': 'Misclassified water: classified as water but water mask\nsays it is land, switched to secondary label.',
        'value': 5},
       {'description': 'Omitted snow/ice: land according to the water mask that\nwas classified as something other than snow but with a maximum annual\ntemperature below 1◦C, relabeled as snow/ice.\n',
        'value': 6},
       {'description': 'Misclassified snow/ice: land according to the water mask\nthat was classified as snow but with a minimum annual temperature\ngreater than 1◦C, relabeled as barren.\n',
        'value': 7},
       {'description': 'Backfilled label: missing label from stabilization,\nfilled with the pre-stabilized result.',
        'value': 8},
       {'description': 'Forest type changed: climate-based change to forest class.',
        'value': 9}],
      'name': 'QC'},
     {'description': 'Binary land (class 2) / water (class 1) mask derived from MOD44W',
      'gee:classes': [{'color': '1c0dff', 'description': 'Water', 'value': 1},
       {'color': 'f9ffa4', 'description': 'Land,', 'value': 2}],
      'name': 'LW'}]
    

    So, the idea is to create a repository like this one that I use to keep all the scale and offset parameters used for the scaleAndOffset() method in ee_extra : eemont updated. But, in this case, it would be a repository where we would store the collection, the band and the values, colors and descriptions just as you need them for the Dataset class! Then, sankee can just grab the data from this repository to keep all datasets updated :)

    Let me know what you think, and, if you want, I can work on creating that repository and linking it to sankee!

    Cheers,

    Dave

    opened by davemlz 5
Releases(v0.2.0)
Owner
Aaron Zuspan
Remote sensing, forests, and fire
Aaron Zuspan
A data preprocessing package for time series data. Design for machine learning and deep learning.

A data preprocessing package for time series data. Design for machine learning and deep learning.

Allen Chiang 146 Sep 18, 2022
A machine learning toolkit dedicated to time-series data

tslearn The machine learning toolkit for time series analysis in Python Section Description Installation Installing the dependencies and tslearn Getti

null 2.3k Sep 27, 2022
Tool for producing high quality forecasts for time series data that has multiple seasonality with linear or non-linear growth.

Prophet: Automatic Forecasting Procedure Prophet is a procedure for forecasting time series data based on an additive model where non-linear trends ar

Facebook 15k Oct 1, 2022
A machine learning toolkit dedicated to time-series data

tslearn The machine learning toolkit for time series analysis in Python Section Description Installation Installing the dependencies and tslearn Getti

null 2.2k Sep 23, 2022
STUMPY is a powerful and scalable Python library for computing a Matrix Profile, which can be used for a variety of time series data mining tasks

STUMPY STUMPY is a powerful and scalable library that efficiently computes something called the matrix profile, which can be used for a variety of tim

TD Ameritrade 2.4k Sep 29, 2022
Automatically build ARIMA, SARIMAX, VAR, FB Prophet and XGBoost Models on Time Series data sets with a Single Line of Code. Now updated with Dask to handle millions of rows.

Auto_TS: Auto_TimeSeries Automatically build multiple Time Series models using a Single Line of Code. Now updated with Dask. Auto_timeseries is a comp

AutoViz and Auto_ViML 486 Sep 30, 2022
MaD GUI is a basis for graphical annotation and computational analysis of time series data.

MaD GUI Machine Learning and Data Analytics Graphical User Interface MaD GUI is a basis for graphical annotation and computational analysis of time se

Machine Learning and Data Analytics Lab FAU 8 Aug 25, 2022
PyPOTS - A Python Toolbox for Data Mining on Partially-Observed Time Series

A python toolbox/library for data mining on partially-observed time series, supporting tasks of forecasting/imputation/classification/clustering on incomplete multivariate time series with missing values.

Wenjie Du 117 Sep 21, 2022
Open source time series library for Python

PyFlux PyFlux is an open source time series library for Python. The library has a good array of modern time series models, as well as a flexible array

Ross Taylor 2k Sep 21, 2022
Automatic extraction of relevant features from time series:

tsfresh This repository contains the TSFRESH python package. The abbreviation stands for "Time Series Feature extraction based on scalable hypothesis

Blue Yonder GmbH 6.7k Sep 30, 2022
A unified framework for machine learning with time series

Welcome to sktime A unified framework for machine learning with time series We provide specialized time series algorithms and scikit-learn compatible

The Alan Turing Institute 5.7k Sep 27, 2022
A statistical library designed to fill the void in Python's time series analysis capabilities, including the equivalent of R's auto.arima function.

pmdarima Pmdarima (originally pyramid-arima, for the anagram of 'py' + 'arima') is a statistical library designed to fill the void in Python's time se

alkaline-ml 1.3k Sep 29, 2022
Probabilistic time series modeling in Python

GluonTS - Probabilistic Time Series Modeling in Python GluonTS is a Python toolkit for probabilistic time series modeling, built around Apache MXNet (

Amazon Web Services - Labs 3k Sep 25, 2022
A python library for easy manipulation and forecasting of time series.

Time Series Made Easy in Python darts is a python library for easy manipulation and forecasting of time series. It contains a variety of models, from

Unit8 4.7k Sep 23, 2022
A Python package for time series classification

pyts: a Python package for time series classification pyts is a Python package for time series classification. It aims to make time series classificat

Johann Faouzi 1.3k Sep 22, 2022
Time series forecasting with PyTorch

Our article on Towards Data Science introduces the package and provides background information. Pytorch Forecasting aims to ease state-of-the-art time

Jan Beitner 2.3k Oct 2, 2022
Python module for machine learning time series:

seglearn Seglearn is a python package for machine learning time series or sequences. It provides an integrated pipeline for segmentation, feature extr

David Burns 527 Sep 12, 2022
A Python toolkit for rule-based/unsupervised anomaly detection in time series

Anomaly Detection Toolkit (ADTK) Anomaly Detection Toolkit (ADTK) is a Python package for unsupervised / rule-based time series anomaly detection. As

Arundo Analytics 863 Sep 19, 2022
AtsPy: Automated Time Series Models in Python (by @firmai)

Automated Time Series Models in Python (AtsPy) SSRN Report Easily develop state of the art time series models to forecast univariate data series. Simp

Derek Snow 459 Sep 19, 2022