How to use set_token in mapdeck? - r

I'm trying to reproduce this example: https://github.com/SymbolixAU/mapdeck, using mapdeck r package.
I registered myself on mapbox site and create my token.
Whenever I run my script there is no error, but there is no map either.
library(mapdeck)
library(leaflet)
key <- set_token("pk.eyJ1IjoicmFxdWVsc2FyYWl2YTE5ODgiLCJhIjoiY2p4MzM2eHh5MG95aTN5cDQxdjVocDlxMCJ9.Wskus8QqYwjAufGpW71OVg")
df <- readRDS("df.rds")
df$Station_Long = as.numeric(as.character(df$lon_Pay))
df$Station_Lat = as.numeric(as.character(df$lat_Pay))
df$id = as.factor(as.numeric(as.factor(df$ID)))
mapdeck(
token = key,
style = mapdeck_style('dark')
, location = c(104, 1)
, zoom = 8
, pitch = 45
) %>%
add_arc(
data = df
, origin = c("centroid_lon", "centroid_lat")
, destination = c("lon_Pay", "lat_Pay")
, layer_id = 'arclayer'
, stroke_width = 3
, stroke_from = "#ccffff"
, stroke_to = "#ccffff"
)
My key is NULL (empty).
Does anybody knows why this is happening?

If you use set_token() you don't assign it to a variable, you just call it.
library(mapdeck)
set_token( "YOUR_MAPOBX_TOKEN" )
It's then stored globally in your session
## view your token
mapdeck_tokens()
# Mapdeck tokens
# - mapbox : YOUR_MAPBOX_TOKEN
Using set_token() means you don't have to supply the token argument in the mapdeck() call
url <- 'https://raw.githubusercontent.com/plotly/datasets/master/2011_february_aa_flight_paths.csv'
flights <- read.csv(url)
flights$id <- seq_len(nrow(flights))
flights$stroke <- sample(1:3, size = nrow(flights), replace = T)
flights$info <- paste0("<b>",flights$airport1, " - ", flights$airport2, "</b>")
mapdeck( style = mapdeck_style("dark"), pitch = 45 ) %>%
add_arc(
data = flights
, layer_id = "arc_layer"
, origin = c("start_lon", "start_lat")
, destination = c("end_lon", "end_lat")
, stroke_from = "airport1"
, stroke_to = "airport2"
, stroke_width = "stroke"
, tooltip = "info"
, auto_highlight = TRUE
, legend = T
, legend_options = list(
stroke_from = list( title = "Origin airport" ),
css = "max-height: 100px;")
)

Related

Remove an automatic title in a plot (R)

I am using a function "lp_lin_panel" from the package "lpirfs", for example:
hor3.1_h <- lp_lin_panel(data_set = panel_3 , data_sample = "Full" , endog_data = "E.tertiary", cumul_mult = TRUE , shock = "lv18_bank_c", diff_shock = FALSE , iv_reg = FALSE , instrum = NULL , panel_model = "within" , panel_effect = "individual" , robust_cov = "vcovSCC" , use_gmm = FALSE, gmm_model = "onestep", gmm_transformation = "d", c_exog_data = cv_3_h, l_exog_data = NULL, confint = 1.96 , hor = 6 )
When I use the command:
plot(hor3.1_h , main = NULL)
I still get an automatic title in the plot. Like this
Is there another way to remove it?
Thank you
Try to use:
plot(hor3.1_h) + labs(title = "")

How can I make the color scale in mapdeck static

I am developing a shiny app which steps through time by each hour and shows the precipitation on a mapdeck map. I read in the weather data for the entire day and using reactivity filtering the data for the hour and plotting them as scatterplot using mapdeck_update to update the data. The color scale changes whenever the map updates based on the range of data in that hour. What I want is a static color scale based on the data range for the day. Is it possible?
I have tried using manual colors but for some reason they are not working
library(mapdeck)
ui <- fluidPage(
fluidRow(sliderInput(inputId = "hr",label = "Hour",min = 1,max = 3,value = 1)),
fluidRow(mapdeckOutput(outputId = "wx"))
)
sr <- function(input, output, session) {
mydata <- read.table(header=TRUE, sep=",",text="
ROW,COL,Center Latitude,Center Longitude,vil_int_36,hr
28,439,23.669885449218786,-97.2498101160108,20,1
41,433,24.37845221074034,-97.59803936272704,21,1
59,441,25.35333762373948,-97.11966878019186,22,1
61,441,25.461905262766468,-97.11878391116397,23,1
62,443,25.515163854569053,-96.99946877404128,24,1
29,439,23.724265738052193,-97.24945283742396,25,2
43,433,24.48713046908765,-97.59764743717052,26,2
59,442,25.35284441116698,-97.06032252207848,27,2
61,442,25.46141127997772,-97.05937801465758,28,2
62,444,25.514605007836384,-96.94003374232112,29,2
29,440,23.723846594719276,-97.19096992696834,30,3
43,434,24.486897474919978,-97.53876699838483,31,3
60,443,25.406603480942334,-97.00047511628769,32,3
62,441,25.516184831702166,-97.11834002241596,33,3
62,449,25.511327212479294,-96.64286546489153,34,3
")
wx_map <- mapdeck(data=NULL,token = Sys.getenv("MAPBOX_API_TOKEN"),style = 'mapbox://styles/mapbox/dark-v9',zoom = 6, location = c(-97,24.5))
observe({
wx_dt <- mydata %>% dplyr::filter(hr == input$hr)
mapdeck_update(map_id = "wx") %>%
add_scatterplot(data=wx_dt,lon = "Center.Longitude",lat = "Center.Latitude",radius = 15000,fill_colour = "vil_int_36",legend = TRUE,layer_id = "wxlyr",update_view = FALSE,focus_layer=FALSE)
})
output$wx <- renderMapdeck(wx_map)
}
shinyApp(ui, sr)
Notice how the range of color scale in the legend changes but the color of the dots stay almost the same. I want the color to represent the min-max of the entire data set (not just the hour) so that I can see change in intensity while stepping through each hour. Thank you.
Good question; you're right you need to create a manual legend so it remains static, otherwise it will update each time the values in the plot update.
The manual legend needs to use the same colours as the map. The map gets coloured by library(colourvalues). So you can use this to make the colours outside of the map, then use the results as the manual legend
l <- colourvalues::colour_values(
x = mydata$vil_int_36
, n_summaries = 5
)
legend <- mapdeck::legend_element(
variables = l$summary_values
, colours = l$summary_colours
, colour_type = "fill"
, variable_type = "category"
)
js_legend <- mapdeck::mapdeck_legend(legend)
Now this js_legend object is in the correct JSON format for the map to render it as a legend
js_legend
# {"fill_colour":{"colour":["#440154FF","#3B528BFF","#21908CFF","#5DC963FF","#FDE725FF"],"variable":["20.00","23.50","27.00","30.50","34.00"],"colourType":["fill_colour"],"type":["category"],"title":[""],"css":[""]}}
Here it is in your shiny
library(mapdeck)
library(shiny)
ui <- fluidPage(
fluidRow(sliderInput(inputId = "hr",label = "Hour",min = 1,max = 3,value = 1)),
fluidRow(mapdeckOutput(outputId = "wx"))
)
sr <- function(input, output, session) {
mydata <- read.table(header=TRUE, sep=",",text="
ROW,COL,Center Latitude,Center Longitude,vil_int_36,hr
28,439,23.669885449218786,-97.2498101160108,20,1
41,433,24.37845221074034,-97.59803936272704,21,1
59,441,25.35333762373948,-97.11966878019186,22,1
61,441,25.461905262766468,-97.11878391116397,23,1
62,443,25.515163854569053,-96.99946877404128,24,1
29,439,23.724265738052193,-97.24945283742396,25,2
43,433,24.48713046908765,-97.59764743717052,26,2
59,442,25.35284441116698,-97.06032252207848,27,2
61,442,25.46141127997772,-97.05937801465758,28,2
62,444,25.514605007836384,-96.94003374232112,29,2
29,440,23.723846594719276,-97.19096992696834,30,3
43,434,24.486897474919978,-97.53876699838483,31,3
60,443,25.406603480942334,-97.00047511628769,32,3
62,441,25.516184831702166,-97.11834002241596,33,3
62,449,25.511327212479294,-96.64286546489153,34,3
")
## create a manual legend
l <- colourvalues::colour_values(
x = mydata$vil_int_36
, n_summaries = 5
)
legend <- mapdeck::legend_element(
variables = l$summary_values
, colours = l$summary_colours
, colour_type = "fill"
, variable_type = "category"
)
js_legend <- mapdeck::mapdeck_legend(legend)
### --------------------------------
wx_map <- mapdeck(
style = 'mapbox://styles/mapbox/dark-v9'
, zoom = 6
, location = c(-97,24.5)
)
observe({
wx_dt <- mydata %>% dplyr::filter(hr == input$hr)
mapdeck_update(map_id = "wx") %>%
add_scatterplot(
data = wx_dt
, lon = "Center.Longitude"
, lat = "Center.Latitude"
, radius = 15000
, fill_colour = "vil_int_36"
, legend = js_legend
, layer_id = "wxlyr"
, update_view = FALSE
, focus_layer = FALSE
)
})
output$wx <- renderMapdeck(wx_map)
}
shinyApp(ui, sr)

Mapping the shortest flight path across the date line in R leaflet/Shiny, using gcIntermediate [duplicate]

This question already has answers here:
Plotting routes that cross the international dateline using leaflet library in R
(3 answers)
Closed 4 years ago.
I'm creating a map of Australian airports and their international destinations using R-Leaflet.
Here is my sample data:
df<-data.frame("Australian_Airport" = "Brisbane",
"International" = c("Auckland", "Bandar Seri Begawan","Bangkok","Christchurch","Denpasar","Dunedin","Hamilton","Hong Kong","Honiara","Kuala Lumpur"),
"Australian_lon" = c(153.117, 153.117,153.117,153.117,153.117,153.117, 153.117, 153.117, 153.117, 153.117),
"Australian_lat" = c(-27.3842,-27.3842,-27.3842,-27.3842,-27.3842,-27.3842, -27.3842, -27.3842, -27.3842, -27.3842),
"International_lon" = c(174.7633, 114.9398, 100.5018, 172.6362, 115.2126,-82.77177, -84.56134, 114.10950, 159.97290, 101.68685),
"International_lat" = c(-36.848460, 4.903052, 13.756331, -43.532054,-8.670458,28.019740, 39.399501, 22.396428, -9.445638, 3.139003)
)
I thought it would be cool to use curved flight paths using gcIntermediate, so I created a SpatialLines object:
library(rgeos)
library(geosphere)
p1<-as.matrix(df[,c(3,4)])
p2<-as.matrix(df[,c(5,6)])
df2 <-gcIntermediate(p1, p2, breakAtDateLine=F,
n=100,
addStartEnd=TRUE,
sp=T)
And then I plotted it using leaflet and Shiny:
server <-function(input, output) {
airportmap<- leaflet() %>% addTiles() %>%
addCircleMarkers(df, lng = df$Australian_lon, lat = df$Australian_lat,
radius = 2, label = paste(df$Australian_Airport, "Airport"))%>%
addPolylines(data = df2, weight = 1)
output$mymap <- renderLeaflet({airportmap}) # render the base map
}
ui<- navbarPage("International flight path statistics - top routes",
tabPanel("Interactive map",
leafletOutput('mymap', width="100%", height=900)
)
)
# Run the application
shinyApp(ui = ui, server = server)
It looks like this:
So the paths are incorrect if they cross the date line. Changing breakAtDateLine to FALSE doesn't fix it (the line disappears but the path is still broken). At this stage, I suspect I may need to use a different mapping system or something but I'd be very grateful if anyone has some advice.
Thanks in advance.
Overview
I set the max bounds and minimum zoom level to only display the world map once. It looks okay in the RStudio viewer but fails when I display it in browser. I'm hoping this helps spark other answers.
Code
# load necessary packages
library( leaflet )
library( geosphere )
# create data
df <-
data.frame("Australian_Airport" = "Brisbane",
"International" = c("Auckland", "Bandar Seri Begawan","Bangkok","Christchurch","Denpasar","Dunedin","Hamilton","Hong Kong","Honiara","Kuala Lumpur"),
"Australian_lon" = c(153.117, 153.117,153.117,153.117,153.117,153.117, 153.117, 153.117, 153.117, 153.117),
"Australian_lat" = c(-27.3842,-27.3842,-27.3842,-27.3842,-27.3842,-27.3842, -27.3842, -27.3842, -27.3842, -27.3842),
"International_lon" = c(174.7633, 114.9398, 100.5018, 172.6362, 115.2126,-82.77177, -84.56134, 114.10950, 159.97290, 101.68685),
"International_lat" = c(-36.848460, 4.903052, 13.756331, -43.532054,-8.670458,28.019740, 39.399501, 22.396428, -9.445638, 3.139003)
, stringsAsFactors = FALSE
)
# create curved lines
curved.lines <-
gcIntermediate(
p1 = as.matrix( x = df[ , 3:4 ] )
, p2 = as.matrix( x = df[ , 5:6 ] )
, breakAtDateLine = TRUE
, n = 1000
, addStartEnd = TRUE
, sp = TRUE
)
# create leaflet
airport <-
leaflet( options = leafletOptions( minZoom = 1) ) %>%
setMaxBounds( lng1 = -180
, lat1 = -89.98155760646617
, lng2 = 180
, lat2 = 89.99346179538875 ) %>%
addTiles() %>%
addCircleMarkers( data = df
, lng = ~Australian_lon
, lat = ~Australian_lat
, radius = 2
, color = "red"
, label = paste( ~Australian_Airport
, "Airport" )
) %>%
addCircleMarkers( data = df
, lng = ~International_lon
, lat = ~International_lat
, radius = 2
, color = "blue"
, label = paste( ~International
, "Airport" )
) %>%
addPolylines( data = curved.lines
, weight = 1
)
# display map
airport
# end of script #
If you are interested in another mapping library, then googleway uses Google Maps, which in my experience is better at handling lines that cross the date line.
Notes
To use Google Maps you need an API key
Currently only sf objects are supported, not sp
This will also work in shiny; I'm just showing you the basic map here
I authored googleway
library(sf)
library(googleway)
## convert the sp object to sf
sf <- sf::st_as_sf(df2)
set_key("your_api_key")
google_map() %>%
add_polylines(data = sf)

Drawing journey path using leaflet in R

I am creating a Shiny dashboard with a dataframe of start longitude/latitude and end longitude/latitude cooridnated that I have plotted in R using the leaflet package:
`m=leaflet()%>%
addTiles() %>%
addMarkers(lng=(data$Start_long[i:j]), lat=(data$Start_lat[i:j]),popup="Start") %>%
addCircleMarkers(lng=(data$End_long[i:j]), lat=(data$End_lat[i:j]),popup="End",clusterOptions=markerClusterOptions())`
I was wondering if there was a way to join the start and end coordinated by public transport routes (maybe through google maps API or in-library functions or failing that, join the coordinates by a straight line?
You can use my googleway package to both get the directions/routes, and plot it on a Google map
To use Google's API you need a valid key for each API you want to use. In this case you'll want a directions key, and for plotting the map you'll want a maps javascript key
(You can generate one key and enable it for both APIs if you wish)
To call the Directions API and plot it in R, you can do
library(googleway)
api_key <- "your_directions_api_key"
map_key <- "your_maps_api_key"
## set up a data.frame of locations
## can also use 'lat/lon' coordinates as the origin/destination
df_locations <- data.frame(
origin = c("Melbourne, Australia", "Sydney, Australia")
, destination = c("Sydney, Australia", "Brisbane, Australia")
, stringsAsFactors = F
)
## loop over each pair of locations, and extract the polyline from the result
lst_directions <- apply(df_locations, 1, function(x){
res <- google_directions(
key = api_key
, origin = x[['origin']]
, destination = x[['destination']]
)
df_result <- data.frame(
origin = x[['origin']]
, destination = x[['destination']]
, route = res$routes$overview_polyline$points
)
return(df_result)
})
## convert the results to a data.frame
df_directions <- do.call(rbind, lst_directions)
## plot the map
google_map(key = map_key ) %>%
add_polylines(data = df_directions, polyline = "route")
And similarly in a Shiny app
library(shiny)
library(shinydashboard)
library(googleway)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody(
textInput(inputId = "origin", label = "Origin"),
textInput(inputId = "destination", label = "Destination"),
actionButton(inputId = "getRoute", label = "Get Rotue"),
google_mapOutput("myMap")
)
)
server <- function(input, output){
api_key <- "your_directions_api_key"
map_key <- "your_maps_api_key"
df_route <- eventReactive(input$getRoute,{
print("getting route")
o <- input$origin
d <- input$destination
return(data.frame(origin = o, destination = d, stringsAsFactors = F))
})
output$myMap <- renderGoogle_map({
df <- df_route()
print(df)
if(df$origin == "" | df$destination == "")
return()
res <- google_directions(
key = api_key
, origin = df$origin
, destination = df$destination
)
df_route <- data.frame(route = res$routes$overview_polyline$points)
google_map(key = map_key ) %>%
add_polylines(data = df_route, polyline = "route")
})
}
shinyApp(ui, server)
You can addPolylines() to the map.
It takes two vectors as arguments, one for the lat and one for the lng, where each row is a 'waypoint'.
It's difficult to help you without knowing the structure of your data.
MRE:
library(leaflet)
cities <- read.csv(textConnection("
City,Lat,Long,Pop
Boston,42.3601,-71.0589,645966
Hartford,41.7627,-72.6743,125017
New York City,40.7127,-74.0059,8406000
Philadelphia,39.9500,-75.1667,1553000
Pittsburgh,40.4397,-79.9764,305841
Providence,41.8236,-71.4222,177994
"))
leaflet() %>%
addTiles() %>%
addPolylines(lat = cities$Lat, lng = cities$Long)
I use "for loop" to solve such problem,just draw polylines one by one.
(sorry for my Chinese expression ^_^)
for examply :
for(i in 1:nrow(sz)){
if(i<=nrow(sz) ){
a <- as.numeric(c(sz[i,c(8,10)]));
b <- as.numeric(c(sz[i,c(9,11)]));
A <- A %>% addPolylines(a,b,group=NULL,weight = 1,color = "brown",
stroke = TRUE,fill = NULL,opacity = 0.8)}
or like a more complex one
for(j in 0:23){if(j<=23)
#j--切每小时数据
j1 <- as.character(paste(j,"点",sep=''))
sz <- sz121[sz121$h==j,]
sz_4 <- sz121[sz121$bi_state==4 &sz121$h==j ,]
sz_8 <- sz121[sz121$bi_state==8&sz121$h==j,]
#还原A
A <- leaflet(sz121) %>% amap() %>% addLabelOnlyMarkers(~s_lon,~s_lat) %>%
addLegend(title=j1,colors=NULL,labels =NULL,position="topleft")
A <- A %>%addCircleMarkers(data=sz_8,~s_lon,~s_lat,color="orange",fill=TRUE,fillColor = "red", opacity = 1,fillOpacity=0.8,
weight =1,radius = 10) %>%addCircleMarkers(data=sz_4,~s_lon,~s_lat,color="black",fill=TRUE,fillColor = "red",
opacity = 1,fillOpacity=0.8,weight =5,radius = 10 ) %>%
addCircleMarkers(data=sz_8,~e_lon,~e_lat,color="orange",fill=TRUE,fillColor = "blue", opacity = 1,fillOpacity=0.8,weight=1,radius = 10) %>%
addCircleMarkers(data=sz_4,~e_lon,~e_lat,color="black",fill=TRUE,fillColor = "blue", opacity = 1,fillOpacity=0.8,weight =5,radius = 10 )
for(i in 1:nrow(sz)){
#i--画路径
if(i<=nrow(sz) ){
a <- as.numeric(c(sz[i,c(8,10)]));
b <- as.numeric(c(sz[i,c(9,11)]));
A <- A %>% addPolylines(a,b,group=NULL,weight = 1,color = "brown",stroke = TRUE,fill = NULL,opacity = 0.8)
}
if(i==nrow(sz)){print(A)}
}
Sys.sleep(3)
}

How to get image iconMarker working for plotGoogleMaps R?

What am I trying to do:
I am trying to plot 2 groups of points (vessels) with different icons on a nice interactive map. (The vessels have longitude and latitude) The interactivity is important!
The code will actually go inside an iframe in a shiny application.
I set up an example vessel data set (two groups of 5), and plot them onto 2 separate layers. I have been doing a bit of research and plotGoogleMaps seemed like a good package to go to.
library(plotGoogleMaps)
vessels = data.frame(id = c(1:10)
, lat = c(22.0959, 22.5684, 21.9189, 21.8409, 22.4663, 22.7434, 22.1658, 24.5691, 22.4787, 22.3039)
, lon = c(114.021, 114.252, 113.210, 113.128, 113.894, 114.613, 113.803, 119.730, 113.910, 114.147))
group1 = vessels[1:5,]
group2 = vessels[6:10,]
coordinates(group1) = ~ lon + lat
proj4string(group1) = CRS("+proj=longlat +datum=WGS84")
group1 <- SpatialPointsDataFrame( group1 , data = data.frame( ID = row.names( group1 ) ))
coordinates(group2) = ~ lon + lat
proj4string(group2) = CRS("+proj=longlat +datum=WGS84")
group2 <- SpatialPointsDataFrame( group2 , data = data.frame( ID = row.names( group1 ) ))
m <- plotGoogleMaps(group1, legend = FALSE, layerName = "Vessels 1"
, add = T, iconMarker='http://maps.google.com/mapfiles/kml/shapes/placemark_circle.png', mapTypeId='ROADMAP')
m <- plotGoogleMaps(group2,legend = FALSE, layerName = "Vessels 2"
, previousMap = m , add = F
, iconMarker = 'http://maps.google.com/mapfiles/kml/shapes/placemark_circle.png'
, filename = "out.htm")
Could anyone please tell me where the code is going wrong? Any constructive ideas are appreciated as well!
Result:
The icon marker has not actually been picked up as you can see it on the result. I would like to use a custom image. Thank you for your help
You need a little modification on the last 2 lines of code, and than you will get what you want.
m <- plotGoogleMaps(group1, legend = FALSE, layerName = "Vessels 1"
, add =T,
iconMarker=rep('http://maps.google.com/mapfiles/kml/shapes/placemark_circle.png',nrow(group1) ),
mapTypeId='ROADMAP', filename = "out.htm")
m <- plotGoogleMaps(group2,legend = FALSE, layerName = "Vessels 2"
, previousMap = m , add = F
, iconMarker = rep('http://maps.google.com/mapfiles/kml/shapes/placemark_circle.png',nrow(group2) )
, filename = "out.htm")

Resources