Display Europe map in RShiny

465 views Asked by At

I'm creating a map and want to plot/display this map in RShiny. The map is created by:

library(ggplot2)
library(grid)
library(rworldmap)

## Get the world map: ##
worldMap <- getMap()

## Define vector with all European countries: ##
v.europe <- c("Norway", "Sweden", "Finland", "Denmark", "United Kingdom","Ireland", "Greece",
              "Belgium", "Netherlands", "France", "Spain", "Portugal", "Luxembourg", "Croatia",
              "Germany", "Switzerland", "Austria", "Slovenia", "Italy", "Bulgaria", "Romania",
              "Czech Rep.", "Slovakia", "Hungary", "Poland", "Bosnia Hercegovina", "Serbia",
              "Turkey", "Ukraine", "Moldova", "Belarus", "Estonia", "Latvia", "Lithuania",
              "Montenegro", "Albania", "Macedonia")

## Select only the index of countries of Europe: ##
indEU <- which(worldMap$NAME%in%v.europe)


## Extract longitude and latitude border's coordinates of countries: ##
df.europeCoords <- lapply(indEU, function(i){
  df <- data.frame(worldMap@polygons[[i]]@Polygons[[1]]@coords)
  df$region = as.character(worldMap$NAME[i])
  colnames(df) <- list("long", "lat", "region")
  return(df)
})
df.europeCoords <- do.call("rbind", df.europeCoords)
names(df.europeCoords) <- c("longitude", "latitude", "country")

## Deletes/Removes borders of PLOT: ##
ax <- list(
  title = "",
  zeroline = FALSE,
  showline = FALSE,
  showticklabels = FALSE,
  showgrid = FALSE
)

## Plot the map: ##
p <- ggplot(data = df.europeCoords, aes(x = longitude, y = latitude, group = country, 
                                        text = paste("<b>", country, '</b>\n')), 
            color = "grey50", size = 0.1) + 
     geom_polygon() +
     coord_map(xlim = c(-13, 35),  ylim = c(32, 71)) +
     theme_classic() +
     theme(axis.text.x = element_blank(), axis.text.y = element_blank(), axis.ticks.x = element_blank(),
           axis.ticks.y = element_blank(), axis.title = element_blank(), legend.position = "none",
           plot.margin = unit(0 * c(-1.5, -1.5, -1.5, -1.5), "lines"))

## Create plot_ly() object: ##
EuropePlot <- plotly::ggplotly(p, tooltip = "text") %>%
              layout(xaxis = ax, yaxis = ax)

The map is displayed in the Viewer of RStudio correctly, but if I want to display this in RShiny I get the following error message:

Warning: Error in UseMethod: not applicable method for 'plotly_build' applied to object of class "shiny.tag"

The call of the map plot on server side looks like this:

# PLOT-Output: #
    output$maPPInfoPLOT <- renderPlotly({
          plotly::ggplotly(EuropePlot, dynamicTicks = TRUE)
    })

REMARK:

The plot is created externally in a function and provided with return(EuropePlot). In server.R I use output$maPPInfoPLOT <- renderPlotly({...}), where the UI.R looks like this:

plotlyOutput (outputId = "maPPInfoPLOT", width = "900px", height = "600px")
1

There are 1 answers

0
ismirsehregal On BEST ANSWER

The following works for me:

library(shiny)
library(ggplot2)
library(grid)
library(rworldmap)
library(plotly)
library(mapproj)

getEuropePlot <- function(){

  ## Get the world map: ##
  worldMap <- getMap()
  
  ## Define vector with all European countries: ##
  v.europe <- c("Norway", "Sweden", "Finland", "Denmark", "United Kingdom","Ireland", "Greece",
                "Belgium", "Netherlands", "France", "Spain", "Portugal", "Luxembourg", "Croatia",
                "Germany", "Switzerland", "Austria", "Slovenia", "Italy", "Bulgaria", "Romania",
                "Czech Rep.", "Slovakia", "Hungary", "Poland", "Bosnia Hercegovina", "Serbia",
                "Turkey", "Ukraine", "Moldova", "Belarus", "Estonia", "Latvia", "Lithuania",
                "Montenegro", "Albania", "Macedonia")
  
  ## Select only the index of countries of Europe: ##
  indEU <- which(worldMap$NAME%in%v.europe)
  
  
  ## Extract longitude and latitude border's coordinates of countries: ##
  df.europeCoords <- lapply(indEU, function(i){
    df <- data.frame(worldMap@polygons[[i]]@Polygons[[1]]@coords)
    df$region = as.character(worldMap$NAME[i])
    colnames(df) <- list("long", "lat", "region")
    return(df)
  })
  df.europeCoords <- do.call("rbind", df.europeCoords)
  names(df.europeCoords) <- c("longitude", "latitude", "country")
  
  ## Deletes/Removes borders of PLOT: ##
  ax <- list(
    title = "",
    zeroline = FALSE,
    showline = FALSE,
    showticklabels = FALSE,
    showgrid = FALSE
  )
  
  ## Plot the map: ##
  p <- ggplot(data = df.europeCoords, aes(x = longitude, y = latitude, group = country, 
                                          text = paste("<b>", country, '</b>\n')), 
              color = "grey50", size = 0.1) + 
    geom_polygon() +
    coord_map(xlim = c(-13, 35),  ylim = c(32, 71)) +
    theme_classic() +
    theme(axis.text.x = element_blank(), axis.text.y = element_blank(), axis.ticks.x = element_blank(),
          axis.ticks.y = element_blank(), axis.title = element_blank(), legend.position = "none",
          plot.margin = unit(0 * c(-1.5, -1.5, -1.5, -1.5), "lines"))
  
  ## Create plot_ly() object: ##
  EuropePlot <- plotly::ggplotly(p, tooltip = "text") %>%
    layout(xaxis = ax, yaxis = ax)
}

ui <- fluidPage(
  plotlyOutput (outputId = "maPPInfoPLOT", width = "900px", height = "600px")
)

server <- function(input, output, session) {
  # PLOT-Output: #
  EuropePlot <- getEuropePlot()
  output$maPPInfoPLOT <- renderPlotly({
    plotly::ggplotly(EuropePlot, dynamicTicks = TRUE)
  })
}

shinyApp(ui, server)