In code below we try to assess if monthly remotely sensed snow indicators have predictive power on Agriculture Stress Index (ASI) over the March-April-May (MAM) planting season in Afghanistan.
Data Sources
Normalized Difference Snow Index (NDSI): MODIS Terra Satellite
Snow Water Equivalent (SWE): Famine Early Warning Systems Network (FEWS NET) Land Data Assimilation System (FLDAS)
Agricultural Stress Index (ASI): FAO
We run the analysis for each province in Afghanistan.
Results
These results concur with the previous analysis of Faryab province that indicated a low correlation/predictive between driest SWE years and least healthy ASI years within
Feb-Mar snow indicators (SWE & NDSI) show a more intuitive relationship with ASI than Dec-Jan snow indicators. This could indicate that later season hydro-dynamics play a more important role in agricultural MAM drought than the actual the total quantity of snow detected in the heart of the winter months (D-J).
SWE & NDSI are moderately correlated with each other as expected
Discussion & Next Steps
Simple N-D-J aggregated snow indicators (NDSI & SWE) does not appear to be useful in trigger design. However,
To confirm or support the importance of late-season hydro-dynamics we may consider further integrating snow-melt dynamics into the analysis as started output here
df_swe_long |>left_join( df_asi_yr ) |>filter( mo %in%c("Nov","Dec","Jan", "Feb","Mar")# adm1_name == "Kabul" ) |>ggplot(aes(x= value, y= asi_end/100) )+geom_point(size = pt_size)+scale_y_continuous(labels = scales$label_percent() )+facet_grid(rows =vars(adm1_name),cols =vars(mo),scale ="free" )+theme(panel.border =element_rect(colour ="black", fill=NA),strip.text =element_text(size= strip_text_size),axis.text.x =element_text(angle =90),axis.text.y =element_text(size =7) )+labs( x="SWE Value - FLDAS",y="Cumulative ASI (% stressed)",title ="Monthly Snow Water Equivalent (SWE) vs Cumulative MAM ASI" )
Code
# df_swe_monthly_wide <- df_swe_long |># pivot_wider(id_cols = c("adm1_name","adm1_code","yr"),# names_from = mo, # values_from = value # same here ... using raw value or anomaly # )# # df_swe_asi_wide <- left_join(df_asi_yr,df_swe_monthly_wide, by = c("adm1_code","yr") )
Code
ndsi_params <-list(value ="value",no_snow_frac ="no_snow_frac",ndsi_anom ="ndsi_anom" , ndsi_z="ndsi_z", snow_frac_change="snow_frac_change" )ldf_ndsi_asi_wide <-map( ndsi_params,\(tp){ df_ndsi_wide <- df_ndsi_long |>pivot_wider(id_cols =c("adm1_name","adm1_code","yr"),names_from = mo, values_from =all_of(tp) # this is the critical value -- could use z-score, anomaly, raw -value etc or bareground )left_join(df_asi_yr,df_ndsi_wide, by =c("adm1_code","yr") ) |>filter(if_all(.cols =any_of(month(c(1:12), label = T, abbr=T)),~!is.na(.x)) ) } )
Code
swe_params <-list(value ="value",anom ="swe_anom" , z="swe_z", change ="swe_change" )ldf_swe_asi_wide <-map( swe_params,\(tp){ df_swe_wide <- df_swe_long |>pivot_wider(id_cols =c("adm1_name","adm1_code","yr"),names_from = mo, values_from =all_of(tp) # this is the critical value -- could use z-score, anomaly, raw -value etc or bareground )left_join(df_asi_yr,df_swe_wide, by =c("adm1_code","yr") ) |>filter(if_all(.cols =any_of(month(c(1:12), label = T, abbr=T)),~!is.na(.x)) ) } )
Snow vs ASI
Code
asi_stats =list(`EOS`="asi_end",max ="asi_max",`anomaly`="asi_max_anom",`z-score`="asi_max_z",mean ="asi_mean" )lp_ndsi_heat <-imap(ldf_ndsi_asi_wide,\(dft,ndsi_stat){map( asi_stats, \(stat_temp){ dft_corrs_wide <- dft |>group_by( adm1_code, adm1_name ) |>summarise(across(.cols =c("Jun","Jul","Aug","Sep","Oct","Nov","Dec","Jan","Feb","Mar","Apr","May"),.fns =~cor(.,!!sym(stat_temp)) ),.groups="drop" ) dft_long <- dft_corrs_wide |>pivot_longer(cols = Jun: May) |>mutate(name =fct_relevel(name, "Oct","Nov","Dec","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep") ) p_title <-glue("Correlation between monthly NDSI ({ndsi_stat}) and ASI ({stat_temp}) over M-A-M") dft_long |>filter(!name %in%month(6:9, abbr= T, label=T)) |>ggplot(aes(x= name,y= adm1_name,fill = value) )+geom_tile()+scale_fill_gradient2(low =hdx_hex("tomato-hdx"), # Color for negative valuesmid ="white", # Color for zerohigh =hdx_hex("mint-hdx"), # Color for positive valuesmidpoint =0# Set midpoint at zero )+geom_tile(data= dft_long |>filter(adm1_name =="Faryab", name %in%c("Oct","Nov","Dec","Jan","Feb","Mar","Apr","May")),fill =NA, color ="black", lwd =1.5 )+geom_text(aes(label =round(value,2)) )+labs(title = p_title,subtitle ="Afghanistan by Province",y="Province" )+theme(axis.title.x =element_blank(),legend.title=element_blank(),plot.title =element_text(size =12),plot.subtitle =element_text(size =12),legend.text =element_text(angle=90) ) } ) } )# lp_ndsi_heat$ndsi_anom$EOS# lp_ndsi_heat$ndsi_z$EOS# lp_ndsi_heat$ndsi_z$max
Below we have correlated monthly NDSI values against End of Season (EOS). As NDSI is a measure of % snow we’d expect an negatibve relationship in key winter months where high % snow fraction should be associated with low EOS ASI and visa versa.
However the heat map below shows generally a positive relationship between % snow in Dec & Jan & EOS ASI. This is the opposite of what we’d intuitively expect, but is also confirmed by SW.
Code
lp_ndsi_heat$value$EOS
Code
lp_swe_heat <-imap(ldf_swe_asi_wide,\(dft,swe_stat){map( asi_stats, \(stat_temp){ dft_corrs_wide <- dft |>group_by( adm1_code, adm1_name ) |>summarise(across(.cols =c("Nov","Dec","Jan","Feb","Mar"),.fns =~cor(.,!!sym(stat_temp)) ),.groups="drop" ) dft_long <- dft_corrs_wide |>pivot_longer(cols = Nov:Mar) |>mutate(name =fct_relevel(name, "Nov","Dec","Jan","Feb","Mar") ) p_title <-glue("Correlation between monthly SWE ({swe_stat}) and ASI ({stat_temp}) over M-A-M") dft_long |>ggplot(aes(x= name,y= adm1_name,fill = value) )+geom_tile()+scale_fill_gradient2(low =hdx_hex("tomato-hdx"), # Color for negative valuesmid ="white", # Color for zerohigh =hdx_hex("mint-hdx"), # Color for positive valuesmidpoint =0# Set midpoint at zero )+geom_tile(data= dft_long |>filter(adm1_name =="Faryab", name %in%c("Nov","Dec","Jan","Feb","Mar")),fill =NA, color ="black", lwd =1.5 )+geom_text(aes(label =round(value,2)) )+labs(title = p_title,subtitle ="Afghanistan by Province",y="Province" )+theme(axis.title.x =element_blank(),legend.title=element_blank(),plot.title =element_text(size =12),plot.subtitle =element_text(size =12),legend.text =element_text(angle=90) ) } ) } )
where we see the same relationship with high water/snow values in Dec & Jan correlated with higher Ag stress (EOS).
Potential explanation
Of note is the fact that by Feb-Mar the relationship shifts back to the direction we would expect: More snow-less stress. This could indicate that it’s not simply the total snowfall impacting water availability and crop health, but perhaps there is a later season dynamic (snow melt?) that impacts water availability. Perhaps if there is some (x?) amount of snow available, it keeps a consistent supply of water to crops, but if it disappears too early, than the agriculture suffers