Change map colourfill based on user selection - r

It's been a while since i'm having this problem. My current shiny app is not able to communicate with the user selection. It is supposed to show a colour fill variation across different region when a user makes a selection. However, it seems like the map is not showing it. My best guess is that it is not reading the 'pal' function correctly, and not able to capture the selection that the user input.
any kind of help would be great.
library(datasets)
library(dplyr)
library(ggplot2)
library(gridExtra)
library(leaflet)
library(leaflet.extras)
library(Matrix)
library(readxl)
library(rgdal)
library(shiny)
library(stringr)
library(tidyverse)
library(tidyr)
library(RColorBrewer)
cf <- read.csv("datafile.csv")
sgmap55 <-readOGR("shapefile.kml")
bins <-c(1,50,100,150,200)
pal <- colorBin("Blues", domain = NULL, bins = bins, na.color = "#808080")
#5) setting for the labels.
labels <- sprintf(
"<strong>%s</strong><br/>%g respondents </sup>",
cf$planarea, cf$planarea)%>% lapply(htmltools::HTML)
##Section C: ShinyApp starts here
ui <- fluidPage(
titlePanel("Brand Interaction with Regions"),
sidebarLayout(
sidebarPanel(
radioButtons("brand", "Select First Brand:", choices = colnames(cf[,c(3,4,5,6,7,8,9,10,11,12,13,14)]))),
mainPanel(
leafletOutput("sgmap2")
)
)
)
server <- function(input, output, session) {
output$sgmap2 <- renderLeaflet({
selected_brand <- input$brand
leaflet() %>%
addTiles() %>%
addResetMapButton()%>%
clearMarkers()%>%
addProviderTiles("OpenStreetMap") %>%
setView(103.8198,1.3521,11)%>%
addPolygons(data = sgmap55,
highlight = highlightOptions(
weight = 5,
color = "#666666",
fillOpacity = 0.7,
fillColor = pal(input$selected_brand),
bringToFront = TRUE))
})
}
shinyApp(ui = ui, server = server)

manage to solve it with below code in between the server portion:
req(input$brand)
cpop <- cf[[input$brand]]

Related

In shiny + leaflet, setview is updated every time render is executed. I want to prevent this

I create a map app using shiny and leaflet.
It projects a map and some shape files.
The shape file has area values.
I want to set whether to display the shape file or not based on the area value.
Specifically, the sliderInput function is used.
Although the display of the shape file is restricted using the sliderInput function,
The setview is reset every time the number is changed by sliderInput.
Instead of running setview every time, I want you to run setview where you are.
What should I do? I want you to tell me.
Below is the sample code
library(shiny)
library(leaflet)
ui <- shinyUI(fluidPage(
titlePanel("sample sample sample sample "),
#sidebarLayout settings
sidebarLayout(
sidebarPanel(
sliderInput("area_slider",label = h3("settings"),min = 0,max = 6000,value = c(0,6000)),
),
#mainpanel settings
mainPanel(
leafletOutput("mymap",height=600)
)
)
))
server <- shinyServer(function(input, output) {
#map settings
output$mymap <- renderLeaflet({
leaflet() %>%
addTiles(group="OSM")%>%
#setView
#setView(lng=139.8,lat=35.7,zoom=12)%>%
#maker settings1
addAwesomeMarkers(lng = df$lng,
lat = df$lat,
clusterOptions = markerClusterOptions(),
group="Oct")%>%
addPolygons(data = shp %>% subset(shp#data$area < input$area_slider),
color = "#2feeb5",
group="carea")%>%
#Layers Control
addLayersControl(
baseGroups = c("OSM"),
overlayGroups = c("Oct","carea"),
options = layersControlOptions(collapsed = FALSE))
})
})
shinyApp(ui, server)

Publishing a shiny/leaflet map made in R to a website

I'm helping a friend doing some research on the number of breweries in CT. With help from this community I was able to make a map of breweries in leaflet and was able to add a slider using shiny. Now I want to be able to give my friend the map so he can add it to the website where he is publishing his research. I'm new to some of this and was wondering if anybody had some ideas for me. Here is the code (thanks to Ben) I used to make the map:
library(shiny)
library(leaflet)
ui <- bootstrapPage(
tags$style(type = "text/css", "html, body {width:100%;height:100%}"),
leafletOutput("map", width = "100%", height = "100%"),
absolutePanel(bottom = 30, right = 10,
textOutput("Counter"),
sliderInput("Year", "Year", 1990, 2000, value = 1995, step = 1, sep = "")
)
)
server <- function(input, output, session) {
sliderData <- reactive({
breweries_subset %>%
filter(YearOpened <= input$Year)
})
output$Counter <- renderText(
paste("Number Breweries: ", nrow(sliderData()))
)
output$map <- renderLeaflet({
leaflet() %>%
addTiles() %>%
fitBounds(min(breweries_subset$Longitude), min(breweries_subset$Latitude),
max(breweries_subset$Longitude), max(breweries_subset$Latitude))
})
observe({
leafletProxy("map", data = sliderData()) %>%
clearMarkers() %>%
addProviderTiles(provider = 'Esri.WorldStreetMap') %>%
addAwesomeMarkers(icon = beer_icon,
group = 'Breweries',
popup = ~ Name)
})
}
shinyApp(ui = ui, server = server)
UPDATE
I took your suggestions and tried publishing to shinyapps.io. Here's the code I used:
For ui.R:
library(shiny)
library(leaflet)
ui <- bootstrapPage(
tags$style(type = "text/css", "html, body {width:100%;height:100%}"),
leafletOutput("map", width = "100%", height = "100%"),
absolutePanel(bottom = 30, right = 10,
textOutput("Counter"),
sliderInput("Year", "Year", 1990, 2019, value = 1995, step = 1, sep = "")
)
)
And for server.R:
library(shiny)
library(leaflet)
library(leaflet.extras)
library(fontawesome)
library(rsconnect)
function(input, output, session) {
ct_breweries <- read.csv('ct_breweries.csv', header=TRUE, sep=',')
sliderData <- reactive({
ct_breweries %>%
filter(YearOpened <= input$Year)
})
output$Counter <- renderText(
paste('Number of Breweries: ', nrow(sliderData()))
)
output$map <- renderLeaflet({
leaflet() %>%
addTiles() %>%
fitBounds(min(ct_breweries$Longitude), min(ct_breweries$Latitude),
max(ct_breweries$Longitude), max(ct_breweries$Latitude))
})
observe({
leafletProxy('map', data = sliderData()) %>%
clearMarkers() %>%
addProviderTiles(provider = 'Esri.WorldStreetMap') %>%
addAwesomeMarkers(icon = beer_icon,
group = 'Breweries',
popup = ~ Name)
})
}
It works fine locally. When I try to publish it, I get a Disconnected from Server error. In the logs it says something about 'YearOpened' not found. There's definitely a column for that in the .csv. I'm wondering if it has something to do with the call to the fall. Any ideas? Thanks
Try adding all the package loading and dataset reading to a global.R file (in the same app folder) as below:
library(shiny)
library(leaflet)
library(leaflet.extras)
library(fontawesome)
library(rsconnect)
ct_breweries <- read.csv('ct_breweries.csv', header=TRUE, sep=',')
You can then remove these from ui.R and server.R.
The problem seems to be that the dataset is not visible to the server - this should fix that. Also, make sure that the csv file is in the same folder.
Update
Based on my comment above, if this is sufficient, you can just save an html file of the map that you can send to your friend to open in a browser. I have attempted to write the code without your data so this may not work.
library(leaflet)
library(fontawesome)
library(htmlwidgets)
ct_breweries <- read.csv('ct_breweries.csv', header=TRUE, sep=',')
leaflet_map <- leaflet(data = ct_breweries) %>%
addProviderTiles(provider = 'Esri.WorldStreetMap') %>%
addAwesomeMarkers(icon = beer_icon,
group = ~ YearOpened,
popup = ~ Name) %>%
addLayersControl(
overlayGroups = 1990:2000,
options = layersControlOptions(collapsed = FALSE)
) %>% hideGroup(~ YearOpened)
saveWidget(leaflet_map, file="leaflet_map.html")
It does lose the slider option - replaced with checkboxes. You can remove the hideGroup() and collapsed = FALSE to see other options. This might be easier assuming the slider is not a requirement.
This file is saved offline but you will need an internet connection to fetch the leaflet map tiles.

R Leaflet GeoJSON Coloring

I am still working on this R Leaflet self project to learn and I'm trying to color in some Polygons in the Wake County area of Raleigh, NC. Below is the image of what I am trying to color.
https://imgur.com/a/xdvNLvM
Basically I am trying to get each of those polygons colored differently. I've tried addPolygons but I guess I didn't have correct Polygon data. I've looked at color binning but I seem to be out of ideas. Below is my code. I even tried to unnest the GeoJSON data and create a factor palette but that hasn't seemed to work.
library(shiny)
library(leaflet.extras)
library(geojsonio)
library(rgdal)
dataurl <- 'https://opendata.arcgis.com/datasets/f5c3b84a6fcc499d8f9ece78602258eb_0.geojson'
data <- geojson_read(dataurl, method = 'web', parse = FALSE, what = 'list')
wake <- readOGR(dataurl)
wake$zips <- factor(sample.int(39L, nrow(wake), TRUE))
#bikedata <- 'D:/bicycle-crash-data-chapel-hill-region.geojson'
#bike <- geojson_read(bikedata)
vtdata <- 'http://geodata.vermont.gov/datasets/4c206846699947429df59c8cb552ab5c_11.geojson'
vt <- geojson_read(vtdata)
factpal <- colorFactor(topo.colors(39), wake$zips)
ui <- shinyUI(
fluidPage(
leafletOutput("map", width = "100%", height = "900px")
)
)
server <- function(input, output) {
wakegeojson <- reactive({
data
})
#bikegeojson <- reactive({
# bike
#})
vtgeojson <- reactive({
vt
})
output$map <- renderLeaflet({
leaflet() %>%
addTiles() %>%
setView(-93.65, 42.0285, zoom = 4)
})
observe({
leafletProxy("map") %>%
addWMSTiles("http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi",
layers = "nexrad-n0r-900913",
options = WMSTileOptions(format = "image/png", transparent = TRUE),
attribution = "") %>%
addGeoJSON(wakegeojson(), weight = 3, fill = factpal) %>%
#addGeoJSON(bikegeojson()) %>%
addGeoJSON(vtgeojson(), fill = FALSE, color = "black")
})
}
app <- shinyApp(ui = ui, server = server)
runApp(app, launch.browser = TRUE)
I think I need to explore the addPolygons feature more but I'm not exactly sure how to do that or how to parse/unnest my GeoJSON data in order to accomplish filling in the Wake County Zipcodes with different colors. Any help is always appreciated. Thank you.
I would switch to sf. You can directly load the geojson and produce a Multipolygon and a Multilinestring object which will also read much faster than readOGR.
Then you can just put those objects in addPolygons and addPolylines.
The following example should work:
library(shiny)
library(leaflet.extras)
library(geojsonio)
library(rgdal)
library(sf)
dataurl <- 'https://opendata.arcgis.com/datasets/f5c3b84a6fcc499d8f9ece78602258eb_0.geojson'
wake <- st_read(dataurl)
wake$zips <- factor(sample.int(39L, nrow(wake), TRUE))
vtdata <- 'http://geodata.vermont.gov/datasets/4c206846699947429df59c8cb552ab5c_11.geojson'
vt <- st_read(vtdata)
factpal <- colorFactor(topo.colors(39), wake$zips)
ui <- shinyUI(
fluidPage(
leafletOutput("map", width = "100%", height = "900px")
)
)
server <- function(input, output) {
wakegeojson <- reactive({
wake
})
vtgeojson <- reactive({
vt
})
output$map <- renderLeaflet({
leaflet() %>%
addTiles() %>%
addPolygons(data=wakegeojson(), color=factpal(wake$zips)) %>%
addPolylines(data=vtgeojson(), color="red")
})
}
app <- shinyApp(ui = ui, server = server)
runApp(app, launch.browser = TRUE)

problems with select input in r shiny leaflet app

I am using R 3.2.3 through RStudio Version 0.99.491, on Windows 10 64bit... I am creating a leaflet shiny app, using graduated circlemarkers. I want to display different months to show the change in data using selectInput(), but i don't know how to connect it to the 'radius =' argument of addCirclemarker() to make it dynamic. I know I'm just making it up with the 'radius =' argument of addCirclemarker() but I can't tell if I have selectInput() wrong too. here's the data I'm using. The result shows no error message and the map worked when the radius argument was given a single column assignment, ie a static map.
ui.r:
library(shiny)
library(leaflet)
shinyUI(fluidPage(
titlePanel("CAT Rider Count Map"),
sidebarLayout(
sidebarPanel(
selectInput("var", label = "1. Select the Month",
choices = c("April" = 3, "May" = 4, "June" = 5),
selected = 4)),
mainPanel(leafletOutput('crossact.map')
))))
server.r
library(shiny)
library(googlesheets)
library(leaflet)
gs_auth()
ttt <- gs_auth()
saveRDS(ttt, "ttt.rds")
gs_auth(token = ttt)
gs_auth(token = "ttt.rds")
crossact <- gs_title("crossact")
crossact <- crossact%>% gs_read_csv()
shinyServer(
function(input, output, session){
colm <- reactive({
as.numeric(input$var)
})
output$crossact.map <- renderLeaflet({
##################################################################
#RADIUS SECTION
##################################################################
crossact.map <- leaflet(crossact) %>%
addTiles('http://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png')
crossact.map%>% setView(-71.43381, 42.48649, zoom = 17)
crossact.map %>% ***addCircleMarkers(~lng, ~lat, popup=~crossact$name, weight =1,
radius=~(crossact[,colm()]),
color="#ffa500", stroke = TRUE, fillOpacity = 0.6)
})
})
thanks!
For the solution to my specific problem, I used code from the superzip app, for anyone making leaflet shiny apps with markers, this seems to have it all.
http://shiny.rstudio.com/gallery/superzip-example.html (hit the Get Code button and it will send you to Github)
Correct me if I'm wrong, but, sizeBy <- input$size pull the values from the choice argument, and is the bridge to the selectInput() function. radius <- crossact[[sizeBy]] assigns the overlapping strings from the data.frame object to the selectInput() variable sizeBy by making the variable radius. For this to work, the map function must have an observer({}) wrapper to have it update itself when the selection changes.
ui.r
library(shiny)
library(leaflet)
#this is the assignment of columns to the choices argument in selectinput()
vars <- c(
"April" = "April",
"May" = "May",
"June" = "June")
shinyUI(fluidPage(
h5("Integrating Leaflet With Shiny"),
titlePanel("CAT Rider Count Map"),
sidebarLayout(
sidebarPanel(
selectInput("size", "Size", vars, selected = "April")),
mainPanel(leafletOutput('crossact.map')
))))
Server.r
library(shiny)
library(googlesheets)
library(leaflet)
#google authorization, token storage, file acquisition and assignment
gs_auth()
ttt <- gs_auth()
saveRDS(ttt, "ttt.rds")
gs_auth(token = ttt)
gs_auth(token = "ttt.rds")
crossact <- gs_title("crossact")
crossact <- crossact%>% gs_read_csv()
shinyServer(
function(input, output, session){
####observer is used to maintain the circle size.
observe({
#####this connects selectInput and assigns the radius value
sizeBy <- input$size
radius <- crossact[[sizeBy]]
output$crossact.map <- renderLeaflet({
crossact.map <- leaflet(crossact) %>%
addTiles('http://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png')
crossact.map%>% setView(-71.43381, 42.48649, zoom = 17)
crossact.map %>% addCircleMarkers(~lng, ~lat, popup=~crossact$name, weight = 1,radius = radius,
color="#ffa500", stroke = TRUE, fillOpacity = 0.6)
})
})
})

Interactive choropleth map with R Shiny and leaflet

I am trying to create a shiny app where I can select the value that I want to plot into my map. It might be that this is a very easy task but I am new in Shiny and I can't figure it out.
I don't understand whether I have to use selectInput or if leaflet has a different way to interact with Shiny.
This is my code
library(RColorBrewer)
library(rgdal)
library(shiny)
pal <- colorQuantile("YlGn", NULL, n = 5)
state_popup <- paste0("<strong>State: </strong>",
africa$COUNTRY,
"<br><strong>Resource Revenue(IMF)</strong>",
africa$Africa_r_1)
leaflet_africa <- leaflet(data = africa) %>%
addProviderTiles("CartoDB.Positron") %>%
addPolygons(fillColor = ~pal(Africa_r_1),
fillOpacity = 0.8,
color = "#BDBDC3",
weight = 1,
popup = state_popup)
ui <- fluidPage(
leafletOutput("map1")
)
server <- function(input, output, session) {
output$map1 <- renderLeaflet({
leaflet_africa
})
}
shinyApp(ui = ui, server = server)

Resources