SkillAgentSearch skills...

Blackmarbler

Georeferenced Rasters and Statistics of Nighttime Lights from NASA Black Marble

Install / Use

/learn @worldbank/Blackmarbler
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

BlackMarbleR <img src="man/figures/logo.png" align="right" width="200" />

<!-- badges: start -->

CRAN_Status_Badge downloads GitHub Repo stars activity License: MIT R-CMD-check

<!-- badges: end -->

BlackMarbleR is a R package that provides a simple way to use nighttime lights data from NASA's Black Marble. Black Marble is a NASA Earth Science Data Systems (ESDS) project that provides a product suite of daily, monthly and yearly global nighttime lights. This package automates the process of downloading all relevant tiles from the NASA LAADS DAAC to cover a region of interest, converting and mosaicing the raw files (in HDF5 format) to georeferenced rasters.

Installation <a name="installation"></a>

The package can be installed via CRAN.

install.packages("blackmarbler")

To install the development version from Github:

# install.packages("devtools")
devtools::install_github("worldbank/blackmarbler")

Bearer Token <a name="token">

Follow the below steps to obtain a bearer token:

  1. Create a NASA Earth Data account account. On the top right of the webpage, click "Login" then "Earthdata Login". Then click "register" (blue button).

  2. Enter the information in the registration page. You must include the following information; this information is not required to create an account, but the bearer token will not work without this information:

    • Study Area
    • User Type
    • Organization
  3. Click "Register for EarthData Login" (green button at bottom). Check your email, and click the link in the email to activate the account.

  4. Go to the Earth Data Login page and login.

  5. On the panel near the top, click "EULAs" then "Accept New EULAs". Accept:

    • MERIS EULA
    • Sentinel EULA
  6. On the "Profile Home" page, you should see something like below. Information should be filled in for each category, and "Agreed To Meris EULA" and "Agreed To Sentinel-3 EULA" should be True.

<p align="center"> <img src="man/figures/nasa_profile_info.png" alt="NASA Profile Home Information" width="500"/> </p>
  1. Go to the NASA LAADS Archive and login (login button on top right). You will see a page to authorize use of Sentinel3 and Meris. Click the green "Authorize" button.

  2. To obtain the bearer token, go to the Earth Data Login page and login. On the top panel, click "Generate token". On this page, click "Show Token" to see the bearer token.

<p align="center"> <img src="man/figures/nasa_login_3.png" alt="NASA LAADS Bearer Token" width="500"/> </p>
  1. If the bearer token ever stops working, you make need to go to the "Generate token" page (see step 8), delete any existing tokens, and generate a new token.

Programmatically retrieve token <a name="token-automatic">

After following the above steps, the bearer token can also be programmatically retrieved using the get_nasa_token() function and your usename and password.

bearer <- get_nasa_token(username = "USERNAME-HERE", 
                         password = "PASSWORD-HERE")

Usage <a name="usage">

Setup <a name="setup">

Before downloading and extracting Black Marble data, we first load packages, define the NASA bearer token, and define a region of interest.

#### Setup
# Load packages
library(blackmarbler)
library(geodata)
library(sf)
library(terra)
library(ggplot2)
library(tidyterra)
library(lubridate)

#### Define NASA bearer token
bearer <- "BEARER-TOKEN-HERE"

### ROI
# Define region of interest (roi). The roi must be (1) an sf polygon and (2)
# in the WGS84 (epsg:4326) coordinate reference system. Here, we use the
# getData function to load a polygon of Ghana
roi_sf <- gadm(country = "GHA", level=1, path = tempdir()) 

Make raster of nighttime lights <a name="raster">

The below example shows making daily, monthly, and annual rasters of nighttime lights for Ghana.

### Daily data: raster for February 5, 2021
r_20210205 <- bm_raster(roi_sf = roi_sf,
                        product_id = "VNP46A2",
                        date = "2021-02-05",
                        bearer = bearer)

### Monthly data: raster for October 2021
r_202110 <- bm_raster(roi_sf = roi_sf,
                      product_id = "VNP46A3",
                      date = "2021-10-01", # The day is ignored
                      bearer = bearer)

### Annual data: raster for 2021
r_2021 <- bm_raster(roi_sf = roi_sf,
                    product_id = "VNP46A4",
                    date = 2021,
                    bearer = bearer)

Make raster of nighttime lights across multiple time periods <a name="stack">

To extract data for multiple time periods, add multiple time periods to date. The function will return a SpatRaster object with multiple bands, where each band corresponds to a different date. The below code provides examples getting data across multiple days, months, and years.

#### Daily data in March 2021
r_daily <- bm_raster(roi_sf = roi_sf,
                     product_id = "VNP46A2",
                     date = seq.Date(from = ymd("2021-03-01"), to = ymd("2021-03-31"), by = "day"),
                     bearer = bearer)

#### Monthly aggregated data in 2021 and 2022
r_monthly <- bm_raster(roi_sf = roi_sf,
                       product_id = "VNP46A3",
                       date = seq.Date(from = ymd("2021-01-01"), to = ymd("2022-12-01"), by = "month"),
                       bearer = bearer)

#### Yearly aggregated data in 2012 and 2021
r_annual <- bm_raster(roi_sf = roi_sf,
                      product_id = "VNP46A4",
                      date = 2012:2021,
                      bearer = bearer)

Map of nighttime lights <a name="map">

Using one of the rasters, we can make a map of nighttime lights

#### Make raster
r <- bm_raster(roi_sf = roi_sf,
               product_id = "VNP46A3",
               date = "2021-10-01",
               bearer = bearer)

#### Prep data
r <- r |> terra::mask(roi_sf)

## Distribution is skewed, so log
r[] <- log(r[] + 1)

##### Map
ggplot() +
  geom_spatraster(data = r) +
  scale_fill_gradient2(low = "black",
                       mid = "yellow",
                       high = "red",
                       midpoint = 4.5,
                       na.value = "transparent") +
  labs(title = "Nighttime Lights: October 2021") +
  coord_sf() +
  theme_void() +
  theme(plot.title = element_text(face = "bold", hjust = 0.5),
  legend.position = "none")
<p align="center"> <img src="man/figures/ntl_gha.png" alt="Nighttime Lights Map" width="800"/> </p>

Trends over time <a name="trends">

We can use the bm_extract function to observe changes in nighttime lights over time. The bm_extract function leverages the exactextractr package to aggregate nighttime lights data to polygons. Below we show trends in annual nighttime lights data across Ghana's first administrative divisions.

#### Extract annual data
ntl_df <- bm_extract(roi_sf = roi_sf,
                     product_id = "VNP46A4",
                     date = 2012:2022,
                     bearer = bearer)

#### Trends over time
ntl_df |>
  ggplot() +
  geom_col(aes(x = date,
  y = ntl_mean),
  fill = "darkorange") +
  facet_wrap(~NAME_1) +
  labs(x = NULL,
       y = "NTL Luminosity",
       title = "Ghana Admin Level 1: Annual Average Nighttime Lights") +
  scale_x_continuous(labels = seq(2012, 2022, 4),
                     breaks = seq(2012, 2022, 4)) +
  theme_minimal() +
  theme(strip.text = element_text(face = "bold"))
<p align="center"> <img src="man/figures/ntl_trends_gha.png" alt="Nighttime Lights Trends" width="800"/> </p>

Workflow to update data <a name="update-data">

Some users may want to monitor near-real-time changes in nighttime lights. For example, daily Black Marble nighttime lights data is updated regularly, where data is available roughly on a week delay; same use cases may require examining trends in daily nighttime lights data as new data becomes available. Below shows example code that could be regularly run to produce an updated daily dataset of nighttime lights.

The below code produces a dataframe of nighttime lights for each date, where average nighttime lights for Ghana's 1st administrative division is produced. The code will check whether data has already been downloa

View on GitHub
GitHub Stars27
CategoryDevelopment
Updated7d ago
Forks7

Languages

HTML

Security Score

80/100

Audited on Mar 23, 2026

No findings