I am building an app that displays circles for different coordinates.
If I select (Manager == Robert_ZZZ and Days == 'Wednesday') then this will show all the circles of Robert on a Wednesday. In my reproducible example below, when I select Manager == Robert_ZZZ and Days == Wednesday, I see 8 circles, which doesn't make sense. I should only see 4 circles since Robert_ZZZZ appears 4 times with different coordinates on a Wednesday. So why are the 4 extra circles showing up?
I added two radioButtons and I want to display the intersection of the different variables on my map and looked at
# Load libraries
library(dplyr)
library(shiny)
library(leaflet)
## Data
Latitude = c(33.79053,34.31533,21.44848,33.89115, 29.54777, 29.64597, 30.21765, 29.90082)
Longitude = c(-84.0348,-83.8166,-158.003, -117.295,-95.101,-95.5768,-95.341,-95.6294)
Worker = c('A','A','B','B','C','D','E','F')
Max.Distance.from.C.or.HB = c(35,55,75,100,25,15,18,17)
Manager = c('Andrew_XXXXX','Andrew_XXXXX','Andy_YYYY', 'Andy_YYYY', 'Robert_ZZZ','Robert_ZZZ','Robert_ZZZ','Robert_ZZZ')
Days = c('Tuesday','Monday','Monday','Tuesday', 'Wednesday', 'Wednesday','Wednesday','Wednesday')
coverage_data <- data.frame(Latitude,Longitude,Worker, Max.Distance.from.C.or.HB, Manager,
Days)
# Convert to miles
coverage_data <- coverage_data %>%
mutate(Radius = coverage_data$Max.Distance.from.C.or.HB * 1609.34)
# App
ui <- bootstrapPage(
tags$style(type = "text/css", "html, body {width:100%;height:100%}"),
leafletOutput("map", width = "100%", height = "100%"),
absolutePanel(bottom = 6, left = 6,
# sliderInput("range","Radius", min(coverage_data$Radius), max(coverage_data$Radius),
# value = range(coverage_data$Radius), step = 10
# ),
radioButtons(inputId = "selection_days", label = "Days:",
choices = c("Monday" = "Monday",
"Tuesday" = "Tuesday",
"Wednesday" = "Wednesday"
)),
radioButtons(inputId = "selection_manager", label = "Manager:",
choices = c("Andrew_XXXXX" = "Andrew_XXXXX",
"Andy_YYYY" = "Andy_YYYY",
"Robert_ZZZ" = "Robert_ZZZ"
))#,
# checkboxGroupInput("checkGroup", label = h3("Days"),
# choices = list("Monday" = 1, "Tuesday" = 2),
# selected = 1)
)
)
server <- function(input, output, session) {
filteredData2 <- reactive({
coverage_data[coverage_data$Days == input$selection_days
& coverage_data$Manager == input$selection_manager, ]
})
pal <- colorFactor(
palette = 'Set1', #Dark2 is another palette option
domain = coverage_data$Worker
)
output$map <- renderLeaflet({
leaflet(coverage_data) %>%
setView(lng = -95.7129, lat = 34.0902, zoom = 4.499) %>%
addProviderTiles(providers$OpenStreetMap.France) # %>%
#fitBounds(~min(Longitude),~min(Latitude), ~max(Longitude),~max(Latitude))
})
observe({
leafletProxy("map", data = filteredData2()) %>%
clearShapes() %>%
addCircles(#lng = coverage_data$Longitude,
#lat = coverage_data$Latitude,
#color = ~factpal(category),
color = ~pal(coverage_data$Worker),
weight = 1,
radius = coverage_data$Radius,
opacity = 0.5,
#label = lapply(coverage_data$label, HTML),
fillOpacity = 0.5
)
})
}
shinyApp(ui,server)
I appreciate any help correcting my logic.
Here's the change you need -
observe({
leafletProxy("map", data = filteredData2()) %>%
clearShapes() %>%
addCircles(
#lng = coverage_data$Longitude,
#lat = coverage_data$Latitude,
#color = ~factpal(category),
color = ~pal(Worker), ################### changed
weight = 1,
radius = ~Radius, ####################### changed
opacity = 0.5,
#label = lapply(coverage_data$label, HTML),
fillOpacity = 0.5
)
})
Also, leaflet(coverage_data) is not needed in output$map; simply leaflet() will do since you are not plotting anything there.
Related
I have a Shiny app with a leaflet showing ~9,000 points on a grid (each point representing a 100 m x 100 m square). The app is animated, so that each point changes colour over time. The first version of the app used addPolygons() with the setShapeStyle() function from here to allow the polygons to change colour over time, while accounting for area that each point accounts for. The polygon app was great but super slow, so I changed to addCircleMarkers instead, coupled with setCircleMarkerStyle() from the same GitHub page. This is way faster and works well, BUT I have 2 problems - 1) at low zooms, my points overlap, and 2) at high zooms, my points are separated by space.
Can anyway help me apply the same animation solutions offered by the change of style as here, but applied to addCircles() so that I can use a set radius, or a similar solution? Ideas for making the points square, so that I don't end up with empty spaces at high zooms are also welcome.
libraries and fake data:
library(plyr)
library(dplyr)
library(tidyr)
library(lubridate)
library(shiny)
library(leaflet)
library(viridisLite)
nodes <- structure(list(node = 1:9, Lon = c(-60.1760758677342, -60.1768617891598,
-60.1664512653477, -60.1672369749724, -60.1680228296767, -60.1688085769102,
-60.1695943435806, -60.170380129055, -60.1711659327049), Lat = c(43.316878317912,
43.317580709354, 43.309714197049,43.310416744826, 43.311119197611,
43.311821734546, 43.312524176034, 43.3132266121, 43.31392913277
)), row.names = c(NA, -9L), class = "data.frame")
data <- nodes %>%
crossing(Date = seq(as_date("2020-01-01"), as_date("2020-03-15"), "1 day")) %>%
mutate(Density = abs(rnorm(675, 10, 10)),
Exceed = ifelse(Density > 20, 1, 0),
Layer = paste(node, "Tile", sep = "_"))
FirstDay <- data %>%
filter(Date == min(Date))
Helper functions (based on the Github page referenced):
leafletjs <- tags$head(
tags$script(HTML('
window.LeafletWidget.methods.setStyle = function(category, layerId, style){
var map = this;
if (!layerId){
return;
} else if (!(typeof(layerId) === "object" && layerId.length)){
layerId = [layerId];
}
style = HTMLWidgets.dataframeToD3(style);
layerId.forEach(function(d,i){
var layer = map.layerManager.getLayer(category, d);
if (layer){
layer.setStyle(style[i]);
}
});
};
')))
setCircleMarkerStyle <- function(map, layerId
, radius = NULL
, stroke = NULL
, color = NULL
, weight = NULL
, opacity = NULL
, fill = NULL
, fillColor = NULL
, fillOpacity = NULL
, dashArray = NULL
, options = NULL
, data = getMapData(map)
){
options <- c(list(layerId = layerId),
options,
filterNULL(list(stroke = stroke, color = color,
weight = weight, opacity = opacity,
fill = fill, fillColor = fillColor,
fillOpacity = fillOpacity, dashArray = dashArray
)))
if (length(options) < 2) { # no style options set
return()
}
# evaluate all options
options <- evalFormula(options, data = data)
# make them the same length (by building a data.frame)
options <- do.call(data.frame, c(options, list(stringsAsFactors=FALSE)))
layerId <- options[[1]]
style <- options[-1] # drop layer column
#print(list(style=style))
leaflet::invokeMethod(map, data, "setStyle", "marker", layerId, style);
}
UI and server
ui <- fluidPage(
leafletjs,
sidebarLayout(
sidebarPanel(sliderInput("dateSel", "Date",
min = min(data$Date), max = max(data$Date),
value = min(data$Date), step = 1, timeFormat = "%d %b %y",
animate = animationOptions(interval = 100, loop = FALSE))),
mainPanel(leafletOutput("MapAnimate"))))
server <- function(input, output, session) {
filteredData <- reactive({
data %>% filter(Date == input$dateSel)
})
output$MapAnimate <- renderLeaflet({
range <- range(data$Density)
palette <- colorNumeric(palette = viridis(100), domain = range)
leaflet(FirstDay) %>%
addTiles() %>%
addCircleMarkers(lng = ~Lon, lat = ~Lat, layerId = ~Layer,
fillColor = "lightgray", fill = TRUE,
color = "white", stroke = TRUE,
fillOpacity = 1, opacity = 1, weight = 2) %>%
leaflet::addLegend(pal = palette, values = range, opacity = 0.9, position = "topleft")
})
observe({
df.in <- filteredData()
range <- range(data$Density)
palette <- colorNumeric(palette = viridis(100), domain = range)
leafletProxy("MapAnimate", data = df.in) %>%
setCircleMarkerStyle(layerId = ~Layer,
fillColor = ~palette(Density),
color = ~ifelse(Exceed == 1, "red", "white"))
})
}
shinyApp(ui = ui, server = server)
I've just created my first Shiny app and published to the Internet - https://craycrayjodie.shinyapps.io/MapApp/
When launching the app and viewing in Chrome and I.E the default page ('Map' tab) loads as expected - with the "March" data displayed on the map. This is specified in the sliderTextInput for the page.
However, when I load the app and view in Firefox (i.e. the 'Map' tab), the "March" data is not displayed on the map when the app loads by default in Firefox. I need to move the sliderTextInput, then the data loads on the map in the Browser.
This is only an issue for Firefox, the other browsers (i.e. Chrome and IE) are fine and have the March data loaded and displayed on the map when the default 'Map' page loads.
I have published my files up to GitHub - https://github.com/craycrayjodie/DataVis
Also, my app.R logic is as follows:
library(dplyr)
library(lubridate)
library(sf)
library(leaflet)
library(shinythemes)
library(RColorBrewer)
library(shinyWidgets)
library(rmapshaper)
library(rsconnect)
library(shiny)
library(ggplot2)
library(highcharter)
library(magrittr)
library(htmlwidgets)
library(RColorBrewer)
library(shinycssloaders)
###################################################################################################
myAusdata_by_month_sf = readRDS("myAusdata_by_month.rds") #load previously saved datafile
myAusdata_by_month_5 = readRDS("myAusdata_by_month_5.rds") #load previously saved datafile
areas_by_weeks = readRDS("areas_by_weeks.rds") #load previously saved datafile
# Options for Spinner
options(spinner.color="pink", spinner.type = 7, spinner.color.background="#ffffff", spinner.size=1)
ui <- shinyUI(
navbarPage(
title = "Australians Mobility Changes During COVID",
theme = shinytheme("yeti"),
tabPanel("Map",
div(class = "outer",
tags$head(
includeCSS("styles.css")
),
leafletOutput("map", width = "100%", height = "100%"),
absolutePanel(bottom = 30, left = 250, draggable = TRUE,
# slider title, step increments
sliderTextInput("choices", "Select month:", choices = unique(myAusdata_by_month_sf$month),
animate = animationOptions(interval = 1500, loop = FALSE), grid = TRUE, selected = "March", width = 400))
),
tags$div(id = "cite",
'Data downloaded from Facebook for Good by Jodie Anderson (2020).'
)
),
tabPanel("Story",
highchartOutput("timeline", height = "800px" ) %>% withSpinner(),
includeMarkdown("analysis.md"),
br()
),
tabPanel("Heatmap",
highchartOutput("heatmap", height = "100%") %>% withSpinner(),
br()
),
tabPanel("About",
includeMarkdown("about.md"),
br()
)
)
)
# Define server logic
server <- function(input, output, session) {
filteredData <- reactive({
myAusdata_by_month_sf %>%
filter(month %in% input$choices)
})
popup <- reactive({
sprintf("%s: %.1f%%", filteredData()$polygon_name, filteredData()$AvRelChange*100)
})
output$map <- renderLeaflet({
mypalette <- colorNumeric(palette = "PuOr", domain = myAusdata_by_month_sf$AvRelChange, na.color = "transparent")
leaflet(myAusdata_by_month_sf) %>%
setView(134, -29, 4) %>%
addProviderTiles("Esri.WorldGrayCanvas") %>%
addLegend(pal=mypalette, values=~AvRelChange, opacity=1, title = "Mobility Change (%)", position = "bottomleft",
labFormat = labelFormat(prefix = "(", suffix = ")", between = ", ",
transform = function(x) 100 * x))
})
observe({
mypalette <- colorNumeric(palette = "PuOr", domain = myAusdata_by_month_sf$AvRelChange, na.color = "transparent")
leafletProxy("map", data = filteredData()) %>%
clearShapes() %>%
addPolygons(fillColor = ~mypalette(AvRelChange),
stroke=TRUE,
fillOpacity = 1,
color = "grey",
weight = 0.3,
label = popup(), labelOptions = labelOptions(
style = list("font-weight" = "normal", padding = "2px 2px"),
textsize = "13px",
direction = "auto", offset = c(20, -25)))
})
output$timeline <- renderHighchart ({
hc <- myAusdata_by_month_5 %>%
hchart ('spline', hcaes(x= date, y=AvRelChange, group=NAME_1)) %>%
hc_colors(brewer.pal(8, "Dark2")) %>%
hc_title(text="Australians Mobility Changes", style=list(fontWeight="bold", fontSize="30px"),
align="left") %>%
hc_subtitle(text="During the coronavirus pandemic", style=list(fontWeight="bold"), align="left") %>%
hc_xAxis(title = list(text=NULL), plotBands = list(list(label = list(text = "Australia<br>in<br>lockdown"), color = "rgba(100, 0, 0, 0.1)",from = datetime_to_timestamp(as.Date('2020-03-16', tz = 'UTC')),
to = datetime_to_timestamp(as.Date('2020-03-31', tz = 'UTC'))))) %>%
hc_yAxis(title=list(text = "Mobility Change (%)"), showLastLabel = FALSE, labels = list(format = "{value}%")) %>%
hc_caption(text = "The Change in Mobility metric looks at how much people are moving around and compares it to a baseline period that predates most social distancing measures.<br>
The baseline period for this dataset is the four weeks of February 2020 (i.e. from the 2nd to the 29th).", useHTML = TRUE)%>%
hc_credits(text = "www.highcharts.com", href = "www.highcharts.com", enabled = TRUE, style = list(fontSize="10px")) %>%
hc_tooltip(crosshairs = TRUE, borderWidth = 2, valueSuffix = "%") %>%
hc_navigator(enabled = TRUE) %>%
hc_rangeSelector(enabled = TRUE) %>%
hc_plotOptions(series = list(marker = list(enabled = FALSE), lineWidth = 4)) %>%
hc_add_annotation(labels = list(list(point = list(xAxis = 0,yAxis = 0,x = datetime_to_timestamp(as.Date('2020-07-13', tz = 'UTC')),y = 7),shape = "rect", text = "10th July: QLD opens borders", useHTML = TRUE))) %>%
hc_add_annotation(labels = list(list(point = list(xAxis = 0,yAxis = 0,x = datetime_to_timestamp(as.Date('2020-07-20', tz = 'UTC')),y = -22),shape = "rect", text = "30th June: Vic in lockdown", useHTML = TRUE))) %>%
hc_add_annotation(labels = list(list(point = list(xAxis = 0,yAxis = 0,x = datetime_to_timestamp(as.Date('2020-08-20', tz = 'UTC')),y = -30),shape = "rect", text = "2nd Aug: Vic restrictions ease", useHTML = TRUE))) %>%
hc_add_annotation(labels = list(list(point = list(xAxis = 0,yAxis = 0,x = datetime_to_timestamp(as.Date('2020-11-14', tz = 'UTC')),y = -41),shape = "rect", text = "16th Nov: SA restrictions in place<br>21st Nov: SA restrictions lifted", useHTML = TRUE)))
hc
})
output$heatmap <- renderHighchart ({
hc1 <- areas_by_weeks %>%
hchart(type = "heatmap", hcaes(x = date, y = polygon_name, value = AvRelChange)) %>%
hc_title(text="Australians Mobility Changes", style=list(fontWeight="bold", fontSize="30px"), align="left") %>%
hc_subtitle(text="During the coronavirus pandemic", style=list(fontWeight="bold"), align="left") %>%
hc_boost(useGPUTranslations = TRUE) %>%
hc_size(height = 5000, width = 550) %>%
hc_colorAxis(labels = list(format = '{value}%'), stops = color_stops(10, rev(brewer.pal(10, "RdBu")))) %>%
hc_legend(itemMarginTop = 75, layout = "vertical", verticalAlign = "top", align = "right", valueDecimals = 0) %>%
hc_xAxis(labels = list(enabled = FALSE), tickInterval = 5, title = NULL, lineWidth = 0, tickLength = 20) %>%
hc_yAxis(title=list(text = ""), reversed = TRUE, gridLineWidth = 0) %>%
hc_tooltip(pointFormat = '{point.date} <br> {point.polygon_name}: <b>{point.value} %') %>%
hc_credits(position = list(align = 'center', x = 135, y = -4), text = "www.highcharts.com", href = "http://www.highcharts.com", enabled = TRUE, style = list(fontSize="10px")) %>%
hc_caption(align = 'center', text = "The white coloured boxes in the heatmap represent gaps in data.", useHTML = TRUE)
hc1
})
}
# Run the application
shinyApp(ui = ui, server = server)
If a clever cookie can please advise on what changes I need to make to get the app working when the page loads with Firefox, that would be fabulous :)
I'm a Rshiny newbie very eager to learn but right now I'm facing an issue I cannot overcome alone and I would greatly appreciate if someone could help me out ! :)
My problem is (I guess) quite simple:
I have created a map with my polygons and I've managed to display some basic informations when I click on them (have a look on here) but I have no idea how to add a barplot (for example) below my map for each polygon I click.
Could someone help me on how doing that please ? (after hours and hours of attempts my eyesballs are really about to pop out of their sockets !!!)
Many thanks in advance !
Romain
My code:
library(shiny)
library(leaflet)
library(dplyr)
library(magrittr)
library(devtools)
library(RColorBrewer)
library(rgdal)
library(sp)
communes <- readOGR("G:/Ateliers/Projet/communes.shp")
commmunes#data
nom_commune INSEE Variable_1 Variable_2 Variable_3 area_sqkm
1 AUZEVILLE-TOLOSANE 31035 289 8.727212 9.336384 6.979758
2 CASTANET-TOLOSAN 31113 85 4.384877 8.891650 8.460724
3 LABEGE 31254 288 5.047406 2.031651 7.663404
4 PECHBUSQUE 31411 443 6.577743 8.120896 3.099422
5 RAMONVILLE-SAINT-AGNE 31446 95 2.601305 8.909278 6.236784
>
ui <- fluidPage(
leafletOutput("mymap"))
#### SERVEUR R #####
bins <- c(3,3.5,6,6.5,7,7.5,8,8.5)
pal <- colorBin("YlOrRd", domain = communes$area_sqkm, bins = bins)
labels <- sprintf(
"<strong>%s</strong><br/>%g km2",
communes$nom_commun, communes$area_sqkm
) %>% lapply(htmltools::HTML)
server <- function(input, output, session) {
output$mymap<-renderLeaflet(
leaflet(communes) %>%
addProviderTiles(providers$Stamen.TonerLite,
options = providerTileOptions(noWrap = TRUE)
) %>%
setView(1.50, 43.54, zoom = 12) %>%
addTiles() %>%
addPolygons(fillColor = ~pal(area_sqkm),
weight = 2,
opacity = 1,
color = "white",
dashArray = "3",
fillOpacity = 0.7,
highlight = highlightOptions(
weight = 5,
color = "#666",
dashArray = "",
fillOpacity = 0.7,
bringToFront = TRUE),
label = labels,
labelOptions = labelOptions(
style = list("font-weight" = "normal", padding = "3px 8px"),
textsize = "15px",
direction = "auto")) %>%
addLegend(pal = pal, values = ~area_sqkm, opacity = 0.7, title = NULL,
position = "bottomright")
)
}
shinyApp(ui = ui, server=server)
The data I would like to display in my barplots are the variable 1,2 and 3 :
data <- read.csv("G:/Ateliers/Projet/communes.csv", sep=";")
data
nom_commune INSEE Variable_1 Variable_2 Variable_3 area_sqkm
1 AUZEVILLE-TOLOSANE 31035 289 8.727212 9.336384 6.979758
2 CASTANET-TOLOSAN 31113 85 4.384877 8.891650 8.460724
3 LABEGE 31254 288 5.047406 2.031651 7.663404
4 PECHBUSQUE 31411 443 6.577743 8.120896 3.099422
5 RAMONVILLE-SAINT-AGNE 31446 95 2.601305 8.909278 6.236784
>
Here is an example shiny app with other data, since I do not have access to your shape data for the map. I believe this might do what you need it to do and can be adapted for your needs.
I would create a reactiveVal to store the id of the polygon region that is clicked on (this variable stores input$mymap_shape_click$id). You data used in addPolygons should have an id to reference.
In your plot (or in a separate reactive expression), you can filter the data based on the reactiveVal containing the id.
library(shiny)
library(leaflet)
library(rgdal)
library(sf)
library(ggplot2)
library(tidyverse)
arcgis_data = st_read("http://data.phl.opendata.arcgis.com/datasets/bc2b2e8e356742568e43b0128c344d03_0.geojson")
arcgis_data$id <- 1:nrow(arcgis_data) ## Add an 'id' value to each shape
plot_data <- read.table(text =
"id nom_commune INSEE Variable_1 Variable_2 Variable_3 area_sqkm
1 AUZEVILLE-TOLOSANE 31035 289 8.727212 9.336384 6.979758
2 CASTANET-TOLOSAN 31113 85 4.384877 8.891650 8.460724
3 LABEGE 31254 288 5.047406 2.031651 7.663404
4 PECHBUSQUE 31411 443 6.577743 8.120896 3.099422
5 RAMONVILLE-SAINT-AGNE 31446 95 2.601305 8.909278 6.236784", header = T, stringsAsFactors = F
)
ui <- fluidPage(
leafletOutput(outputId = "mymap"),
plotOutput(outputId = "myplot")
)
server <- function(input, output){
## use reactive value to store the id from observing the shape click
rv <- reactiveVal()
output$mymap <- renderLeaflet({
leaflet() %>%
addPolygons(data = arcgis_data %>% slice(1:5), layerId = ~id) %>%
addProviderTiles("CartoDB.Positron")
})
observeEvent(input$mymap_shape_click, {
rv(input$mymap_shape_click$id)
})
## you can now plot your plot based on the id of region selected
output$myplot <- renderPlot({
plot_data %>%
filter(id == rv()) %>%
pivot_longer(cols = starts_with("Variable"), names_to = "Variable", values_to = "Value") %>%
ggplot(aes(x = Variable, y = Value)) +
geom_col()
})
}
shinyApp(ui, server)
Edit: For your uploaded data, you don't need to add a separate id for communes. Instead, you could match by name (nom_commune). You can use that in your layerId instead. This looks like it should work. I did take out some of the additional label information as this appeared to be missing from the .shp file I downloaded.
library(shiny)
library(leaflet)
library(rgdal)
library(sf)
library(ggplot2)
library(tidyverse)
communes <- readOGR("communes_ok.shp")
ui <- fluidPage(
leafletOutput(outputId = "mymap"),
plotOutput(outputId = "myplot")
)
server <- function(input, output){
## use reactive values to store the id from observing the shape click
rv <- reactiveVal()
output$mymap<-renderLeaflet(
leaflet(communes) %>%
addProviderTiles(providers$Stamen.TonerLite,
options = providerTileOptions(noWrap = TRUE)) %>%
setView(1.50, 43.54, zoom = 12) %>%
addTiles() %>%
addPolygons(fillColor = "blue",
weight = 2,
opacity = 1,
color = "white",
dashArray = "3",
fillOpacity = 0.3,
highlight = highlightOptions(
weight = 5,
color = "#666",
dashArray = "",
fillOpacity = 0.7,
bringToFront = TRUE),
layerId = ~nm_cmmn)
)
observeEvent(input$mymap_shape_click, {
rv(input$mymap_shape_click$id)
})
## you can now 'output' your generated data however you want
output$myplot <- renderPlot({
if (is.null(rv())) return (NULL)
plot_data %>%
filter(nom_commune == rv()) %>%
pivot_longer(cols = starts_with("Variable"), names_to = "Variable", values_to = "Value") %>%
ggplot(aes(x = Variable, y = Value)) +
geom_col()
})
}
shinyApp(ui, server)
My shinyApp is composed of two zone, a map and a chart.
You can select an area in the chart which will update data on the map coresponding to the selected chart area.
So the map is using an observe and a leafletProxy to add filtered Data so as a ClearMarkers() to remove previous filtered data.
The problem is : I have an other MarkersLayer part of an overlayGroup and which can be displayed by the overlayGroupWidget but it doesn't show up.
Why? Due of the ClearMarkers() which remove every markers on the map (T0New and T1New)
So I would like to remove specific layers which are T0New and MapData.
I tried removeMarker() and clearGroup() but it didn't worked out...
Any ideas?
Here is an example of my code whith sample data :
library(shiny)
library(leaflet)
library(leaflet.extras)
library(tidyverse)
library(sf)
#Create T0New data
lat <- c(49.823, 58.478, 57.478, 45.823)
lng <- c(-10.854,-10.854,2.021,2.02)
date_start_min <- c(125,135,168,149)
T0New <- data.frame(lat,lng)
#Create T1New data
lat <- c(48.956, 56.356, 57.445, 45.253)
lng <- c(-9.762,-8.884,1.971,2.17)
T1New <- data.frame(lat,lng)
ui <- fluidPage(
leafletOutput("map", height = "50vh"),
plotOutput("distribPlot", height = "47vh",
brush = brushOpts(id = "distribPlot_brush", direction = "x", resetOnNew = FALSE))
)
server <- function(input, output, session) {
#filtrer les données par attribut du graphique
filteredGraphData <- reactive({
noSelection <- TRUE
currentlyFiltered <- T0New
if(!is.null(input$distribPlot_brush)){
thisSel <- input$distribPlot_brush
currentlyFiltered <- currentlyFiltered %>%
filter(date_start_min >= thisSel$xmin, date_start_min <= thisSel$xmax)
noSelection <- FALSE
}
if(!noSelection){
return(currentlyFiltered)
}
})
#Sortie map
output$map <- renderLeaflet({
leaflet()%>%
addLayersControl(
position = "bottomright",
overlayGroups = "T1New",
options = layersControlOptions(collapsed = F)
) %>%
hideGroup("T1New") %>%
addProviderTiles(providers$CartoDB.Positron) %>%
addCircleMarkers(
lat = T0New$lat,
lng = T0New$lng,
radius = 4,
color = 'red',
stroke = FALSE,
fillOpacity = 1
)%>%
addCircleMarkers(
lat = T1New$lat,
lng = T1New$lng,
radius = 5,
color = 'blue',
stroke = FALSE,
fillOpacity = 1,
group = "T1New"
)
})
observe({
if(length(filteredGraphData()) > 1){
mapData <- filteredGraphData()
mapProxy <- leafletProxy("map", session = session, data = c(mapData, T0New))
mapProxy %>%
clearMarkers() %>%
addCircleMarkers(
data = T0New,
lat = T0New$lat,
lng = T0New$lng,
radius = 1,
color = 'black',
stroke = FALSE,
fillOpacity = 1
) %>%
addCircleMarkers(
data = mapData,
lat = mapData$lat,
lng = mapData$lng,
radius = 4,
color = 'red',
stroke = FALSE,
fillOpacity = 1
)
}else{
mapProxy <- leafletProxy("map", session = session, data = T0New)
mapProxy %>%
clearMarkers() %>%
addCircleMarkers(
radius = 4,
color = 'red',
stroke = FALSE,
fillOpacity = 1
)
}
})
#Sortie graph
output$distribPlot <- renderPlot({
distribPlot <- ggplot(T0New,aes(date_start_min)) +
geom_density(col = "#053144", fill = "#43a2ca", alpha = 0.3, adjust = 0.75)
return(distribPlot)
})
}
# Create Shiny app ----
shinyApp(ui = ui, server = server)
I finally was able to find a solution : it is in clearGroup()
I don't know why it didn't worked in the first place, her it is :
library(shiny)
library(leaflet)
library(leaflet.extras)
library(tidyverse)
library(sf)
#Create T0New data
lat <- c(49.823, 58.478, 57.478, 45.823)
lng <- c(-10.854,-10.854,2.021,2.02)
date_start_min <- c(125,135,168,149)
T0New <- data.frame(lat,lng)
#Create T1New data
lat <- c(48.956, 56.356, 57.445, 45.253)
lng <- c(-9.762,-8.884,1.971,2.17)
T1New <- data.frame(lat,lng)
ui <- fluidPage(
leafletOutput("map", height = "50vh"),
plotOutput("distribPlot", height = "47vh",
brush = brushOpts(id = "distribPlot_brush", direction = "x", resetOnNew = FALSE))
)
server <- function(input, output, session) {
#filtrer les données par attribut du graphique
filteredGraphData <- reactive({
noSelection <- TRUE
currentlyFiltered <- T0New
if(!is.null(input$distribPlot_brush)){
thisSel <- input$distribPlot_brush
currentlyFiltered <- currentlyFiltered %>%
filter(date_start_min >= thisSel$xmin, date_start_min <= thisSel$xmax)
noSelection <- FALSE
}
if(!noSelection){
return(currentlyFiltered)
}
})
#Sortie map
output$map <- renderLeaflet({
leaflet()%>%
addLayersControl(
position = "bottomright",
overlayGroups = "T1New",
options = layersControlOptions(collapsed = F)
) %>%
hideGroup("T1New") %>%
addProviderTiles(providers$CartoDB.Positron) %>%
addCircleMarkers(
lat = T0New$lat,
lng = T0New$lng,
radius = 4,
color = 'red',
stroke = FALSE,
fillOpacity = 1,
group = 'A'
)%>%
addCircleMarkers(
lat = T1New$lat,
lng = T1New$lng,
radius = 5,
color = 'blue',
stroke = FALSE,
fillOpacity = 1,
group = "T1New"
)
})
observe({
if(length(filteredGraphData()) > 1){
mapData <- filteredGraphData()
mapProxy <- leafletProxy("map", session = session, data = c(mapData, T0New))
mapProxy %>%
clearGroup('A') %>%
addCircleMarkers(
data = T0New,
lat = T0New$lat,
lng = T0New$lng,
radius = 1,
color = 'black',
stroke = FALSE,
fillOpacity = 1,
group = 'A'
) %>%
addCircleMarkers(
data = mapData,
lat = mapData$lat,
lng = mapData$lng,
radius = 4,
color = 'red',
stroke = FALSE,
fillOpacity = 1,
group = 'reactive'
)
}else{
mapProxy <- leafletProxy("map", session = session, data = T0New)
mapProxy %>%
clearGroup('A') %>%
addCircleMarkers(
radius = 4,
color = 'red',
stroke = FALSE,
fillOpacity = 1,
group = 'A'
)
}
})
#Sortie graph
output$distribPlot <- renderPlot({
distribPlot <- ggplot(T0New,aes(date_start_min)) +
geom_density(col = "#053144", fill = "#43a2ca", alpha = 0.3, adjust = 0.75)
return(distribPlot)
})
}
# Create Shiny app ----
shinyApp(ui = ui, server = server)
I added points on a map using shiny and leaflet.
Each point is a different type of transit option.
I want to distinguish the different types by color and couldn't figure this out.
Tried using "if" which doesn't work.
Thanks!
This is the basic code I have
library(leaflet)
ui <- fluidPage(
leafletOutput("map"),
headerPanel("Example"),
sidebarPanel(checkboxGroupInput(inputId = "Type", label = "Data
Layer",choices = c("Bike", "Muni", "Bus", "BART"), selected = "Bike")))
server <- function(input, output) {
output$map <- renderLeaflet({
rownumber = which(Stops_and_stations$Type == input$Type)
x <- Stops_and_stations[rownumber,]
leaflet(width = 1000, height = 500) %>%
addTiles() %>%
addCircleMarkers(lng = x$stop_lon,
lat = x$stop_lat,
radius= 3, color = '#ff6633') %>%
setView(lng = -122.4000,
lat = 37.79500,
zoom = 13)
})
}
shinyApp(ui, server)
And this is what I tried to add
.....
if(input$Type == "Bike"){
leaflet(width = 1000, height = 500) %>%
addTiles() %>%
addCircleMarkers(lng = x$stop_lon,
lat = x$stop_lat,
radius= 3, color = '#ff6633') %>%
setView(lng = -122.4000,
lat = 37.79500,
zoom = 13)
}
if(input$Type == "Muni"){
leaflet(width = 1000, height = 500) %>%
addTiles() %>%
addCircleMarkers(lng = x$stop_lon,
lat = x$stop_lat,
radius= 3, color = '#0033ff') %>%
setView(lng = -122.4000,
lat = 37.79500,
zoom = 13)
}
.....
It would be much easier to answer to your question if you provided Stops_and_stations and thus made it a reproducible example..
One approach to use distinct colors for different groups is to add a color column to your data.frame:
Since we don't know your data, I created some random dataset.
Stops_and_stations <- data.frame(
Type = rep(c("Bike", "Muni", "Bus", "BART"), each = 10),
stop_lon = -runif(40, 122.4200, 122.4500),
stop_lat = runif(40, 37.76800, 37.78900),
color = rep(c("Red", "Blue", "Green", "Yellow"), each = 10)
)
Then instead of specifying a concrete color such as #ff6633, you can use the color column.
addCircleMarkers(lng = x$stop_lon,
lat = x$stop_lat,
radius= 3, color = x$color)
I would also like to point out that your subsetting is not right: you are using checkboxGroupInput which can have more values, so you need to use the %in% operator to filter.
x <- Stops_and_stations[Stops_and_stations$Type %in% input$Type,]