chrisvwn / Rnightlights

R package to extract data from satellite nightlights.
GNU General Public License v3.0
47 stars 14 forks source link

Predictable & Large Spikes in Monthly Nightlights Data in Africa #41

Closed cdavison7 closed 4 years ago

cdavison7 commented 4 years ago

Hello Chris, Thanks for your work in creating this package! I am looking at several countries in Africa: Sierra Leone, Guinea, and Liberia, and I am seeing large spikes in radiance that occur systematically around February/March and then there is usually a second spike sometime around August-October. I am trying to use the data as a proxy for GDP in a geographical area, and I am concerned there may be too much measurement error for the data to be useful. Do you have any thoughts or insight into this?

I have attached graphs where 301 denotes January 2013 and 401 denotes January 2014, etc... I also realize that to correctly proxy for GDP I need to divide by area of land, but that won't change the patterns in the data. Also, here is the code I used:

library(Rnightlights) library(lubridate) library(reshape2) library(tidyr) library(mFilter) library(ggplot2) library(dplyr)

highestAdmLevelStats.gin <- getCtryNlData(ctryCode = "GIN", admLevel = "highest", nlType = "VIIRS.M", nlPeriods =nlRange("201301", "201612", "VIIRS.M"), nlStats = list("sum",na.rm=TRUE), ignoreMissing=FALSE)

highestAdmLevelStats.lbr <- getCtryNlData(ctryCode = "LBR", admLevel = "highest", nlType = "VIIRS.M", nlPeriods =nlRange("201301", "201612", "VIIRS.M"), nlStats = list("sum",na.rm=TRUE), ignoreMissing=FALSE)

highestAdmLevelStats.sle <- getCtryNlData(ctryCode = "SLE", admLevel = "highest", nlType = "VIIRS.M", nlPeriods =nlRange("201301", "201612", "VIIRS.M"), nlStats = list("sum",na.rm=TRUE), ignoreMissing=FALSE)

SLE_nightlights_test <- gather(highestAdmLevelStats.sle, 4:ncol(highestAdmLevelStats.sle), key = year, value = light)

SLE_nightlights_test$year <- gsub("NL_VIIRS.MVCMCFG-MTSALL-MEAN-RGFT", "", SLE_nightlights_test$year)

SLE_nightlights_test$year <- gsub("_SUM", "", SLE_nightlights_test$year) SLE_nightlights_test$year <- gsub("201", "", SLE_nightlights_test$year)

ggplot(data = SLE_nightlights_test, aes(x = year, y = light, group = province)) + geom_line(aes(color = province))

GIN_nightlights_test <- gather(highestAdmLevelStats.gin, 4:ncol(highestAdmLevelStats.gin), key = year, value = light) GIN_nightlights_test$year <- gsub("NL_VIIRS.MVCMCFG-MTSALL-MEAN-RGFT", "", GIN_nightlights_test$year)

GIN_nightlights_test$year <- gsub("_SUM", "", GIN_nightlights_test$year) GIN_nightlights_test$year <- gsub("201", "", GIN_nightlights_test$year)

ggplot(data = GIN_nightlights_test, aes(x = year, y = light, group = region)) + geom_line(aes(color = region))

LBR_nightlights_test <- gather(highestAdmLevelStats.lbr, 4:ncol(highestAdmLevelStats.lbr), key = year, value = light) LBR_nightlights_test$year <- gsub("NL_VIIRS.MVCMCFG-MTSALL-MEAN-RGFT", "", LBR_nightlights_test$year)

LBR_nightlights_test$year <- gsub("_SUM", "", LBR_nightlights_test$year) LBR_nightlights_test$year <- gsub("201", "", LBR_nightlights_test$year)

ggplot(data = LBR_nightlights_test, aes(x = year, y = light, group = county)) + geom_line(aes(color = county))

Thanks so much for your help in this!!!

GIN_region_monthly LBR_province_monthly SLE_province_monthly

chrisvwn commented 4 years ago

Hi @cdavison7 first a disclaimer. I am not an expert in nightlights or satellite imagery so my views are not authoritative. Please see contacts on the NOAA page lower down in this response who can give an authoritative response. With that out of the way, let me put forward my understanding of this phenomenon.

I believe the 2 spikes are due, in large part, to cloud coverage. This will be clearer if viewed on an annual scale to see the annual seasons. During the seasons where there is heavy cloud cover, less light generated at the earth's surface is received at the satellite instrument and, thus, the sum of radiances is affected. The monthly VIIRS radiances are taken as averages of the daily readings and from the documentation (https://www.ngdc.noaa.gov/eog/viirs/download_dnb_composites.html) it is possible to have zero cloud-free readings for a pixel in the month resulting in a zero reading or a lower reading than on a cloud-free night resulting in a lower average for the month.

In the monthly composites, there are many areas of the globe where it is impossible to get good quality data coverage for that month. This can be due to cloud-cover, especially in the tropical regions, or due to solar illumination, as happens toward the poles in their respective summer months. Therefore, it is imperative that users of these data utilize the cloud-free observations file and not assume a value of zero in the average radiance image means that no lights were observed.

Ideally, one should check if there are zero pixels in the radiances and compare this with the cloud-free coverages to determine if the zeros/lower radiances are due to cloud cover as mentioned in the link above. The next version of Rnightlights (or the github version though this is still unstable) will have the ability to download and process cloud-free coverages and the other nightlights imagery available.

However, for this purpose I think it is simpler to use another source of cloud cover for visual inspection. Of course a rigorous determination should use/incorporate the method above.

Here, using the example of Guinea, I have tried to superimpose a graph of cloud cover from https://www.worldweatheronline.com/conakry-weather-averages/conakry/gn.aspx onto your sum of radiances graph for the same period. Please see below:

Screenshot from 2019-10-10 21-47-46

This makes sense to me as there seems to be an inverse relationship between cloud-cover and recorded radiances.

Hope this helps.

cdavison7 commented 4 years ago

@chrisvwn Thanks so much for your quick and helpful response. I will keep an eye out for your next version of Rnightlights and maybe the data will work better then for my purposes. Great work on the package.

chrisvwn commented 4 years ago

@cdavison7 You're welcome. If I may ask, does your project require that you do a thorough study of the nightlights including a thorough explanation of the different aspects of the data? And might you have a list of requirements that you are looking for? This would help me understand some of the user needs and help in the future development of the package.