Quick question all.
I have some data in sql server which i have loaded into RStudio. I have made a barchart for the data and now i am using leaflet library with the use of latitude and longitude to plot a point on the map. I want to be able to use popup to show a barchart in it when the user clicks on the point.
BarChart code (maybe this is a problem because i am using googleVis library so not sure if i can use this in the popup. but again this is the most appropriate bar graph i can make and need- other suggestions could be helpful as i am not a professional in R libraries yet)
Switzerland <- sqlQuery(con, "sql query")
SwitzerlandChart <- gvisBarChart(Switzerland, options = list(height=200))
For the graph plot the code is:
m <- leaflet() %>%
addTiles() %>% # Add default OpenStreetMap map tiles
addCircles(lng=8.498868, lat=46.9221, popup=paste(plot(SwitzerlandChart)))
When i run this code it opens a webpage to view my barplot.
Then i run the following:
m #Prints the graph
This prints the graph with the point in the desired location but the popup shows me a webpage instead which also only i can open.
I want to be able to plot the bargraph inside the popup please.
Hope someone can help
Maybe a little late but here's a solution. The addPopups() function in library(leaflet) seems to be able to handle .svg files. Therefore, you could simply save your plot using svg() and then read it again using readLines(). Here's a reproducible example using library(mapview):
library(lattice)
library(mapview)
library(sp)
data(meuse)
coordinates(meuse) <- ~x+y
proj4string(meuse) <- CRS("+init=epsg:28992")
clr <- rep("grey", length(meuse))
fldr <- tempfile()
dir.create(fldr)
pop <- lapply(seq(length(meuse)), function(i) {
clr[i] <- "red"
p <- xyplot(meuse$cadmium ~ meuse$copper,
col = clr, pch = 20, alpha = 0.7)
svg(filename = paste(fldr, "test.svg", sep = "/"),
width = 250 * 0.01334, height = 250 * 0.01334)
print(p)
dev.off()
tst <- paste(readLines(paste(fldr, "test.svg", sep = "/")), collapse = "")
return(tst)
})
mapview(meuse, popup = pop, cex = "cadmium")
You will see that each popup is a scatterplot. As for a leaflet example, consider this:
content <- pop[[1]]
leaflet() %>% addTiles() %>%
addPopups(-122.327298, 47.597131, content,
options = popupOptions(closeButton = FALSE)
)
In case you need the plot to be interactive, you could have a look at library(gridSVG) which is able to produce interactive svg plots from e.g. lattice or ggplot2 plots.
UPDATE:
library(mapview) now has designated functionality for this:
popupGraph: to embed lattice, ggplot2 or interactive hatmlwidgets based plots.
popupImage: to embed local or remote (web) images
This is currently only available in the development version of mapview which can be installed with:
devtools::install_github("environmentalinformatics-marburg/mapview", ref = "develop"
This may be a little late too, but here is a full leaflet implementation. I first create the plot and then use the popupGraph function to add it in.
# make a plot of the two columns in the dataset
p <- xyplot(Home ~ Auto, data = Jun, col = "orange", pch = 20, cex = 2)
# make one for each data point
p <- mget(rep("p", length(Jun)))
# color code it so that the corresponding points are dark green
clr <- rep("orange", length(Jun))
p <- lapply(1:length(p), function(i) {
clr[i] <- "dark green"
update(p[[i]], col = clr)
})
# now make the leaflet map
m1 <- leaflet() %>%
addTiles() %>%
setView(lng = -72, lat = 41, zoom = 8) %>%
# add the markers for the Jun dataset
# use the popupGraph function
addCircleMarkers(data = Jun, lat = ~Lat, lng = ~Lon,
color = ~beatCol(BeatHomeLvl), popup = popupGraph(p),
radius = ~sqrt(BeatHome*50), group = 'Home - Jun') %>%
# layer control
addLayersControl(
overlayGroups = c('Home - Jun'
),
options = layersControlOptions(collapsed = F)
) %>%
# legend for compare to average
addLegend('bottomright', pal = beatCol, values = last$BeatTotalLvl,
title = 'Compare<br>Quote Count to<br>3Mos State Avg',
opacity = 1)
m1
Here is the output.
Related
I'm trying to add separate images to popups so that as you click on each location, an image specific to that place/popup appears. I've figured out how to get one image in, but it applies to all of the popups on the map instead of just one. I have been trying to use the package leafpop for this, but I can't really figure out how to make it work. Even if I just use one image, nothing appears on the map.
This is what my code looks like for it:
library(leaflet)
library(leafpop)
img = system.file("file/image_name.jpg", package = "jpg")
leaflet(map) %>%
addTiles() %>%
addCircleMarkers(label = map#data$name,
weight = 2,
color = "grey",
fillColor = "red",
fillOpacity = 0.7)%>%
addPopupImages(img, group = "map")
I know there's some bits in there that I'm not quite doing right. At this point, I just want to know if it's even possible to do this the way I'm envisioning. Any help is appreciated.
The images need to be in a vector of the same length as the points passed to leaflet. Here is a reproducible example you can copy paste that will get you started:
library(tidyverse)
library(sf)
library(leaflet)
library(leafpop)
pts <- tibble(x = runif(10, 175, 176),
y = runif(10, -38, -37)) %>%
st_as_sf(coords = c("x", "y"), crs = 4326)
img <- glue::glue("https://github.com/IQAndreas/sample-images/blob/gh-pages/100-100-color/{11:20}.jpg?raw=true")
pts$img <- img
leaflet() %>%
addTiles() %>%
addCircleMarkers(data = pts, group = "pts") %>%
addPopupImages(pts$img, group = "pts")
Figured it out, with the help of Rich Pauloo! This is the code I ended up using the get local image files. It's a little clunky, but it worked out for me:
data_name <- readOGR("data/map_file.kml")
data_name2 <- data.frame(data_name)
pts <- st_as_sf(data.frame(data_name2),
coords = c("coords.x1", "coords.x2"), crs = 4326)
img <- c("images/picture_name.jpg") ##did this for every image I wanted to use, in the order
##that matched up with the data points I wanted them associated with.
pts$img <- img
leaflet() %>%
addTiles() %>%
addCircleMarkers(data = pts, group = "pts") %>%
addPopupImages(pts$img, group = "pts", width = 300)
Sorry if my conventions for writing out code are not quite right for the website. I just wanted to keep things generic and not include any of my file names or anything.
Anyone created a leaflet map in Code Workbook using r-Leaflet? I have a functioning script that runs (also double checked in R) but how do I get it to visualise and then use in a Report etc. I have tried various tweaks on what may get it to run but no success - any ideas
leaflet_map <- function(map_data) {
library(leaflet)
data<-map_data
# first cut the continuous variable into bins
# these bins are now factors
data$Fill_rateLvl <- cut(data$Fill_rate,
c(0,.5,0.6,0.7,0.8,0.9,1), include.lowest = T,
labels = c('<50%', '50-60%', '60-70%', '70-80%', '80-90%','90-100%'))
# then assign a palette to this using colorFactor
# in this case it goes from red for the smaller values to yellow and green
# standard stoplight for bad, good, and best
FillCol <- colorFactor(palette = 'RdYlGn', data$Fill_rateLvl)
m<-leaflet() %>%
addTiles() %>%
addProviderTiles(providers$CartoDB.Positron)%>%
setView(lng = -0, lat = 50, zoom = 8) %>%
addCircleMarkers(data = data, lat = ~lat, lng = ~long,
color = ~FillCol(Fill_rateLvl), popup = data$Lead_employer,
radius = ~sqrt(Fill_rate*50), group = 'Fill rate') %>%
addLegend('bottomright', pal = FillCol, values = data$Fill_rateLvl,
title = 'Fill rate for next two weeks',
opacity = 1)
return(NULL)
}
I am not familiar with R in code workbook, but it sounds to me that you need to materialize your leaflet map as a dataset and then consume it in some sort of map compatible UI.
For example slate has a map widget which is backed by leaflets. You can find documentation and examples for it in https://www.palantir.com/docs/foundry/slate/widgets-map/
I am able to retrive a Direction map with the below Rscript, but I am unable to find function for making it Interactive.
longitude <- c( 77.605855,77.606800,77.596843,77.575793 )
latitude <- c(12.956580,12.966157, 12.964777,12.964473)
d <- as.data.frame(cbind(longitude,latitude))
map <- get_googlemap(center = c(lon = 77.605855, lat = 12.956580), zoom = 14,
size = c(500, 500), scale = 2,maptype = c("roadmap"),markers = d, path = d)
Below are the functionalities that I need to have in my map.
1. Interactive Zoom.
2. Auto Center so that all the markers are visible.
3. OnClick on the marker I would like to show title -say for Eg. "This is Your Car".
The documentation leaflet referred by #SymbolixAU at the comments helped me to arrive at the solution, below is my code to address my requirements mentioned in the question.
library(leaflet)
longitute <-c(77.605855,77.606800,77.596843,77.596747,77.596296,77.595738,77.594944 )
latitude <- c(12.956580,12.966157, 12.964777,12.964323,12.963570,12.962964, 12.962399)
d <- as.data.frame(cbind(longitute,latitude))
m <- leaflet() %>%
addTiles() %>% # Add default OpenStreetMap map tiles
addMarkers(lng=d$longitute, lat=d$latitude, popup="New Point",)
m<- addPolylines(m , lng = d$longitute, lat = d$latitude)
m
So this is my Output.
I am currently struggling to map multiple polygons in a shiny app. The purpose of the shiny app is to take some data pertaining to disease spread in a number of states and map the areas of highest risk. The app must be able to map multiple states at the click of the "Start!" button.
(Note: This app is very large (6000+ lines in total) so only relevant code will be shown here, I don't want to burden the ones trying to help me)
Excerpts from:
Server.R
#The purpose of col_inputs and col_names is to create a two-dimensional array with all of the input parameters for the function. This was done to maintain compatibility with some legacy code. Catted_states on the other hand combines all states selected into a list.
(Example: c("AZ","FL","VA")
output$gm <- renderLeaflet({
global_map(ARG_1, ARG_2, ARG_3)
})
Global_Map.R
The only real concerns with this code is that 'M' isn't being drawn at all after the for loop finishes.
global_map <- function(col_names, col_inputs, catted_states) {
User_para <- array(0, dim = c(16, 2))
for( I in 1:length(states) {
if (state_num > 10) {
read.csv(Loop specific file)
}
if (state_num < 10) {
read.csv(Loop specific file)
}
state_num * Loop specific calculation[I]
pal <- colorNumeric(palette = "Purples", domain = state_output$risk)
pal_sR <- pal(state_output$risk)
m <- addProviderTiles(m, "CartoDB.Positron")
m <- addLegend(m, title = "Risk", pal = pal, values = ~state_output$risk,
opacity = 0.7)
m <- addPolygons(m, stroke = FALSE, smoothFactor = 0, fillOpacity = 0.5,
color = ~pal_sR)
}
}
How can I get this code to map the multiple states? What is incorrect about my leaflet calls? I need this code to load multiple shape files into shiny and draw polygons once on each shape file and map them accordingly
I am not really sure if that solves your problem, but your example is absolutely not reproducible and also has several errors. If you want to produce several polygons inside a for loop and then add them to a leaflet map, here is the code:
library(shiny)
library(leaflet)
ui <- fluidPage(
sliderInput("nPolys", "How many Loops", min = 1, max = 20, value = 3),
## Map
leafletOutput("gm")
)
server <- function(input, output) {
## Initialize map
m = leaflet() %>% addTiles()
## Render Map
output$gm <- renderLeaflet({
## Loop
for (I in 1:input$nPolys) {
## Create dummy polygons
Sr1 = Polygon(cbind(c(2,4,4,1,2)*runif(1,1,10),c(2,3,5,4,2)*runif(1,1,10)))
Sr2 = Polygon(cbind(c(5,4,2,5)*runif(1,1,10),c(2,3,2,2)*runif(1,1,10)))
Srs1 = Polygons(list(Sr1), "s1"); Srs2 = Polygons(list(Sr2), "s2")
SpP = SpatialPolygons(list(Srs1,Srs2), 1:2)
## add Polygons to map
m <- addPolygons(m, data=SpP, stroke = FALSE, smoothFactor = 0, fillOpacity = 0.5)
}
## Call map !
m
})
}
shinyApp(ui, server)
I'm using leaflet for R and I simply would like to be redirected on some URL when I click on the raster image. My current code is the following :
library(htmlwidgets)
library(raster)
library(leaflet)
library(sp)
imgPath = paste(projectPath,"/test.tif", sep = "")
outPath = paste(projectPath, "/leaflethtmlgen.html", sep="")
r <- raster(imgPath)
pal <- colorNumeric(c("#FF0000", "#666666", "#FFFFFF"), values(r),
na.color = "transparent")
m <- leaflet()
m <- addTiles(m)
m <- addRasterImage(m,r, colors=pal, opacity = 0.9, maxBytes = 123123123, group = "Raster1")
m <- addLegend(m,pal = pal, values = values(r), title = "Test")
m <- addLayersControl(
m,
overlayGroups = c("Raster1"),
options = layersControlOptions(collapsed = FALSE)
)
m
The result is the following:
You could use viewExtent from the mapview package for that:
library(mapview)
mapview(poppendorf[[10]]) +
viewExtent(poppendorf[[10]],
opacity = 0, fillOpacity = 0,
popup = 'Search Google')
viewExtent does as the name suggests draw a rectangle around the the extent of a raster image (or any spatial object form the sp package). By setting the line and fill opacity to zero and providing a custom popup you can achieve something that is pretty close to what you want. I am not aware of any way to directly link hyperlinks to raster objects in leaflet for R.
HTH,
Tim