<jupyter_start><jupyter_text>Welcome to the WPS quick data explorer<jupyter_code>#%matplotlib widget
import ee
import datetime
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import ipywidgets as widgets
from ipywidgets import Layout, AppLayout, Dropdown, Output, Textarea, VBox, Label, DatePicker, HBox
import pandas as pd
from pandas import date_range
import geemap
import bqplot as bq
import numpy as np
def get_vis_params(dataset):
    if dataset=='NDVI':
        vis_params = {
          'min': 0.0,
          'max': 1,
          'palette': [
            'FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718', '74A901',
            '66A000', '529400', '3E8601', '207401', '056201', '004C00', '023B01',
            '012E01', '011D01', '011301'
          ],
        }
    if dataset=='Surface Soil Moisture':
        vis_params = {
          'min': 0.0,
          'max': 100,
          'palette': [
            'FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718', '74A901',
            '66A000', '529400', '3E8601', '207401', '056201', '004C00', '023B01',
            '012E01', '011D01', '011301'
          ],
        }
    if dataset=='Evapotranspiration':
        vis_params = {
          'min': 0.0,
          'max': 10,
          'palette': [
            'FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718', '74A901',
            '66A000', '529400', '3E8601', '207401', '056201', '004C00', '023B01',
            '012E01', '011D01', '011301'
          ],
        }
    if dataset=='outline':
        vis_params = {
        "color": "00000088",
        "width": 2,
        "edges": True}
    if dataset=='anomaly':
        vis_params = {
          'min':-60,
          'max': 60,
          'palette': ['#B40426', '#E6745B', '#F6B69B', '#DDDDDD', '#A9C5FC', '#6F91F2', '#3B4CC0']
        }
    return vis_params

#initialize map and GEE
Map = geemap.Map(center=(0, -10), zoom=2, width='400px', height='400px')


datasets = {
    'NDVI': [ee.ImageCollection("MODIS/006/MOD13A1"), 'NDVI', 'NDVI [-]', 0.0001],
    'Surface Soil Moisture' : [ee.ImageCollection("NASA_USDA/HSL/SMAP10KM_soil_moisture"), 'ssm','ssm [mm]', 1],
    'Evapotranspiration' : [ee.ImageCollection("FAO/WAPOR/2/L1_AETI_D"), 'L1_AETI_D', 'ET [mm/d]', 0.1]
}
# initialize figure
zeros_1 = np.zeros(365)
dates = date_range(start='01-01-2021', periods=365)

dt_x = bq.DateScale()
sc_y = bq.LinearScale()

time_series = bq.Lines(x=dates, y=zeros_1, scales={'x': dt_x, 'y': sc_y})
time_series2 = bq.Lines(x=dates, y=zeros_1*np.nan, scales={'x': dt_x, 'y': sc_y})
ax_x = bq.Axis(scale=dt_x)
ax_y = bq.Axis(scale=sc_y, orientation='vertical')

fig = bq.Figure(marks=[time_series2, time_series], axes=[ax_x, ax_y],
                fig_margin=dict(top=50, bottom=80, left=80, right=10))
fig.layout.width='auto'
fig.layout.height='400px'

# zeros_1 = np.zeros(365)
# dates = range(1,365)

# dt_x = bq.LinearScale()
# sc_y = bq.LinearScale()

# time_series2 = bq.Lines(x=dates, y=zeros_1, scales={'x': dt_x, 'y': sc_y})
# ax_x = bq.Axis(scale=dt_x)
# ax_y = bq.Axis(scale=sc_y, orientation='vertical')

# fig1 = bq.Figure(marks=[time_series2], axes=[ax_x, ax_y],
#                 fig_margin=dict(top=50, bottom=80, left=80, right=10))
# fig1.layout.width='auto'
# fig1.layout.height='400px'
d = widgets.Text(
    description='Country name (FAO)')
a = widgets.Dropdown(
    value='NDVI', 
    options=['NDVI', 'Surface Soil Moisture', 'Evapotranspiration'], 
    description='dataset')
b = widgets.DatePicker(
    description='Start date',
    value=datetime.datetime(2021,1,1)
    )
c = widgets.DatePicker(
    description='End date',
    value=datetime.datetime(2021,3,1)
    )
button = widgets.Button(description="Go")
e = widgets.Dropdown(
    value='mean', 
    options=['mean', 'anomaly'], 
    description='analysis')

text1 = 'Ready'
text2 = 'Loading please wait...'
text = 'Please select country'
htmlWidget = widgets.HTML(value = f"<b><center><font color='green'>{text1}</center> </b>")
def update_graphs(btn):
    htmlWidget.value = f"<b><center><font color='red'>{text2}</center></b>"
    dataset = a.value
    st_time = b.value
    end_time = c.value
    countries = d.value
    analysis = e.value
    
    y1 = st_time.year
    
    bandname = datasets[dataset][1]
    scale_factor = datasets[dataset][3]
    
    start = datetime.datetime.strftime(st_time,'%Y-%m-%d')
    end = datetime.datetime.strftime(end_time,'%Y-%m-%d')
    country_list = countries.split(',')
    if isinstance(country_list, list)==False:
        country_list = [country_list]
    Countries = ee.FeatureCollection("FAO/GAUL_SIMPLIFIED_500m/2015/level0")
    region =  Countries.filter(ee.Filter.inList('ADM0_NAME',country_list));
    if region.getInfo()['features'] == []:
        htmlWidget.value = f"<b><center><font color='red'>{text}</center></b>"
    regeo = region.geometry()
      
    filteredCollection = datasets[dataset][0].filter(ee.Filter.date(start,end)
                                                ).select(bandname)
    image = filteredCollection.mean().clip(regeo).multiply(scale_factor)
    
    if analysis == 'mean':
        vis_params =  get_vis_params(dataset)
    elif analysis == 'anomaly':
        doy1 = st_time.timetuple().tm_yday
        doy2 = end_time.timetuple().tm_yday
        totMean = datasets[dataset][0].filter(ee.Filter.dayOfYear(doy1, doy2)
                                          ).select(bandname
                                                  ).mean().clip(regeo).multiply(scale_factor)
        diff1 = image.select(bandname).subtract(totMean.select(bandname)).rename('diff1');
        percDiff = diff1.select('diff1').divide(totMean.select(bandname)).multiply(100).rename('diff_perct');
        image = percDiff
        vis_params = get_vis_params('anomaly')
        
    style = get_vis_params('outline')
    
    Map.clear_layers()
    Map.setOptions("ROADMAP");
    Map.centerObject(regeo)
    Map.addLayer(image, vis_params=vis_params)

    Map.add_colorbar(vis_params=vis_params,
                     cmap='BuPu', discrete=False, label=None,
                     orientation='horizontal', position='bottomright',
                     transparent_bg=False, layer_name='legend')

    def meanCol(img):
        mean = img.reduceRegion(reducer=ee.Reducer.mean(),
                              geometry=region.geometry(),
                              scale=1000).get(datasets[dataset][1])
        return img.set('date', img.date().format()).set('mean', mean)


    VegImeans = filteredCollection.map(meanCol)
    nested_list = VegImeans.reduceColumns(ee.Reducer.toList(2), ['date','mean']).values().get(0)
    df = pd.DataFrame(nested_list.getInfo(), columns=['date','mean'])
    df['date'] = pd.to_datetime(df['date'])
    df = df.set_index('date')
    time_series.x = df.index
    time_series.y = df['mean']*scale_factor
    ax_y.label=datasets[dataset][2]
    fig.title = '{} : {}'.format(', '.join(country_list), dataset)
    
    if analysis == 'anomaly':
        Allmeans =datasets[dataset][0].select(bandname).map(meanCol)
        nested_list_all = Allmeans.reduceColumns(ee.Reducer.toList(2), ['date','mean']).values().get(0)
        df = pd.DataFrame(nested_list_all.getInfo(), columns=['date','mean'])
        df['date'] = pd.to_datetime(df['date'])
        df = df.set_index('date')
        doy=[dat.timetuple().tm_yday for dat in df.index]
        year=[dat.year for dat in df.index]
        df.index = pd.MultiIndex.from_arrays([year, doy])
        df2 = df.unstack(0)
        df3 = df2['mean']
        df3_fill = df3.apply(lambda series: series.loc[:series.last_valid_index()].ffill())
        all_lines = []
        for y in df3_fill.columns:
            all_lines.append(df3_fill[y]*scale_factor)
        artificial_x = [datetime.datetime(y1, 1, 1) + datetime.timedelta(days - 1) for days in df3_fill.index]
        time_series2.x = np.array(artificial_x).astype('datetime64')
        time_series2.y = all_lines
        time_series2.colors=['#D3D3D3']
        ax_x.tick_format='%b'
    else:
        time_series2.x = time_series.x
        time_series2.y = time_series.y * np.nan
        ax_x.tick_format=''
    htmlWidget.value = f"<b><center><font color='green'>{text1}</center></b>"    
    return



button.on_click(update_graphs)
Lab = Label(value='Enter country names seperated by commas (no space) and select dataset.')
Lab1 = Label(value='Names must be exact match for FAO GAUL ADM0 (e.g. Ethiopia,Kenya).')

Lab2 = Label(value = 'Dataset sources: NDVI (MODIS), Surface Soil Moisture (SMAP), ET (WaPOR)')
Lab3 = Label('*for anomaly map, start and end date must be within same year')
Lab4 = Label('for anomaly graph, grey lines are from all other years of data available, matched to same day of year')

AppLayout(center=Map, 
          header=VBox([VBox([Lab, Lab1]),HBox(
              [VBox([d, a, e]),VBox([b, c]),VBox([button,htmlWidget])]), Lab3, Lab4]),
#           left_sidebar=Lab3,
          right_sidebar=VBox([fig]),
          footer=Lab2,
          pane_widths=['80px', 1, 2],
          pane_heights=['250px', 1, 1],
          height='700px',
          width='900px',
          grid_gap="10px")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1645101663585952, 'fraction_numerical': 0.05045123409807546, 'mean_word_length': 3.03244191144235, 'pattern_counts': {'":': 3, '<': 25, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '414392', 'license': 'MIT', 'n_tokens_mistral': 3543, 'n_tokens_neox': 3243, 'n_words': 584, 'path': 'notebooks/wps_3.ipynb', 'repo_name': 'CMicha/geemap-heroku', 'size': '9197'}