Simple and Fast Visualization of Biodiversity Occurrence Data using GBIF and R Shiny

[This article was first published on R Code – Geekcologist, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

As an ecologist, being able to easily visualize biodiversity occurrence data is an essential need as this kind of data visualization provides critical insights into species distribution patterns and ecological requirements, which is essential for understanding biodiversity dynamics in space and time. Moreover,  for pragmatic reasons, fast and simple biodiversity data visualization can help us to define sampling and monitoring strategies in the field, optimizing resource and time allocation. As someone who is a passionate enthusiast for wildlife and nature, being able to visualize species occurrence is also particularly important when I am planning a trip to a new place I have never been, or just “virtually exploring” a far and unknown corner of the planet. 

In this post, I will show a simple way to create a R Shiny app to visualize biodiversity occurrence based on data from the Global Biodiversity Information Facility, aka GBIF, which “is an international network and data infrastructure funded by the world’s governments and aimed at providing anyone, anywhere, open access to data about all types of life on Earth. Global Biodiversity Information Facility aggregates data from various scientific sources, and as of today, it contains over 2 billion records of species occurrence from all over the world.

This simple R Shiny app allows users to explore species distributions by selecting a taxonomic group and defining a geographic area of interest using latitude and longitude coordinates to define a polygon (only min and max latitude and longitude are used to define the polygon, thus complex boundaries can not be included here), which will be used to retrieve species occurrence data from GBIF within this quadrilateral. The data will be displayed on an interactive map using the R package leaflet.

In the source code, you can also change  the taxa of interest to be shown in the user interface and the months of the year in which the data was collected, which might be useful for seasonal species.

The user interface should look like this:

Here is the R code!

# Install packages
install.packages(c("shiny", "rgbif", "leaflet", dependencies=T))

# Load packages

# Define function to search for occurrences of  specified clades within a polygon (i.e, bounding box=bbox)
search_occurrences <- function(bbox, clade) {
  occ_search_result <- occ_search(
    geometry = paste("POLYGON((", bbox["min_longitude"], " ", bbox["min_latitude"], ",", 
                     bbox["min_longitude"], " ", bbox["max_latitude"], ",", 
                     bbox["max_longitude"], " ", bbox["max_latitude"], ",", 
                     bbox["max_longitude"], " ", bbox["min_latitude"], ",", 
                     bbox["min_longitude"], " ", bbox["min_latitude"], "))"),
    month = 1, 12,###define months of the year
    scientificName = clade,
    hasCoordinate = TRUE

# Define user interface
ui <- fluidPage(
  titlePanel("Species Occurrence"),
      selectInput("clade", "Choose a clade:",
                  choices = c("Aves", "Coleoptera", "Amphibia", "Plantae", "Mammalia", "Actinopterygii", "Insecta"),#you can change the default clades according to your taste in biodiversity
                  selected = "Aves"), #first clade to be shown in the drop down box
      numericInput("min_longitude", "Minimum Longitude:", value = -9),##by default you will have the approximate borders of portugal, but this can be changed in the user interface or directly here
      numericInput("max_longitude", "Maximum Longitude:", value = -6),
      numericInput("min_latitude", "Minimum Latitude:", value = 36),
      numericInput("max_latitude", "Maximum Latitude:", value = 42)

# Define server logic
server <- function(input, output) {
  # Render the leaflet map based on user's clade selection and polygon coordinates
  output$map <- renderLeaflet({
    clade <- input$clade
    bbox <- c(
      min_longitude = input$min_longitude,
      min_latitude = input$min_latitude,
      max_longitude = input$max_longitude,
      max_latitude = input$max_latitude
    occ_search_result <- search_occurrences(bbox, clade)
    leaflet() %>%
      addTiles() %>%
        data = occ_search_result$data,
        lng = ~decimalLongitude,
        lat = ~decimalLatitude,
        popup = ~species,
        radius = 5,
        color = "blue",
        fillOpacity = 0.7
      ) %>%
        lng = mean(bbox[c("min_longitude", "max_longitude")]),
        lat = mean(bbox[c("min_latitude", "max_latitude")]),
        zoom = 14

#et voilà! You can run the application
shinyApp(ui = ui, server = server)

To leave a comment for the author, please follow the link and comment on their blog: R Code – Geekcologist. offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)