Contents

Using ggmap and gganimation to visualize oil spill in Brazil coastline

In 2019, a crude oil spill struck more than 2,000 kilometers off the coast of Brazil’s Northeast and Southeast, affecting more than 400 beaches in more than 200 different municipalities. The first reports of the spill occurred at the end of August with sightings still spreading later this year. This post explores the sighting records available on the IBAMA website to view the impact of the leak using ggmap and gganimation.

In 2019, a crude oil spill struck more than 2,000 kilometers off the coast of Brazil’s Northeast and Southeast, affecting more than 400 beaches in more than 200 different municipalities. The first reports of the spill occurred at the end of August with sightings still spreading later this year. More than a thousand tons of oil have already been collected from the beaches, which is the worst oil leak in Brazil’s history and the largest environmental disaster on the Brazilian coastline.

In this post we will explore the oil sighting data, published on the IBAMA website (the Brazilian Institute of the Environment and Renewable Natural Resources), a state agency from the Ministry of the Environment responsible for implementing federal environmental preservation policies. We’ll try to view the oil spill extension and evolution using the ggmap and gganimation R packages.

Site and Dataset

IBAMA has made the oil spill data and information available on a subsection of its site, keeping a daily record of status and spotting sightings.

Part of the records provided are available in excel format, and according with it’s description, the files contain: the name of each spotted location, the county, the date of first sighting, the state, latitude, longitude, date where the location was revisited and oil spill status at the moment.

Data Scrapping

Although the site offers PDF and XLXS, and it is possible to explore the sightings table within PDF files through the tabulizer package, in this post we’ll only explore the contents of the excel files. The first step to this is to scrap the page that provides the files to download, to extract its links, we’ll use rvest package to do this job.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
library(tidyverse)  # of course
library(rvest)      # to handle html scrapping
library(lubridate)  # handle datetime formats
library(glue)       # easily concat texts
library(knitr)      # markdown output tables
library(kableExtra) # formate markdown tables

# scrap and build url table
base_url <- "http://www.ibama.gov.br"

# page with update table
page <- read_html("http://www.ibama.gov.br/manchasdeoleo-localidades-atingidas")

# get the table
updates <- page %>% 
  html_table() %>% 
  .[[1]]

# get the href links
doc_links <- page %>%
  html_nodes(xpath = "//td/a") %>% 
  html_attr("href")

# put then togheter
doc_list <- updates %>% 
  set_names(c("date","description","items")) %>% 
  mutate( type = str_extract(items, "^[\\w]+") ) %>% 
  mutate( type = ifelse(type=="XLS","XLSX", type)) %>% # one file with "xls" extension
  mutate( link = paste0(base_url, doc_links) ) %>% 
  mutate( date=dmy(date) ) %>%
  as_tibble()

# save it, just in case we want to recover later
saveRDS(doc_list,"./data/oil_leakage_doc_list.rds")

# let's see the links list
doc_list %>% 
  head(10) %>% 
  kable() %>% 
  kableExtra::kable_styling(font_size = 10)
date description items type link
2019-12-14 Localidades Atingidas PDF - 32MB PDF http://www.ibama.gov.br/phocadownload/emergenciasambientais/2019/manchasdeoleo/2019-12-14_LOCALIDADES_AFETADAS.pdf
2019-12-14 Localidades Atingidas XLSX - 74KB XLSX http://www.ibama.gov.br/phocadownload/emergenciasambientais/2019/manchasdeoleo/2019-12-14_LOCALIDADES_AFETADAS.xlsx
2019-12-13 Localidades Atingidas PDF - 32MB PDF http://www.ibama.gov.br/phocadownload/emergenciasambientais/2019/manchasdeoleo/2019-12-13_LOCALIDADES-AFETADAS.pdf
2019-12-13 Localidades Atingidas XLSX - 73KB XLSX http://www.ibama.gov.br/phocadownload/emergenciasambientais/2019/manchasdeoleo/2019-12-13_LOCALIDADES-AFETADAS_planilha.xlsx
2019-12-12 Localidades Atingidas PDF - 31,3MB PDF http://www.ibama.gov.br/phocadownload/emergenciasambientais/2019/manchasdeoleo/2019-12-12_LOCALIDADES_AFETADAS.pdf
2019-12-12 Localidades Atingidas XLSX - 72.2KB XLSX http://www.ibama.gov.br/phocadownload/emergenciasambientais/2019/manchasdeoleo/2019-12-12_LOCALIDADES_AFETADAS.xlsx
2019-12-11 Localidades Atingidas PDF - 31.4MB PDF http://www.ibama.gov.br/phocadownload/emergenciasambientais/2019/manchasdeoleo/2019-12-11_LOCALIDADES_AFETADAS.pdf
2019-12-11 Localidades Atingidas XLSX - 78KB XLSX http://www.ibama.gov.br/phocadownload/emergenciasambientais/2019/manchasdeoleo/2019-12-11_LOCALIDADES_AFETADAS_planilha.xlsx
2019-12-10 Localidades Atingidas PDF - 31MB PDF http://www.ibama.gov.br/phocadownload/emergenciasambientais/2019/manchasdeoleo/2019-12-10_LOCALIDADES-AFETADAS.pdf
2019-12-10 Localidades Atingidas XLSX - 68KB XLSX http://www.ibama.gov.br/phocadownload/emergenciasambientais/2019/manchasdeoleo/2019-12-10_LOCALIDADES-AFETADAS.xlsx

Now that we have the links in hand, let’s download the XLSX files.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# check the pre existence of destination folders
XLSX_DEST_FOLDER <- "./data/oil_leakage_raw"
if(!file.exists("./data")) dir.create("./data")
if(!file.exists(XLSX_DEST_FOLDER)) dir.create(XLSX_DEST_FOLDER)

# download xlsx files
xlsx_filenames <- doc_list %>% 
  filter(type=="XLSX") %>% 
  select(date, link) %>% 
  arrange(date) %>% 
  split(1:nrow(.)) %>% 
  map_chr(function(.x){
    filename <- paste0(XLSX_DEST_FOLDER, "/",as.character(.x$date[1]), ".xlsx")
    download.file(url=.x$link[1], destfile = filename, mode = "wb")
    return(filename)
  })

# save an excel filename index
xlsx_index <- doc_list %>% 
  filter( type=="XLSX" ) %>% 
  arrange(date) %>% 
  mutate( filename = xlsx_filenames )

# save it
saveRDS(xlsx_index, "./data/excel_file_index.rds")

# let's see what we have
xlsx_index %>% 
  head(10) %>% 
  kable() %>% 
  kable_styling(font_size = 9)
date description items type link filename
2019-10-16 Localidades Atingidas XLSX - 15KB XLSX http://www.ibama.gov.br/phocadownload/emergenciasambientais/2019/manchasdeoleo/2019-10-16_LOCALIDADES_AFETADAS.xlsx ./data/oil_leakage_raw/2019-10-16.xlsx
2019-10-17 Localidades Atingidas XLSX - 15KB XLSX http://www.ibama.gov.br/phocadownload/emergenciasambientais/2019/manchasdeoleo/2019-10-17_LOCALIDADES_AFETADAS.xlsx ./data/oil_leakage_raw/2019-10-17.xlsx
2019-10-18 Localidades Atingidas XLSX - 15KB XLSX http://www.ibama.gov.br/phocadownload/emergenciasambientais/2019/manchasdeoleo/2019-10-18_LOCALIDADES_AFETADAS.xlsx ./data/oil_leakage_raw/2019-10-18.xlsx
2019-10-19 Localidades Atingidas XLSX - 44KB XLSX http://www.ibama.gov.br/phocadownload/notas/2019/2019-10-19_LOCALIDADES_AFETADAS_PLANILHA.xls ./data/oil_leakage_raw/2019-10-19.xlsx
2019-10-22 Localidades Atingidas XLSX - 17KB XLSX http://www.ibama.gov.br/phocadownload/emergenciasambientais/2019/manchasdeoleo/2019-10-22_LOCALIDADES_AFETADAS.xlsx ./data/oil_leakage_raw/2019-10-22.xlsx
2019-10-23 Localidades Atingidas XLSX -17KB XLSX http://www.ibama.gov.br/phocadownload/emergenciasambientais/2019/manchasdeoleo/2019-10-23_LOCALIDADES_AFETADAS.xlsx ./data/oil_leakage_raw/2019-10-23.xlsx
2019-10-24 Localidades Atingidas XLSX - 20KB XLSX http://www.ibama.gov.br/phocadownload/notas/2019/2019-10-24_LOCALIDADES_AFETADAS_GERAL.xlsx ./data/oil_leakage_raw/2019-10-24.xlsx
2019-10-25 Localidades Atingidas XLSX - 21KB XLSX http://www.ibama.gov.br/phocadownload/notas/2019/2019-10-25_LOCALIDADES_AFETADAS_GERAL.xlsx ./data/oil_leakage_raw/2019-10-25.xlsx
2019-10-26 Localidades Atingidas XLSX - 18KB XLSX http://www.ibama.gov.br/phocadownload/emergenciasambientais/2019/manchasdeoleo/2019-10-26_LOCALIDADES_AFETADAS.xlsx ./data/oil_leakage_raw/2019-10-26.xlsx
2019-10-27 Localidades Atingidas XLSX - 35KB XLSX http://www.ibama.gov.br/phocadownload/notas/2019/2019-10-27_LOCALIDADES_AFETADAS.xlsx ./data/oil_leakage_raw/2019-10-27.xlsx

Import Data

Let’s use the xlsx package to read excel files and import them into a data.frame. Let’s take a look at one of them.

1
library(xlsx) # import excel files (requires java/rjava)
1
## Warning: package 'xlsx' was built under R version 4.0.5
1
2
3
4
5
6
xlsx_file <- read.xlsx(file = "./data/2019-12-14.xlsx",sheetIndex = 1)

xlsx_file %>% 
  head(10) %>% 
  kable() %>% 
  kable_styling(font_size = 10)
geocodigo localidade loc_id municipio estado sigla_uf Data_Avist Data_Revis Status Latitude Longitude Hora cou
2925303 Praia de Taperapuã 2925303_45 Porto Seguro Bahia BA 2019-11-04 2019-12-14 Oleo Nao Observado 16° 25' 15.03" S 39° 3' 13.45" W 10:14:18 1
2925303 Praia de Mucugê 2925303_46 Porto Seguro Bahia BA 2019-10-31 2019-12-11 Oleo Nao Observado 16° 29' 43.41" S 39° 4' 7.187" W NA 1
2805307 Praia da Ponta dos Mangues 2805307_26 Pirambu Sergipe SE 2019-11-13 2019-11-16 Oleo Nao Observado 10° 43' 54.29" S 36° 50' 24.42" W NA 1
2925303 Praia de Itaquena 2925303_47 Porto Seguro Bahia BA 2019-11-02 2019-11-19 Oleo Nao Observado 16° 39' 7.314" S 39° 5' 40.20" W NA 1
2805307 Praia Pirambu 2805307_21 Pirambu Sergipe SE 2019-11-07 2019-12-07 Oleada - Vestigios / Esparsos 10° 40' 55.80" S 36° 46' 31.49" W NA 1
2805307 Praia Pirambu 2805307_22 Pirambu Sergipe SE 2019-11-09 2019-11-26 Oleada - Vestigios / Esparsos 10° 41' 14.27" S 36° 47' 2.093" W NA 1
2805307 Praia Pirambu 2805307_23 Pirambu Sergipe SE 2019-12-09 2019-12-09 Oleada - Vestigios / Esparsos 10° 41' 32.37" S 36° 47' 28.42" W NA 1
2504603 Praia do Amor 2504603_1 Conde Paraíba PB 2019-09-30 2019-11-14 Oleo Nao Observado 7° 16' 17.60" S 34° 48' 8.354" W NA 1
2504603 Praia de Jacumã 2504603_2 Conde Paraíba PB 2019-08-30 2019-12-12 Oleo Nao Observado 7° 16' 48.85" S 34° 47' 57.13" W NA 1
2504603 Praia de Gramame 2504603_3 Conde Paraíba PB 2019-08-30 2019-11-14 Oleo Nao Observado 7° 15' 11.17" S 34° 48' 21.93" W NA 1

We can see that the file contains: a geocode, the name of each location, a id for that spot, the county name, state name and federation unit acronym, the date of the first spill sighting, the revision date (last status position), the current information about the spill state of the locality, latitude and longitude, plus an “hour” and an unknown cou column.

Attention: note every excel files has the same format, the code bellow handles some differences between then.

To read the files and use its data, we have to clean then first: resolving encoding, transforming the status information in a factor class, and turn the degree notations for latitude and longitude into decimal notation.

Importation

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# import each xlsx_file
files <- xlsx_index %>%
  split(1:nrow(.)) %>% 
  map(function(.x){
    print(.x$filename)
    read.xlsx(file = .x$filename[1], sheetIndex = 1, colClasses="character", stringsAsFactors=F) %>% 
      as_tibble() %>% 
      mutate(file.date=.x$date[1])
  })

# save it as cache
saveRDS(files, "./data/oil_leakage_imported_raw_excel.rds")

Data Clean-up

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# auxiliary function to translate the degree coordinates to decimal coordinates
translateCoord <- function(.coords){
  
  # extract orientation (N,S,W,E)
  directions <- str_extract(.coords,"\\w$")
  
  # split the numbers and rebuilds as xxDyy'zz"
  numbers <- .coords %>% 
    str_extract_all("(\\d\\.*)+") %>% 
    purrr::map(~paste0(.x[1],"d",.x[2],"'",.x[3],"\""))
  
  # modify char2dms to a safity call
  safe_char2dms <- safely(sp::char2dms, otherwise = NA)
  
  # readd orientation(NSWE) and converts to decimal
  numbers %>% 
    purrr::map2(directions, ~paste0(.x, .y)) %>% 
    purrr::map(safe_char2dms) %>% 
    purrr::map(purrr::pluck("result")) %>% 
    purrr::map(as.numeric) %>% 
    unlist() %>% 
    return()
}

# clean ant transform status data in to ordenated factor
statusToFactor <- function(.status){
  tibble( from_status = tolower(.status) )  %>% 
    mutate(
      to_status = case_when(
        str_detect(from_status, "manchas")   ~ "stains",
        str_detect(from_status, "esparsos")  ~ "traces/sparse",
        str_detect(from_status, "observado") ~ "not observed",
        T ~ as.character(NA)
      )
    ) %>% 
    mutate( fct_status = factor(to_status, levels = c("not observed", "traces/sparse", "stains"), ordered = T) ) %>% 
    pull(fct_status) %>% 
    return()
}

# read the raw excel importation
files <- readRDS("./data/oil_leakage_imported_raw_excel.rds")

# put all the excels in one dataframe
# perform a data cleanup
stains_raw <- files %>% 
  # the file form day 2019-11-06 hasn't coordinates
  keep(function(.x){ .x$file.date[1] != "2019-11-06"} ) %>% 
  # for each "excel" data
  map_df(function(.x){
    
    # some excels have two "municipio" columns
    if("municipio_" %in% names(.x)) .x <- select(.x, -municipio)
    
    # clean and normalize colnames
    col.names <- .x %>%
      names() %>% 
      tolower() %>%
      str_replace_all("munic.+pi.*", "municipio") %>% # acento no municipio 
      str_replace_all("name", "localidade") %>% 
      str_replace_all("latitutde","latitude")
    
    # rename the cols and select what we'll use
    .x %>% 
      set_names(col.names) %>% 
      select(file.date, localidade, municipio, 
             estado, data_avist, data_revis,
             latitude, longitude, status) %>% 
      
      # handle portuguese accents
      mutate(
        localidade = iconv(localidade, from="UTF-8", to="LATIN1"),
        municipio  = iconv(municipio, from="UTF-8", to="LATIN1"),
        estado     = iconv(estado, from="UTF-8", to="LATIN1"),
        status     = iconv(status, from="UTF-8", to="LATIN1"),
        data_avist = ymd(as.character(data_avist)), 
        data_revis = ymd(as.character(data_revis))
      ) %>% 
      return()
  })

# we have to translate degree coordinates to decimal
stains_coord <- stains_raw %>%   
  mutate(
    lat.degree = translateCoord(latitude),
    lon.degree = translateCoord(longitude)
  ) %>% 
  # in some of the files, the coordinates are indeed in decimal 
  mutate(
    lat.degree = ifelse(is.na(lat.degree), as.numeric(latitude), lat.degree),
    lon.degree = ifelse(is.na(lon.degree), as.numeric(longitude), lon.degree)
  )

# in some files, the "UF" column has the name of the states 
# and others the code of states, we handle this making a name<->code table
estado_uf <- files %>% 
  tail(1) %>% 
  .[[1]] %>% 
  mutate(
    estado = iconv(estado, from="UTF-8", to="LATIN1")
  ) %>% 
  select(estado, sigla_uf) %>% 
  distinct() %>% 
  arrange(estado)

# join the state name<->code table
stains_clean <- stains_coord %>% 
  left_join(estado_uf, by = "estado") %>% 
  # handle when the info is correct/incorrect
  mutate(sigla_uf = ifelse(is.na(sigla_uf),estado,sigla_uf)) %>% 
  # there is files without state code
  filter(!is.na(sigla_uf)) %>% 
  select(-estado) %>% 
  # rebuild state name
  inner_join(estado_uf, by="sigla_uf") %>% 
  # reselect only interesting cols
  select(file.date, data_avist, data_revis, sigla_uf, estado, municipio, localidade, lat.degree, lon.degree, status)

# transform the "status" info in a factor column
stains <- stains_clean %>% 
  mutate( status = statusToFactor(status) ) %>% 
  filter(complete.cases(.)) %>% 
  # english col names
  set_names(c("file.date", "sighting_date","revision_date","uf","state","county",
              "local","lat.degree","lon.degree","status")) %>% 
  # last clean-up
  filter(
    lon.degree < 0, # anything greater than that is a error
    revision_date < ymd(20200101), # anything greater than that is a error
    sighting_date < ymd(20200101), # anything greater than that is a error
    complete.cases(.) # missing data is not relevant
  )

# save it, just in case
saveRDS(stains, "./data/oil_leakage.rds")

Now we have all the data from the excel files concatenated, cleaned, treated and stored in a data.frame, let’s look at the final data format.

1
2
3
4
5
6
7
stains <- readRDS("./data/oil_leakage.rds")

# checking the final format
stains %>% 
  head(10) %>% 
  kable() %>% 
  kable_styling(font_size = 8)
file.date sighting_date revision_date uf state county local lat.degree lon.degree status
2019-10-16 2019-09-10 2019-10-15 RN Rio Grande do Norte N¡sia Floresta Barra de Tabatinga - Tartarugas -6.057081 -35.09679 stains
2019-10-16 2019-09-07 2019-10-16 AL Alagoas Japaratinga Praia de Japaratinga -9.093531 -35.25822 stains
2019-10-16 2019-09-18 2019-10-14 AL Alagoas Passo de Camaragibe Praia do Carro Quebrado -9.341689 -35.44870 stains
2019-10-16 2019-09-22 2019-10-13 AL Alagoas Roteiro Praia do Gunga -9.903094 -35.93877 stains
2019-10-16 2019-09-02 2019-10-02 SE Sergipe Barra dos Coqueiros Atalaia Nova -10.952222 -37.02944 stains
2019-10-16 2019-10-04 2019-10-05 BA Bahia Janda¡ra Janda¡ra -11.528550 -37.40157 stains
2019-10-16 2019-10-04 2019-10-13 BA Bahia Conde S¡tio do Conde -11.852953 -37.56399 stains
2019-10-16 2019-10-07 2019-10-08 BA Bahia Esplanada Mamucabo -12.163006 -37.72419 stains
2019-10-16 2019-09-27 2019-10-07 AL Alagoas Coruripe Lagoa do Pau -10.129733 -36.11001 stains
2019-10-16 2019-10-01 2019-10-15 BA Bahia Mata de SÆo JoÆo Santo Ant"nio -12.459700 -37.93229 stains

Plotting as a Map

With the data in hand, we’ll try to visualize the communities affected by the oil spill placing the data in a map. There are several frameworks for plotting maps in R, in this post we will use the ggmap package, which we already have used previously in the past.

Before to use ggmap, we’ll need to get the Google Map API Key and register it, but the procedure is pretty straightforward, just following these instructions. In my code, I always store the keys and others sensible information in yalm files to avoid accidentaly publish then in the GitHub, I also commented about this strategy in a older post.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# ggmap
library(ggmap)
library(yaml) # used to not version the google's map key

# before use ggmap with google maps it's necessary
# read and register a Key for Google Map API
# config <- yaml::read_yaml("./config.yml")
# register_google(key=config$google_map_key)

# get the map area
bbox <- make_bbox(lon = stains$lon.degree, lat=stains$lat.degree, f = .1)
gmap <- get_map(location=bbox, source="google", maptype="terrain")

# plot the data of observations on revision date 2019-11-10
# of location with stains or sparse residuos
ggmap(gmap) +
  geom_point(data=filter(stains, status!="not observed", revision_date==ymd(20191110)),
             aes(x=lon.degree, y=lat.degree, color=status), size=2, alpha=.8) +
  scale_color_manual(values=c("#888888","black","green")) +
  theme_void() +
  ggplot2::coord_fixed() 

The animation

Now the last step is to animate the map in the time dimension, we’ll do this using the great gganimate package, adding a transition function in the ggplot2 + ggmap stack.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
library(gganimate)
bbox <- make_bbox(lon = stains$lon.degree, lat=stains$lat.degree, f = .1)
gmap <- get_map(location=bbox, source="google", maptype="terrain")

p <- ggmap(gmap) +
  geom_point(data=filter(stains, status!="not observed"),
             aes(x=lon.degree, y=lat.degree,
                 color=status, group=county),
             size=3, alpha=.8) +
  scale_color_manual(values=c("#888888","black")) +
  theme_void()

anim <- p  +
  theme( legend.position = "bottom" ) +
  transition_time(revision_date) +
  labs(title="Oil Sighting on Brazil Coast",
       subtitle = "Date:  {frame_time} - source: IBAMA") +
  shadow_wake(wake_length = .15)

anim

/2019-12-31-using-ggmap-and-gganimation-to-visualize-oil-spill-in-brazil-coastline/index.en_files/figure-html/animation-1.gif

Visualizing the spill evolution in one plot

The animated map view gives us an great idea of the size of the ecological impact of the oil spill off the coast of Brazil. But to analytical purpose the animation does not allow you to see the full evolution history at one same time, allowing us to gauge how the spill is progressing.

To do this trick, let’s plot the information as a heatmap, where each location will be on the Y axis, indexed by its latitude, and on the X axis we’ll use the date information.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# let's organize the "county/locality" by latitude
stains %>% 
  select(local, lat.degree, revision_date, status) %>% 
  group_by(local) %>% 
  # calculates a unique latitude for local
  mutate( avg.lat = mean(lat.degree) ) %>% 
  ungroup() %>% 
  # put the locals in latitude order
  mutate( local = fct_reorder(local, avg.lat) ) %>% 
  select( local, revision_date, status ) %>% 
  distinct() %>% 
  # plot as a tile chart (local x date)
  arrange( local, revision_date ) %>% 
  ggplot(aes(x=revision_date, y=local)) +
  geom_tile(aes(fill=status)) +
  scale_fill_manual(values = c("lightgreen", "#888888", "black")) +
  theme_minimal() +
  theme( axis.text.y = element_blank() ) +
  labs(title="Oil Sighting by Latitude and Date", x="date", y="local/latitude")

In this graph, we can visualize how the the oil spill are progressing to the south, following the maritime currents, over the months of October and November, reaching the most extreme point a few days, before December.

The intermittent nature of the chart shows that information registring is not done daily in all locations, and some communities has more status updates than others we should handle this caracteristic to correctly plot the information, but we’ll leave this to other post.