This notebook demonstrates a typical scenario of retrieving PROBA-V data for specific coordinates, using the WCS interface. The WCS service used here is provided by the PROBA-V MEP, endpoints are listed on this page: https://proba-v-mep.esa.int/applications/geo-viewer

In [55]:
import datetime
from datetime import date

# URL of the WCS server
owsBaseURL='https://proba-v-mep.esa.int/applications/geo-viewer/app/geoserver/ows'



# The longitude/latitude point of interest
lon,lat = 4.71213078915, 50.5839444717

# The period of interest
startDate = date(2014, 9, 1)
endDate = date(2015, 10, 1)

# The images to be processed
ndviTS_id       = 'PV_MEP__PROBAV_S5_TOC_100M_NDVI'
ndvi300TS_id    = 'PV_MEP__PROBAV_S10_TOC_333M_NDVI'
bitmaskTS_id    = 'PV_MEP__PROBAV_S5_TOC_100M_BITMASK'
bitmask300TS_id = 'PV_MEP__PROBAV_S10_TOC_333M_BITMASK'

We first retrieve the identifiers of all coverages available in the WCS. The identifier is needed later on to retrieve time series. The PROBA-V MEP WCS names coverages based on the product type, and band that they contain.

In [35]:
import requests
from xml.etree import ElementTree

def getCoverages():

    payload = {
        'service': 'WCS',
        'request': 'GetCapabilities',
        'version': '2.0.1',
    }
    
    response = requests.get(owsBaseURL, params=payload)
    tree = ElementTree.fromstring(response.content)
    namespaces = {
        'wcs': 'http://www.opengis.net/wcs/1.1.1',
        'wcs2': 'http://www.opengis.net/wcs/2.0'
    }
    
    coverages = map(lambda x:x.text, tree.findall('wcs2:Contents/wcs2:CoverageSummary/wcs2:CoverageId',namespaces))
    return coverages

coverages = getCoverages()
print "\n".join(coverages)
PV_MEP__PROBAV_S10_TOC_1KM_BITMASK
PV_MEP__PROBAV_S10_TOC_1KM_BROWSE
PV_MEP__PROBAV_S10_TOC_1KM_GEOMETRY
PV_MEP__PROBAV_S10_TOC_1KM_NDVI
PV_MEP__PROBAV_S10_TOC_1KM_RADIOMETRY
PV_MEP__PROBAV_S10_TOC_333M_BITMASK
PV_MEP__PROBAV_S10_TOC_333M_BROWSE
PV_MEP__PROBAV_S10_TOC_333M_GEOMETRY
PV_MEP__PROBAV_S10_TOC_333M_NDVI
PV_MEP__PROBAV_S10_TOC_333M_RADIOMETRY
PV_MEP__PROBAV_S1_TOA_1KM_BITMASK
PV_MEP__PROBAV_S1_TOA_1KM_BROWSE
PV_MEP__PROBAV_S1_TOA_1KM_GEOMETRY
PV_MEP__PROBAV_S1_TOA_1KM_NDVI
PV_MEP__PROBAV_S1_TOA_1KM_RADIOMETRY
PV_MEP__PROBAV_S1_TOA_333M_BITMASK
PV_MEP__PROBAV_S1_TOA_333M_BROWSE
PV_MEP__PROBAV_S1_TOA_333M_GEOMETRY
PV_MEP__PROBAV_S1_TOA_333M_NDVI
PV_MEP__PROBAV_S1_TOA_333M_RADIOMETRY
PV_MEP__PROBAV_S1_TOC_1KM_BITMASK
PV_MEP__PROBAV_S1_TOC_1KM_BROWSE
PV_MEP__PROBAV_S1_TOC_1KM_GEOMETRY
PV_MEP__PROBAV_S1_TOC_1KM_NDVI
PV_MEP__PROBAV_S1_TOC_1KM_RADIOMETRY
PV_MEP__PROBAV_S1_TOC_333M_BITMASK
PV_MEP__PROBAV_S1_TOC_333M_BROWSE
PV_MEP__PROBAV_S1_TOC_333M_GEOMETRY
PV_MEP__PROBAV_S1_TOC_333M_NDVI
PV_MEP__PROBAV_S1_TOC_333M_RADIOMETRY
PV_MEP__PROBAV_S5_TOA_100M_BITMASK
PV_MEP__PROBAV_S5_TOA_100M_BROWSE
PV_MEP__PROBAV_S5_TOA_100M_GEOMETRY
PV_MEP__PROBAV_S5_TOA_100M_NDVI
PV_MEP__PROBAV_S5_TOA_100M_RADIOMETRY
PV_MEP__PROBAV_S5_TOC_100M_BITMASK
PV_MEP__PROBAV_S5_TOC_100M_BROWSE
PV_MEP__PROBAV_S5_TOC_100M_GEOMETRY
PV_MEP__PROBAV_S5_TOC_100M_NDVI
PV_MEP__PROBAV_S5_TOC_100M_RADIOMETRY

As an example of metadata retrieval, we retrieve the dates of the PROBAV_S10_TOC_1KM_RADIOMETRY coverage. Retrieving the dates is only useful to give us an idea of what data is available.

In [28]:
def getDates(coverage):
    payload = {
        'service': 'WCS',
        'request': 'DescribeCoverage',
        'version': '2.0.1',
        'coverageId': coverage
    }

    response = requests.get(owsBaseURL, params=payload)
    tree = ElementTree.fromstring(response.content)
    namespaces = {
        'wcs': 'http://www.opengis.net/wcs/1.1.1',
        'wcs2': 'http://www.opengis.net/wcs/2.0',
        'wcsgs': 'http://www.geoserver.org/wcsgs/2.0',
        'gmlcov': 'http://www.opengis.net/gmlcov/1.0',
        'gml': 'http://www.opengis.net/gml/3.2'
    }
    return map(lambda x:x.text, tree.findall('wcs2:CoverageDescription/gmlcov:metadata/gmlcov:Extension/wcsgs:TimeDomain/gml:TimeInstant/gml:timePosition',namespaces))
In [29]:
print getDates("PV_MEP__PROBAV_S10_TOC_1KM_RADIOMETRY")
['2013-10-11T00:00:00.000Z', '2013-10-21T00:00:00.000Z', '2013-11-01T00:00:00.000Z', '2013-11-11T00:00:00.000Z', '2013-11-21T00:00:00.000Z', '2013-12-01T00:00:00.000Z', '2013-12-11T00:00:00.000Z', '2013-12-21T00:00:00.000Z', '2014-01-01T00:00:00.000Z', '2014-01-11T00:00:00.000Z', '2014-01-21T00:00:00.000Z', '2014-02-01T00:00:00.000Z', '2014-02-11T00:00:00.000Z', '2014-02-21T00:00:00.000Z', '2014-03-01T00:00:00.000Z', '2014-03-11T00:00:00.000Z', '2014-03-21T00:00:00.000Z', '2014-04-01T00:00:00.000Z', '2014-04-11T00:00:00.000Z', '2014-04-21T00:00:00.000Z', '2014-05-01T00:00:00.000Z', '2014-05-11T00:00:00.000Z', '2014-05-21T00:00:00.000Z', '2014-06-01T00:00:00.000Z', '2014-06-11T00:00:00.000Z', '2014-06-21T00:00:00.000Z', '2014-07-01T00:00:00.000Z', '2014-07-11T00:00:00.000Z', '2014-07-21T00:00:00.000Z', '2014-08-01T00:00:00.000Z', '2014-08-11T00:00:00.000Z', '2014-08-21T00:00:00.000Z', '2014-09-01T00:00:00.000Z', '2014-09-11T00:00:00.000Z', '2014-09-21T00:00:00.000Z', '2014-10-01T00:00:00.000Z', '2014-10-11T00:00:00.000Z', '2014-10-21T00:00:00.000Z', '2014-11-01T00:00:00.000Z', '2014-11-11T00:00:00.000Z', '2014-11-21T00:00:00.000Z', '2014-12-01T00:00:00.000Z', '2014-12-11T00:00:00.000Z', '2014-12-21T00:00:00.000Z', '2015-01-01T00:00:00.000Z', '2015-01-11T00:00:00.000Z', '2015-01-21T00:00:00.000Z', '2015-02-01T00:00:00.000Z', '2015-02-11T00:00:00.000Z', '2015-02-21T00:00:00.000Z', '2015-03-01T00:00:00.000Z', '2015-03-11T00:00:00.000Z', '2015-03-21T00:00:00.000Z', '2015-04-01T00:00:00.000Z', '2015-04-11T00:00:00.000Z', '2015-04-21T00:00:00.000Z', '2015-05-01T00:00:00.000Z', '2015-05-11T00:00:00.000Z', '2015-05-21T00:00:00.000Z', '2015-06-01T00:00:00.000Z', '2015-06-11T00:00:00.000Z', '2015-06-21T00:00:00.000Z', '2015-07-01T00:00:00.000Z', '2015-07-11T00:00:00.000Z', '2015-07-21T00:00:00.000Z', '2015-08-01T00:00:00.000Z', '2015-08-11T00:00:00.000Z', '2015-08-21T00:00:00.000Z', '2015-09-01T00:00:00.000Z', '2015-09-11T00:00:00.000Z', '2015-09-21T00:00:00.000Z', '2015-10-01T00:00:00.000Z', '2015-10-11T00:00:00.000Z', '2015-10-21T00:00:00.000Z', '2015-11-01T00:00:00.000Z', '2015-11-11T00:00:00.000Z', '2015-11-21T00:00:00.000Z', '2015-12-01T00:00:00.000Z', '2015-12-11T00:00:00.000Z', '2015-12-21T00:00:00.000Z', '2016-01-01T00:00:00.000Z', '2016-01-11T00:00:00.000Z', '2016-01-21T00:00:00.000Z', '2016-02-01T00:00:00.000Z', '2016-02-11T00:00:00.000Z', '2016-02-21T00:00:00.000Z', '2016-03-01T00:00:00.000Z', '2016-03-11T00:00:00.000Z', '2016-03-21T00:00:00.000Z', '2016-04-01T00:00:00.000Z', '2016-04-11T00:00:00.000Z', '2016-04-21T00:00:00.000Z', '2016-05-01T00:00:00.000Z', '2016-05-11T00:00:00.000Z', '2016-05-21T00:00:00.000Z', '2016-06-01T00:00:00.000Z', '2016-06-11T00:00:00.000Z', '2016-06-21T00:00:00.000Z', '2016-07-01T00:00:00.000Z', '2016-07-11T00:00:00.000Z', '2016-07-21T00:00:00.000Z', '2016-08-01T00:00:00.000Z', '2016-08-11T00:00:00.000Z', '2016-08-21T00:00:00.000Z', '2016-09-01T00:00:00.000Z', '2016-09-11T00:00:00.000Z', '2016-09-21T00:00:00.000Z', '2016-10-01T00:00:00.000Z', '2016-10-11T00:00:00.000Z', '2016-10-21T00:00:00.000Z', '2016-11-01T00:00:00.000Z', '2016-11-11T00:00:00.000Z', '2016-11-21T00:00:00.000Z', '2016-12-01T00:00:00.000Z', '2016-12-11T00:00:00.000Z', '2016-12-21T00:00:00.000Z', '2017-01-01T00:00:00.000Z', '2017-01-11T00:00:00.000Z', '2017-01-21T00:00:00.000Z', '2017-02-01T00:00:00.000Z', '2017-02-11T00:00:00.000Z', '2017-02-21T00:00:00.000Z', '2017-03-01T00:00:00.000Z', '2017-03-11T00:00:00.000Z']

The PROBA-V MEP WCS web service requires our PROBA-V MEP credentials. We do want to avoid sharing those credentials with other users by accident, so we do not put them directly in the notebook, but use a small input widget instead.

In [36]:
import getpass
# Username and password
username = raw_input()
password = getpass.getpass()

credentials=(username, password)
driesj
········

Now for the actual data retrieval from the WCS service, we first define a function that wraps our requests, and then run it on different sets of parameters. Depending on the length of the time series you request, it can take the server up to 2 minutes to process, so be patient.

In [56]:
import datetime
import matplotlib.pyplot as plt
from datetime import date

def pointWCSRequest(coverageId, lon, lat, startDate = None, endDate = None):
    
    wcsURL = owsBaseURL
    
    payload = {
        'SERVICE': 'WCS',
        'REQUEST': 'GetCoverage',
        'VERSION': '2.0.1',
        'coverageId': coverageId,
        'FORMAT': 'application/json',
        'subset': ['Long,http://www.opengis.net/def/crs/EPSG/0/4326('+str(lon)+')',
                   'Lat,http://www.opengis.net/def/crs/EPSG/0/4326('+str(lat)+')']
    }
        
    if startDate != None and endDate != None:
        timeSubset = 'time("'+startDate.strftime('%Y-%m-%dT%H:%M:%S.000Z')+'","'+endDate.strftime('%Y-%m-%dT%H:%M:%S.000Z')+'")'
        payload['subset'].append(timeSubset)    
    
    return requests.get(wcsURL, params=payload, auth=credentials)


def wcsTimeSeries(coverageID, lon, lat, startDate = None, endDate = None):
    response = pointWCSRequest(coverageID, lon, lat, startDate, endDate)
    timeSeries = response.json()['timeseries']
    timeSeries = map(lambda x:[datetime.datetime.fromtimestamp(x[0]/1000),x[1]], timeSeries)
    return timeSeries


def plotTimeSeries(timeSeries):
    timeAxis = map(lambda x:x[0], timeSeries)
    valueAxis = map(lambda x:x[1],timeSeries)
    plt.figure(figsize=(25,10))
    plt.plot(timeAxis, valueAxis, 'ro')

    
%time ndviTS       = wcsTimeSeries(ndviTS_id, lon, lat, startDate, endDate)
print(ndviTS)
%time bitmaskTS    = wcsTimeSeries(bitmaskTS_id, lon, lat, startDate, endDate)
print(bitmaskTS)
%time ndvi300TS    = wcsTimeSeries(ndvi300TS_id, lon, lat, startDate, endDate)
print(ndvi300TS)
%time bitmask300TS = wcsTimeSeries(bitmask300TS_id, lon, lat, startDate, endDate)
print(bitmask300TS)

# filter nodata values
for i, ts in enumerate(ndviTS):
    if ts[1] == 255:
        del ndviTS[i]
        del bitmaskTS[i]
CPU times: user 43.3 ms, sys: 7.38 ms, total: 50.7 ms
Wall time: 1min 34s
[[datetime.datetime(2014, 9, 1, 0, 0), 181.0], [datetime.datetime(2014, 9, 6, 0, 0), 34.0], [datetime.datetime(2014, 9, 11, 0, 0), 105.0], [datetime.datetime(2014, 9, 16, 0, 0), 110.0], [datetime.datetime(2014, 9, 21, 0, 0), 35.0], [datetime.datetime(2014, 9, 26, 0, 0), 0.0], [datetime.datetime(2014, 10, 1, 0, 0), 113.0], [datetime.datetime(2014, 10, 6, 0, 0), 9.0], [datetime.datetime(2014, 10, 11, 0, 0), 41.0], [datetime.datetime(2014, 10, 16, 0, 0), 37.0], [datetime.datetime(2014, 10, 21, 0, 0), 27.0], [datetime.datetime(2014, 10, 26, 0, 0), 73.0], [datetime.datetime(2014, 11, 1, 0, 0), 29.0], [datetime.datetime(2014, 11, 6, 0, 0), 112.0], [datetime.datetime(2014, 11, 11, 0, 0), 157.0], [datetime.datetime(2014, 11, 16, 0, 0), 51.0], [datetime.datetime(2014, 11, 21, 0, 0), 150.0], [datetime.datetime(2014, 11, 26, 0, 0), 255.0], [datetime.datetime(2014, 12, 1, 0, 0), 22.0], [datetime.datetime(2014, 12, 6, 0, 0), 107.0], [datetime.datetime(2014, 12, 11, 0, 0), 37.0], [datetime.datetime(2014, 12, 16, 0, 0), 38.0], [datetime.datetime(2014, 12, 21, 0, 0), 18.0], [datetime.datetime(2014, 12, 26, 0, 0), 34.0], [datetime.datetime(2015, 1, 1, 0, 0), 36.0], [datetime.datetime(2015, 1, 6, 0, 0), 29.0], [datetime.datetime(2015, 1, 11, 0, 0), 42.0], [datetime.datetime(2015, 1, 16, 0, 0), 41.0], [datetime.datetime(2015, 1, 21, 0, 0), 25.0], [datetime.datetime(2015, 1, 26, 0, 0), 36.0], [datetime.datetime(2015, 2, 1, 0, 0), 57.0], [datetime.datetime(2015, 2, 6, 0, 0), 110.0], [datetime.datetime(2015, 2, 11, 0, 0), 122.0], [datetime.datetime(2015, 2, 16, 0, 0), 89.0], [datetime.datetime(2015, 2, 21, 0, 0), 24.0], [datetime.datetime(2015, 2, 26, 0, 0), 27.0], [datetime.datetime(2015, 3, 1, 0, 0), 68.0], [datetime.datetime(2015, 3, 6, 0, 0), 63.0], [datetime.datetime(2015, 3, 11, 0, 0), 82.0], [datetime.datetime(2015, 3, 16, 0, 0), 69.0], [datetime.datetime(2015, 3, 21, 0, 0), 25.0], [datetime.datetime(2015, 3, 26, 0, 0), 32.0], [datetime.datetime(2015, 4, 1, 0, 0), 26.0], [datetime.datetime(2015, 4, 6, 0, 0), 139.0], [datetime.datetime(2015, 4, 11, 0, 0), 135.0], [datetime.datetime(2015, 4, 16, 0, 0), 142.0], [datetime.datetime(2015, 4, 21, 0, 0), 140.0], [datetime.datetime(2015, 4, 26, 0, 0), 28.0], [datetime.datetime(2015, 5, 1, 0, 0), 84.0], [datetime.datetime(2015, 5, 6, 0, 0), 71.0], [datetime.datetime(2015, 5, 11, 0, 0), 152.0], [datetime.datetime(2015, 5, 16, 0, 0), 129.0], [datetime.datetime(2015, 5, 21, 0, 0), 35.0], [datetime.datetime(2015, 5, 26, 0, 0), 62.0], [datetime.datetime(2015, 6, 1, 0, 0), 134.0], [datetime.datetime(2015, 6, 6, 0, 0), 174.0], [datetime.datetime(2015, 6, 11, 0, 0), 159.0], [datetime.datetime(2015, 6, 16, 0, 0), 46.0], [datetime.datetime(2015, 6, 21, 0, 0), 50.0], [datetime.datetime(2015, 6, 26, 0, 0), 106.0], [datetime.datetime(2015, 7, 1, 0, 0), 184.0], [datetime.datetime(2015, 7, 6, 0, 0), 42.0], [datetime.datetime(2015, 7, 11, 0, 0), 162.0], [datetime.datetime(2015, 7, 16, 0, 0), 163.0], [datetime.datetime(2015, 7, 21, 0, 0), 51.0], [datetime.datetime(2015, 7, 26, 0, 0), 166.0], [datetime.datetime(2015, 8, 1, 0, 0), 178.0], [datetime.datetime(2015, 8, 6, 0, 0), 126.0], [datetime.datetime(2015, 8, 11, 0, 0), 68.0], [datetime.datetime(2015, 8, 16, 0, 0), 0.0], [datetime.datetime(2015, 8, 21, 0, 0), 156.0], [datetime.datetime(2015, 8, 26, 0, 0), 153.0], [datetime.datetime(2015, 9, 1, 0, 0), 49.0], [datetime.datetime(2015, 9, 6, 0, 0), 161.0], [datetime.datetime(2015, 9, 11, 0, 0), 59.0], [datetime.datetime(2015, 9, 16, 0, 0), 27.0], [datetime.datetime(2015, 9, 21, 0, 0), 30.0], [datetime.datetime(2015, 9, 26, 0, 0), 159.0], [datetime.datetime(2015, 10, 1, 0, 0), 155.0]]
CPU times: user 47.3 ms, sys: 0 ns, total: 47.3 ms
Wall time: 38.6 s
[[datetime.datetime(2014, 9, 1, 0, 0), 251.0], [datetime.datetime(2014, 9, 6, 0, 0), 123.0], [datetime.datetime(2014, 9, 11, 0, 0), 251.0], [datetime.datetime(2014, 9, 16, 0, 0), 251.0], [datetime.datetime(2014, 9, 21, 0, 0), 123.0], [datetime.datetime(2014, 9, 26, 0, 0), 59.0], [datetime.datetime(2014, 10, 1, 0, 0), 248.0], [datetime.datetime(2014, 10, 6, 0, 0), 187.0], [datetime.datetime(2014, 10, 11, 0, 0), 251.0], [datetime.datetime(2014, 10, 16, 0, 0), 251.0], [datetime.datetime(2014, 10, 21, 0, 0), 251.0], [datetime.datetime(2014, 10, 26, 0, 0), 251.0], [datetime.datetime(2014, 11, 1, 0, 0), 251.0], [datetime.datetime(2014, 11, 6, 0, 0), 251.0], [datetime.datetime(2014, 11, 11, 0, 0), 248.0], [datetime.datetime(2014, 11, 16, 0, 0), 251.0], [datetime.datetime(2014, 11, 21, 0, 0), 248.0], [datetime.datetime(2014, 11, 26, 0, 0), 10.0], [datetime.datetime(2014, 12, 1, 0, 0), 251.0], [datetime.datetime(2014, 12, 6, 0, 0), 248.0], [datetime.datetime(2014, 12, 11, 0, 0), 251.0], [datetime.datetime(2014, 12, 16, 0, 0), 251.0], [datetime.datetime(2014, 12, 21, 0, 0), 251.0], [datetime.datetime(2014, 12, 26, 0, 0), 251.0], [datetime.datetime(2015, 1, 1, 0, 0), 251.0], [datetime.datetime(2015, 1, 6, 0, 0), 251.0], [datetime.datetime(2015, 1, 11, 0, 0), 251.0], [datetime.datetime(2015, 1, 16, 0, 0), 251.0], [datetime.datetime(2015, 1, 21, 0, 0), 251.0], [datetime.datetime(2015, 1, 26, 0, 0), 251.0], [datetime.datetime(2015, 2, 1, 0, 0), 251.0], [datetime.datetime(2015, 2, 6, 0, 0), 248.0], [datetime.datetime(2015, 2, 11, 0, 0), 248.0], [datetime.datetime(2015, 2, 16, 0, 0), 251.0], [datetime.datetime(2015, 2, 21, 0, 0), 123.0], [datetime.datetime(2015, 2, 26, 0, 0), 251.0], [datetime.datetime(2015, 3, 1, 0, 0), 251.0], [datetime.datetime(2015, 3, 6, 0, 0), 251.0], [datetime.datetime(2015, 3, 11, 0, 0), 251.0], [datetime.datetime(2015, 3, 16, 0, 0), 251.0], [datetime.datetime(2015, 3, 21, 0, 0), 123.0], [datetime.datetime(2015, 3, 26, 0, 0), 251.0], [datetime.datetime(2015, 4, 1, 0, 0), 123.0], [datetime.datetime(2015, 4, 6, 0, 0), 251.0], [datetime.datetime(2015, 4, 11, 0, 0), 251.0], [datetime.datetime(2015, 4, 16, 0, 0), 248.0], [datetime.datetime(2015, 4, 21, 0, 0), 248.0], [datetime.datetime(2015, 4, 26, 0, 0), 123.0], [datetime.datetime(2015, 5, 1, 0, 0), 251.0], [datetime.datetime(2015, 5, 6, 0, 0), 251.0], [datetime.datetime(2015, 5, 11, 0, 0), 248.0], [datetime.datetime(2015, 5, 16, 0, 0), 248.0], [datetime.datetime(2015, 5, 21, 0, 0), 123.0], [datetime.datetime(2015, 5, 26, 0, 0), 251.0], [datetime.datetime(2015, 6, 1, 0, 0), 248.0], [datetime.datetime(2015, 6, 6, 0, 0), 248.0], [datetime.datetime(2015, 6, 11, 0, 0), 251.0], [datetime.datetime(2015, 6, 16, 0, 0), 123.0], [datetime.datetime(2015, 6, 21, 0, 0), 251.0], [datetime.datetime(2015, 6, 26, 0, 0), 251.0], [datetime.datetime(2015, 7, 1, 0, 0), 248.0], [datetime.datetime(2015, 7, 6, 0, 0), 123.0], [datetime.datetime(2015, 7, 11, 0, 0), 248.0], [datetime.datetime(2015, 7, 16, 0, 0), 248.0], [datetime.datetime(2015, 7, 21, 0, 0), 251.0], [datetime.datetime(2015, 7, 26, 0, 0), 249.0], [datetime.datetime(2015, 8, 1, 0, 0), 248.0], [datetime.datetime(2015, 8, 6, 0, 0), 251.0], [datetime.datetime(2015, 8, 11, 0, 0), 251.0], [datetime.datetime(2015, 8, 16, 0, 0), 59.0], [datetime.datetime(2015, 8, 21, 0, 0), 248.0], [datetime.datetime(2015, 8, 26, 0, 0), 248.0], [datetime.datetime(2015, 9, 1, 0, 0), 155.0], [datetime.datetime(2015, 9, 6, 0, 0), 251.0], [datetime.datetime(2015, 9, 11, 0, 0), 251.0], [datetime.datetime(2015, 9, 16, 0, 0), 251.0], [datetime.datetime(2015, 9, 21, 0, 0), 123.0], [datetime.datetime(2015, 9, 26, 0, 0), 248.0], [datetime.datetime(2015, 10, 1, 0, 0), 248.0]]
CPU times: user 43.9 ms, sys: 894 µs, total: 44.8 ms
Wall time: 1min 4s
[[datetime.datetime(2014, 9, 1, 0, 0), 134.0], [datetime.datetime(2014, 9, 11, 0, 0), 141.0], [datetime.datetime(2014, 9, 21, 0, 0), 108.0], [datetime.datetime(2014, 10, 1, 0, 0), 116.0], [datetime.datetime(2014, 10, 11, 0, 0), 75.0], [datetime.datetime(2014, 10, 21, 0, 0), 129.0], [datetime.datetime(2014, 11, 1, 0, 0), 107.0], [datetime.datetime(2014, 11, 11, 0, 0), 115.0], [datetime.datetime(2014, 11, 21, 0, 0), 114.0], [datetime.datetime(2014, 12, 1, 0, 0), 104.0], [datetime.datetime(2014, 12, 11, 0, 0), 64.0], [datetime.datetime(2014, 12, 21, 0, 0), 48.0], [datetime.datetime(2015, 1, 1, 0, 0), 92.0], [datetime.datetime(2015, 1, 11, 0, 0), 89.0], [datetime.datetime(2015, 1, 21, 0, 0), 65.0], [datetime.datetime(2015, 2, 1, 0, 0), 93.0], [datetime.datetime(2015, 2, 11, 0, 0), 97.0], [datetime.datetime(2015, 2, 21, 0, 0), 55.0], [datetime.datetime(2015, 3, 1, 0, 0), 92.0], [datetime.datetime(2015, 3, 11, 0, 0), 101.0], [datetime.datetime(2015, 3, 21, 0, 0), 90.0], [datetime.datetime(2015, 4, 1, 0, 0), 122.0], [datetime.datetime(2015, 4, 11, 0, 0), 147.0], [datetime.datetime(2015, 4, 21, 0, 0), 154.0], [datetime.datetime(2015, 5, 1, 0, 0), 166.0], [datetime.datetime(2015, 5, 11, 0, 0), 147.0], [datetime.datetime(2015, 5, 21, 0, 0), 142.0], [datetime.datetime(2015, 6, 1, 0, 0), 177.0], [datetime.datetime(2015, 6, 11, 0, 0), 187.0], [datetime.datetime(2015, 6, 21, 0, 0), 174.0], [datetime.datetime(2015, 7, 1, 0, 0), 206.0], [datetime.datetime(2015, 7, 11, 0, 0), 155.0], [datetime.datetime(2015, 7, 21, 0, 0), 141.0], [datetime.datetime(2015, 8, 1, 0, 0), 154.0], [datetime.datetime(2015, 8, 11, 0, 0), 116.0], [datetime.datetime(2015, 8, 21, 0, 0), 139.0], [datetime.datetime(2015, 9, 1, 0, 0), 134.0], [datetime.datetime(2015, 9, 11, 0, 0), 133.0], [datetime.datetime(2015, 9, 21, 0, 0), 137.0], [datetime.datetime(2015, 10, 1, 0, 0), 157.0]]
CPU times: user 42.3 ms, sys: 549 µs, total: 42.9 ms
Wall time: 28.3 s
[[datetime.datetime(2014, 9, 1, 0, 0), 248.0], [datetime.datetime(2014, 9, 11, 0, 0), 248.0], [datetime.datetime(2014, 9, 21, 0, 0), 251.0], [datetime.datetime(2014, 10, 1, 0, 0), 248.0], [datetime.datetime(2014, 10, 11, 0, 0), 251.0], [datetime.datetime(2014, 10, 21, 0, 0), 248.0], [datetime.datetime(2014, 11, 1, 0, 0), 248.0], [datetime.datetime(2014, 11, 11, 0, 0), 248.0], [datetime.datetime(2014, 11, 21, 0, 0), 248.0], [datetime.datetime(2014, 12, 1, 0, 0), 248.0], [datetime.datetime(2014, 12, 11, 0, 0), 251.0], [datetime.datetime(2014, 12, 21, 0, 0), 251.0], [datetime.datetime(2015, 1, 1, 0, 0), 251.0], [datetime.datetime(2015, 1, 11, 0, 0), 251.0], [datetime.datetime(2015, 1, 21, 0, 0), 251.0], [datetime.datetime(2015, 2, 1, 0, 0), 248.0], [datetime.datetime(2015, 2, 11, 0, 0), 248.0], [datetime.datetime(2015, 2, 21, 0, 0), 251.0], [datetime.datetime(2015, 3, 1, 0, 0), 248.0], [datetime.datetime(2015, 3, 11, 0, 0), 248.0], [datetime.datetime(2015, 3, 21, 0, 0), 251.0], [datetime.datetime(2015, 4, 1, 0, 0), 248.0], [datetime.datetime(2015, 4, 11, 0, 0), 248.0], [datetime.datetime(2015, 4, 21, 0, 0), 248.0], [datetime.datetime(2015, 5, 1, 0, 0), 248.0], [datetime.datetime(2015, 5, 11, 0, 0), 248.0], [datetime.datetime(2015, 5, 21, 0, 0), 248.0], [datetime.datetime(2015, 6, 1, 0, 0), 248.0], [datetime.datetime(2015, 6, 11, 0, 0), 248.0], [datetime.datetime(2015, 6, 21, 0, 0), 248.0], [datetime.datetime(2015, 7, 1, 0, 0), 248.0], [datetime.datetime(2015, 7, 11, 0, 0), 248.0], [datetime.datetime(2015, 7, 21, 0, 0), 248.0], [datetime.datetime(2015, 8, 1, 0, 0), 248.0], [datetime.datetime(2015, 8, 11, 0, 0), 251.0], [datetime.datetime(2015, 8, 21, 0, 0), 248.0], [datetime.datetime(2015, 9, 1, 0, 0), 248.0], [datetime.datetime(2015, 9, 11, 0, 0), 248.0], [datetime.datetime(2015, 9, 21, 0, 0), 248.0], [datetime.datetime(2015, 10, 1, 0, 0), 248.0]]

This notebook uses mpld3 for plotting, which has the same API as matplotlib, but generates html instead of static images. The cell below shows how to ensure that this package is installed.

In [5]:
# Install some additional python libraries

import sys

! pip27 install --user mpld3
The directory '/home/driesj/.cache/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
The directory '/home/driesj/.cache/pip' or its parent directory is not owned by the current user and caching wheels has been disabled. check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
Requirement already satisfied: mpld3 in /home/driesj/.local/lib/python2.7/site-packages

Now we plot the data using matplotlib. We use different colors to indicate whether the given point is flagged as a clear pixel or not. We also draw a line through clear pixels.

In [61]:
# Plot the data

%matplotlib inline

import matplotlib
import matplotlib.pyplot as plt

fig, ax = plt.subplots()
fig.set_size_inches(12, 4)
ndviTimeStamps = map(lambda x:x[0], ndviTS)
ndviValues = map(lambda x:(x[1]-20)/250, ndviTS)
bitmaskValues = map(lambda x:int(x[1])&7, bitmaskTS)
print bitmaskValues

clear=filter(lambda t:t[1]==0,zip(ndviValues,bitmaskValues,ndviTimeStamps))
clearValues =  list(map(lambda t:t[0],clear))

ax.plot(list(map(lambda t:t[2],clear)), clearValues)

cmp = matplotlib.colors.ListedColormap(
    [ 'green'  # clear (0)
     ,'red'    # shadow (1)
     ,'orange' # unknown (2)
     ,'grey'   # cloud (3)
     ,'blue'], # ice (4)
    5)


scatter = ax.scatter(ndviTimeStamps, ndviValues, c=bitmaskValues, s=50, cmap=cmp)
ndvi300TimeStamps = map(lambda x:x[0], ndvi300TS)
ndvi300Values = map(lambda x:(x[1]-20)/250, ndvi300TS)
bitmask300Values = map(lambda x:int(x[1])&7, bitmask300TS)

clear300=filter(lambda t:t[1]==0,zip(ndvi300Values,bitmask300Values,ndvi300TimeStamps))
clear300Values =  list(map(lambda t:t[0],clear300))

ax.plot(list(map(lambda t:t[2],clear300)), clear300Values)
scatter300 = ax.scatter(ndvi300TimeStamps, ndvi300Values,c=bitmask300Values,marker='^',s=50,cmap=cmp)

import mpld3

css = '''
    table
    {
        border-spacing: 10px;
        border-collapse: separate;
        background-color: #cccccc;
    }
    td
    {
        background-color: #cccccc;
    }
    table, td
    {
        font-family: Arial, Helvetica, sans-serif;
        text-align: left;
    }
'''

labels = ['''<table>
             <tr>
               <td>NDVI:</td>
               <td>{0}</td>
             </tr>
             <tr>
               <td>Date:</td>
               <td>{1}</td>
             </tr>             
             <tr>
               <td>Bitmask:</td>
               <td>{2}</td>
             </tr>                          
           </table>'''
          .format((ts[1]-20)/250,ts[0].strftime('%d-%m-%Y'),int(bitmaskTS[index][1])) for index, ts in enumerate(ndviTS)]

# tooltip = mpld3.plugins.PointLabelTooltip(scatter, labels=labels)
tooltip = mpld3.plugins.PointHTMLTooltip(scatter, labels=labels, css=css)
mpld3.plugins.connect(fig, tooltip)

mpld3.display(fig)
[3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 3, 3, 3, 0, 0, 3, 3, 0, 0, 3, 3, 3, 3, 0, 3, 0, 0, 3, 1, 0, 3, 3, 3, 0, 0, 3, 3, 3, 3, 3, 0, 0]
Out[61]:
In [ ]: