Dynamically render choropleth map with sliderInput in R shiny
I have shapefile which I am reading into R using readOGR to convert it to SpatialPolygonDataframe. The attribute table looks as shown in the figure below.
Each row is a zone (postal code area) and there are values for each hour of the day eg: h_0, h_1, ...h_23 measured for each zone. In my shiny app I want to show a map which changes as the user select a particular hour using sliderInput widget. The shiny app looks like below:
The code that produces the above result is here:
library(shiny)
library(leaflet)
library(reshape2)
library(maps)
library(mapproj)
library(rgdal)
library(RColorBrewer)
library(sp)
library(rgeos)
ui <- fluidPage(
titlePanel("Title"),
sidebarLayout(
sidebarPanel(
tabsetPanel(id= "tabs",
tabPanel("Map", id = "Map",
br(),
p("Choose options below to interact with the Map"),
sliderInput("hour", "Select the hours", min = 0 , max = 23,
value = 7, step = 1, dragRange= TRUE)
)
)
),
mainPanel(
tabsetPanel(type= "tabs",
tabPanel("Map", leafletOutput(outputId = "map"))
)
)
)
)
server <- function(input, output) {
layer <- reactive( {
shp = readOGR("shp",layer = "attractiveness_day3")
shp_p <- spTransform(shp, CRS("+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"))
})
output$map <- renderLeaflet({
bins<- c(0, 2000, 4000, 8000, 16000, Inf)
pal <- colorBin("YlOrRd", domain = layer()$h_7, bins = bins)
leaflet(layer()) %>%
setView(13.4, 52.5, 9) %>%
addTiles()%>%
addPolygons(
fillColor = ~pal(h_7),
weight = 0.0,
opacity = 1,
color = "white",
dashArray = "3",
fillOpacity = 0.7
) %>%
addLegend(pal = pal, values = ~h_7, opacity = 0.7, title = NULL, position = "bottomright")
})
#until here it works but onwards not.
observe(leafletProxy("map", layer())%>%
clearShapes()%>%
addPolygons(
fillColor = ~pal(h_7), # is it possible here to pass column name dynamically
weight = 0.0,
opacity = 1,
color = "white",
dashArray = "3",
fillOpacity = 0.7
) %>%
addLegend(pal = pal, values = ~h_7, opacity = 0.7, title = NULL, position = "bottomright")
)
}
shinyApp(ui, server)
So currently the choropleth map is populated with values of column h_7
selected statically. But I don't know how and whether I can dynamically pass the column name based on sliderInput selection ( For eg. If sliderInput value is 8 the corresponding column is h_8). And then render the map based on the selected column passed from reactive funnction to the observe
and leafletProxy
functions.
sample data : sample data
r shiny leaflet
add a comment |
I have shapefile which I am reading into R using readOGR to convert it to SpatialPolygonDataframe. The attribute table looks as shown in the figure below.
Each row is a zone (postal code area) and there are values for each hour of the day eg: h_0, h_1, ...h_23 measured for each zone. In my shiny app I want to show a map which changes as the user select a particular hour using sliderInput widget. The shiny app looks like below:
The code that produces the above result is here:
library(shiny)
library(leaflet)
library(reshape2)
library(maps)
library(mapproj)
library(rgdal)
library(RColorBrewer)
library(sp)
library(rgeos)
ui <- fluidPage(
titlePanel("Title"),
sidebarLayout(
sidebarPanel(
tabsetPanel(id= "tabs",
tabPanel("Map", id = "Map",
br(),
p("Choose options below to interact with the Map"),
sliderInput("hour", "Select the hours", min = 0 , max = 23,
value = 7, step = 1, dragRange= TRUE)
)
)
),
mainPanel(
tabsetPanel(type= "tabs",
tabPanel("Map", leafletOutput(outputId = "map"))
)
)
)
)
server <- function(input, output) {
layer <- reactive( {
shp = readOGR("shp",layer = "attractiveness_day3")
shp_p <- spTransform(shp, CRS("+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"))
})
output$map <- renderLeaflet({
bins<- c(0, 2000, 4000, 8000, 16000, Inf)
pal <- colorBin("YlOrRd", domain = layer()$h_7, bins = bins)
leaflet(layer()) %>%
setView(13.4, 52.5, 9) %>%
addTiles()%>%
addPolygons(
fillColor = ~pal(h_7),
weight = 0.0,
opacity = 1,
color = "white",
dashArray = "3",
fillOpacity = 0.7
) %>%
addLegend(pal = pal, values = ~h_7, opacity = 0.7, title = NULL, position = "bottomright")
})
#until here it works but onwards not.
observe(leafletProxy("map", layer())%>%
clearShapes()%>%
addPolygons(
fillColor = ~pal(h_7), # is it possible here to pass column name dynamically
weight = 0.0,
opacity = 1,
color = "white",
dashArray = "3",
fillOpacity = 0.7
) %>%
addLegend(pal = pal, values = ~h_7, opacity = 0.7, title = NULL, position = "bottomright")
)
}
shinyApp(ui, server)
So currently the choropleth map is populated with values of column h_7
selected statically. But I don't know how and whether I can dynamically pass the column name based on sliderInput selection ( For eg. If sliderInput value is 8 the corresponding column is h_8). And then render the map based on the selected column passed from reactive funnction to the observe
and leafletProxy
functions.
sample data : sample data
r shiny leaflet
add a comment |
I have shapefile which I am reading into R using readOGR to convert it to SpatialPolygonDataframe. The attribute table looks as shown in the figure below.
Each row is a zone (postal code area) and there are values for each hour of the day eg: h_0, h_1, ...h_23 measured for each zone. In my shiny app I want to show a map which changes as the user select a particular hour using sliderInput widget. The shiny app looks like below:
The code that produces the above result is here:
library(shiny)
library(leaflet)
library(reshape2)
library(maps)
library(mapproj)
library(rgdal)
library(RColorBrewer)
library(sp)
library(rgeos)
ui <- fluidPage(
titlePanel("Title"),
sidebarLayout(
sidebarPanel(
tabsetPanel(id= "tabs",
tabPanel("Map", id = "Map",
br(),
p("Choose options below to interact with the Map"),
sliderInput("hour", "Select the hours", min = 0 , max = 23,
value = 7, step = 1, dragRange= TRUE)
)
)
),
mainPanel(
tabsetPanel(type= "tabs",
tabPanel("Map", leafletOutput(outputId = "map"))
)
)
)
)
server <- function(input, output) {
layer <- reactive( {
shp = readOGR("shp",layer = "attractiveness_day3")
shp_p <- spTransform(shp, CRS("+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"))
})
output$map <- renderLeaflet({
bins<- c(0, 2000, 4000, 8000, 16000, Inf)
pal <- colorBin("YlOrRd", domain = layer()$h_7, bins = bins)
leaflet(layer()) %>%
setView(13.4, 52.5, 9) %>%
addTiles()%>%
addPolygons(
fillColor = ~pal(h_7),
weight = 0.0,
opacity = 1,
color = "white",
dashArray = "3",
fillOpacity = 0.7
) %>%
addLegend(pal = pal, values = ~h_7, opacity = 0.7, title = NULL, position = "bottomright")
})
#until here it works but onwards not.
observe(leafletProxy("map", layer())%>%
clearShapes()%>%
addPolygons(
fillColor = ~pal(h_7), # is it possible here to pass column name dynamically
weight = 0.0,
opacity = 1,
color = "white",
dashArray = "3",
fillOpacity = 0.7
) %>%
addLegend(pal = pal, values = ~h_7, opacity = 0.7, title = NULL, position = "bottomright")
)
}
shinyApp(ui, server)
So currently the choropleth map is populated with values of column h_7
selected statically. But I don't know how and whether I can dynamically pass the column name based on sliderInput selection ( For eg. If sliderInput value is 8 the corresponding column is h_8). And then render the map based on the selected column passed from reactive funnction to the observe
and leafletProxy
functions.
sample data : sample data
r shiny leaflet
I have shapefile which I am reading into R using readOGR to convert it to SpatialPolygonDataframe. The attribute table looks as shown in the figure below.
Each row is a zone (postal code area) and there are values for each hour of the day eg: h_0, h_1, ...h_23 measured for each zone. In my shiny app I want to show a map which changes as the user select a particular hour using sliderInput widget. The shiny app looks like below:
The code that produces the above result is here:
library(shiny)
library(leaflet)
library(reshape2)
library(maps)
library(mapproj)
library(rgdal)
library(RColorBrewer)
library(sp)
library(rgeos)
ui <- fluidPage(
titlePanel("Title"),
sidebarLayout(
sidebarPanel(
tabsetPanel(id= "tabs",
tabPanel("Map", id = "Map",
br(),
p("Choose options below to interact with the Map"),
sliderInput("hour", "Select the hours", min = 0 , max = 23,
value = 7, step = 1, dragRange= TRUE)
)
)
),
mainPanel(
tabsetPanel(type= "tabs",
tabPanel("Map", leafletOutput(outputId = "map"))
)
)
)
)
server <- function(input, output) {
layer <- reactive( {
shp = readOGR("shp",layer = "attractiveness_day3")
shp_p <- spTransform(shp, CRS("+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"))
})
output$map <- renderLeaflet({
bins<- c(0, 2000, 4000, 8000, 16000, Inf)
pal <- colorBin("YlOrRd", domain = layer()$h_7, bins = bins)
leaflet(layer()) %>%
setView(13.4, 52.5, 9) %>%
addTiles()%>%
addPolygons(
fillColor = ~pal(h_7),
weight = 0.0,
opacity = 1,
color = "white",
dashArray = "3",
fillOpacity = 0.7
) %>%
addLegend(pal = pal, values = ~h_7, opacity = 0.7, title = NULL, position = "bottomright")
})
#until here it works but onwards not.
observe(leafletProxy("map", layer())%>%
clearShapes()%>%
addPolygons(
fillColor = ~pal(h_7), # is it possible here to pass column name dynamically
weight = 0.0,
opacity = 1,
color = "white",
dashArray = "3",
fillOpacity = 0.7
) %>%
addLegend(pal = pal, values = ~h_7, opacity = 0.7, title = NULL, position = "bottomright")
)
}
shinyApp(ui, server)
So currently the choropleth map is populated with values of column h_7
selected statically. But I don't know how and whether I can dynamically pass the column name based on sliderInput selection ( For eg. If sliderInput value is 8 the corresponding column is h_8). And then render the map based on the selected column passed from reactive funnction to the observe
and leafletProxy
functions.
sample data : sample data
r shiny leaflet
r shiny leaflet
edited Nov 26 '18 at 15:09
Jio
asked Nov 26 '18 at 12:14
JioJio
2041514
2041514
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
It is possible to pass the column names as a string. In leafletProxy
you can link to your column values with dataset[[column_name]]
. With a single square bracket you are not only selecting the values, but also the corresponding polygons.
For your app to work you need to call layer()
outside the leafletProxy
function. In addition, use clearControls()
to remove duplicate legends.
Finally, I am not sure why you put your shapefile in a reactive
expression. It wil also work if you just add it as a variable in your server
.
observeEvent({input$hour},{
hour_column <- paste0('h_',input$hour)
data = layer()[hour_column]
pal <- colorBin("YlOrRd", domain = as.numeric(data[[hour_column]]), bins = bins)
leafletProxy("map", data=data)%>%
clearShapes()%>%
addPolygons(
fillColor = pal(as.numeric(data[[hour_column]])),
weight = 0.0,
opacity = 1,
color = "white",
dashArray = "3",
fillOpacity = 0.7
) %>% clearControls() %>%
addLegend(pal = pal, values =as.numeric(data[[hour_column]]), opacity = 0.7, title = NULL, position = "bottomright")
})
Hi Wilmar, it gives: Error in sess$onFlushed: attempt to apply non-function. any idea ?
– Jio
Nov 26 '18 at 14:56
Please add a sample of your shapefile and I can help you. Or add a random shapefile with the same columnnames
– Wilmar van Ommeren
Nov 26 '18 at 14:59
I have added a dropbox link to the sample data. Could you try with it ?
– Jio
Nov 26 '18 at 15:10
I edited the answer. It should work now!
– Wilmar van Ommeren
Nov 26 '18 at 15:24
It works now. Thanks for your help!
– Jio
Nov 26 '18 at 16:01
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53480924%2fdynamically-render-choropleth-map-with-sliderinput-in-r-shiny%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
It is possible to pass the column names as a string. In leafletProxy
you can link to your column values with dataset[[column_name]]
. With a single square bracket you are not only selecting the values, but also the corresponding polygons.
For your app to work you need to call layer()
outside the leafletProxy
function. In addition, use clearControls()
to remove duplicate legends.
Finally, I am not sure why you put your shapefile in a reactive
expression. It wil also work if you just add it as a variable in your server
.
observeEvent({input$hour},{
hour_column <- paste0('h_',input$hour)
data = layer()[hour_column]
pal <- colorBin("YlOrRd", domain = as.numeric(data[[hour_column]]), bins = bins)
leafletProxy("map", data=data)%>%
clearShapes()%>%
addPolygons(
fillColor = pal(as.numeric(data[[hour_column]])),
weight = 0.0,
opacity = 1,
color = "white",
dashArray = "3",
fillOpacity = 0.7
) %>% clearControls() %>%
addLegend(pal = pal, values =as.numeric(data[[hour_column]]), opacity = 0.7, title = NULL, position = "bottomright")
})
Hi Wilmar, it gives: Error in sess$onFlushed: attempt to apply non-function. any idea ?
– Jio
Nov 26 '18 at 14:56
Please add a sample of your shapefile and I can help you. Or add a random shapefile with the same columnnames
– Wilmar van Ommeren
Nov 26 '18 at 14:59
I have added a dropbox link to the sample data. Could you try with it ?
– Jio
Nov 26 '18 at 15:10
I edited the answer. It should work now!
– Wilmar van Ommeren
Nov 26 '18 at 15:24
It works now. Thanks for your help!
– Jio
Nov 26 '18 at 16:01
add a comment |
It is possible to pass the column names as a string. In leafletProxy
you can link to your column values with dataset[[column_name]]
. With a single square bracket you are not only selecting the values, but also the corresponding polygons.
For your app to work you need to call layer()
outside the leafletProxy
function. In addition, use clearControls()
to remove duplicate legends.
Finally, I am not sure why you put your shapefile in a reactive
expression. It wil also work if you just add it as a variable in your server
.
observeEvent({input$hour},{
hour_column <- paste0('h_',input$hour)
data = layer()[hour_column]
pal <- colorBin("YlOrRd", domain = as.numeric(data[[hour_column]]), bins = bins)
leafletProxy("map", data=data)%>%
clearShapes()%>%
addPolygons(
fillColor = pal(as.numeric(data[[hour_column]])),
weight = 0.0,
opacity = 1,
color = "white",
dashArray = "3",
fillOpacity = 0.7
) %>% clearControls() %>%
addLegend(pal = pal, values =as.numeric(data[[hour_column]]), opacity = 0.7, title = NULL, position = "bottomright")
})
Hi Wilmar, it gives: Error in sess$onFlushed: attempt to apply non-function. any idea ?
– Jio
Nov 26 '18 at 14:56
Please add a sample of your shapefile and I can help you. Or add a random shapefile with the same columnnames
– Wilmar van Ommeren
Nov 26 '18 at 14:59
I have added a dropbox link to the sample data. Could you try with it ?
– Jio
Nov 26 '18 at 15:10
I edited the answer. It should work now!
– Wilmar van Ommeren
Nov 26 '18 at 15:24
It works now. Thanks for your help!
– Jio
Nov 26 '18 at 16:01
add a comment |
It is possible to pass the column names as a string. In leafletProxy
you can link to your column values with dataset[[column_name]]
. With a single square bracket you are not only selecting the values, but also the corresponding polygons.
For your app to work you need to call layer()
outside the leafletProxy
function. In addition, use clearControls()
to remove duplicate legends.
Finally, I am not sure why you put your shapefile in a reactive
expression. It wil also work if you just add it as a variable in your server
.
observeEvent({input$hour},{
hour_column <- paste0('h_',input$hour)
data = layer()[hour_column]
pal <- colorBin("YlOrRd", domain = as.numeric(data[[hour_column]]), bins = bins)
leafletProxy("map", data=data)%>%
clearShapes()%>%
addPolygons(
fillColor = pal(as.numeric(data[[hour_column]])),
weight = 0.0,
opacity = 1,
color = "white",
dashArray = "3",
fillOpacity = 0.7
) %>% clearControls() %>%
addLegend(pal = pal, values =as.numeric(data[[hour_column]]), opacity = 0.7, title = NULL, position = "bottomright")
})
It is possible to pass the column names as a string. In leafletProxy
you can link to your column values with dataset[[column_name]]
. With a single square bracket you are not only selecting the values, but also the corresponding polygons.
For your app to work you need to call layer()
outside the leafletProxy
function. In addition, use clearControls()
to remove duplicate legends.
Finally, I am not sure why you put your shapefile in a reactive
expression. It wil also work if you just add it as a variable in your server
.
observeEvent({input$hour},{
hour_column <- paste0('h_',input$hour)
data = layer()[hour_column]
pal <- colorBin("YlOrRd", domain = as.numeric(data[[hour_column]]), bins = bins)
leafletProxy("map", data=data)%>%
clearShapes()%>%
addPolygons(
fillColor = pal(as.numeric(data[[hour_column]])),
weight = 0.0,
opacity = 1,
color = "white",
dashArray = "3",
fillOpacity = 0.7
) %>% clearControls() %>%
addLegend(pal = pal, values =as.numeric(data[[hour_column]]), opacity = 0.7, title = NULL, position = "bottomright")
})
edited Nov 26 '18 at 15:32
answered Nov 26 '18 at 13:18
Wilmar van OmmerenWilmar van Ommeren
2,75521640
2,75521640
Hi Wilmar, it gives: Error in sess$onFlushed: attempt to apply non-function. any idea ?
– Jio
Nov 26 '18 at 14:56
Please add a sample of your shapefile and I can help you. Or add a random shapefile with the same columnnames
– Wilmar van Ommeren
Nov 26 '18 at 14:59
I have added a dropbox link to the sample data. Could you try with it ?
– Jio
Nov 26 '18 at 15:10
I edited the answer. It should work now!
– Wilmar van Ommeren
Nov 26 '18 at 15:24
It works now. Thanks for your help!
– Jio
Nov 26 '18 at 16:01
add a comment |
Hi Wilmar, it gives: Error in sess$onFlushed: attempt to apply non-function. any idea ?
– Jio
Nov 26 '18 at 14:56
Please add a sample of your shapefile and I can help you. Or add a random shapefile with the same columnnames
– Wilmar van Ommeren
Nov 26 '18 at 14:59
I have added a dropbox link to the sample data. Could you try with it ?
– Jio
Nov 26 '18 at 15:10
I edited the answer. It should work now!
– Wilmar van Ommeren
Nov 26 '18 at 15:24
It works now. Thanks for your help!
– Jio
Nov 26 '18 at 16:01
Hi Wilmar, it gives: Error in sess$onFlushed: attempt to apply non-function. any idea ?
– Jio
Nov 26 '18 at 14:56
Hi Wilmar, it gives: Error in sess$onFlushed: attempt to apply non-function. any idea ?
– Jio
Nov 26 '18 at 14:56
Please add a sample of your shapefile and I can help you. Or add a random shapefile with the same columnnames
– Wilmar van Ommeren
Nov 26 '18 at 14:59
Please add a sample of your shapefile and I can help you. Or add a random shapefile with the same columnnames
– Wilmar van Ommeren
Nov 26 '18 at 14:59
I have added a dropbox link to the sample data. Could you try with it ?
– Jio
Nov 26 '18 at 15:10
I have added a dropbox link to the sample data. Could you try with it ?
– Jio
Nov 26 '18 at 15:10
I edited the answer. It should work now!
– Wilmar van Ommeren
Nov 26 '18 at 15:24
I edited the answer. It should work now!
– Wilmar van Ommeren
Nov 26 '18 at 15:24
It works now. Thanks for your help!
– Jio
Nov 26 '18 at 16:01
It works now. Thanks for your help!
– Jio
Nov 26 '18 at 16:01
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53480924%2fdynamically-render-choropleth-map-with-sliderinput-in-r-shiny%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown