<p><div><div><div><div data-width="100" data-show-faces="false" data-send="true" data-layout="button_count" data-height="21" data-href="https://www.r-bloggers.com/4-tricks-for-working-with-r-leaflet-and-shiny/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://www.r-graph-gallery.com/2017/03/14/4-tricks-for-working-with-r-leaflet-and-shiny/"> Blog – The R graph Gallery</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p><img class="wp-image-3193" src="https://i1.wp.com/www.r-graph-gallery.com/wp-content/uploads/2017/02/leaflet_tip2.gif?w=450" data-recalc-dims="1"></p>
<p>I recently worked on a dataviz project involving <a target="_blank" rel="nofollow" href="https://shiny.rstudio.com/">Shiny</a> and the <a target="_blank" rel="nofollow" href="http://www.r-graph-gallery.com/portfolio/maps/">Leaflet</a> library. In this post I give <strong>4 handy tricks</strong> we used to improve the app: 1/ how to use <strong>leaflet native widgets</strong> 2/ how to trigger an <strong>action</strong> <strong>when user clicks</strong> on map 3/ how to add a <strong>research bar</strong> on your map 4/ how to propose a <strong>“geolocalize me”</strong> button. For each trick, a <strong>reproducible code</strong> snippet is provided, so you just have to copy and paste it to reproduce the image.</p>
<p><span><strong>Trick 1: use leaflet native control widget</strong></span></p>
<p><span></span></p>
<p>Shiny is used to add <strong>interactivity</strong> to your dataviz. Working on maps, it’s great to add a widget to allow users to switch between datasets, using one layer or another… Of course, this can be achieved using a regular RadioButton or any other shiny widget, building a new map each time.</p>
<p>But Leaflet enables you to build the control widget directly while doing the map. Every layer you create must be added to the same map, all attributed to a “<strong>group</strong>“. Then, the control widget will allow you to switch from one group to another. The code below should help you understand the concept, and everything is explained in more detail on the <a target="_blank" rel="nofollow" href="https://rstudio.github.io/leaflet/showhide.html">amazing Rstudio tutorial</a>.</p>
<p><img class="wp-image-3192" src="https://i1.wp.com/www.r-graph-gallery.com/wp-content/uploads/2017/02/leaflet_tip1.gif?w=450" data-recalc-dims="1"></p>
<p><span><strong>Trick 2: make a graph depending on click position<br>
</strong></span></p>
<p>It is possible to code the map so that clicking on a certain point opens particular information. In this example, the user chooses a marker on the map, which makes either a <a target="_blank" rel="nofollow" href="http://www.r-graph-gallery.com/portfolio/barplot/">barplot</a> OR a <a target="_blank" rel="nofollow" href="http://www.r-graph-gallery.com/portfolio/scatter-plot/">scatterplot</a>. By adding an ID to every marker of the map, using the<strong> layerId</strong> argument, the click information is saved in a <strong>reactive</strong> value than can be used to run specific functions!</p>
<p><img class="wp-image-3193" src="https://i1.wp.com/www.r-graph-gallery.com/wp-content/uploads/2017/02/leaflet_tip2.gif?w=450" data-recalc-dims="1"></p>
<p><span><strong>Trick 3: add a search bar<br>
</strong></span></p>
<p>The<a target="_blank" rel="nofollow" href="https://cran.r-project.org/web/packages/ggmap/ggmap.pdf"> ggmap library</a> allows you to get the coordinates of any place in the world based on a google search. You can use this feature to create a <strong>search bar</strong> in addition to the leaflet map! The <strong>textInput</strong> is passed to the <strong>geocode</strong> function of ggmap. It returns <strong>coordinates</strong> that are given to leaflet to zoom on the map.</p>
<p><img class="wp-image-3194" src="https://i2.wp.com/www.r-graph-gallery.com/wp-content/uploads/2017/02/leaflet_tip3.gif?w=450" data-recalc-dims="1"></p>
<p><span><strong>Trick 4: use geolocalization<br>
</strong></span></p>
<p>When the user clicks on the “localize me” button, the leaflet map automatically zooms to the user’s position. This trick uses a Javascript function (but no Javascript knowledge needed). This example is inspired from <a target="_blank" rel="nofollow" href="https://github.com/AugustT/shiny_geolocation">here</a>.</p>
<p><img class="wp-image-3208" src="https://i2.wp.com/www.r-graph-gallery.com/wp-content/uploads/2017/03/leaflet_tip4.gif?w=450" data-recalc-dims="1"></p>
<p> </p>
<p>This post has been first published on <a target="_blank" rel="nofollow" href="http://www.r-graph-gallery.com/">the R graph gallery</a>, a website that displays hundreds of R charts, always with the reproducible code! You can follow the gallery on Twitter: <a target="_blank" rel="nofollow" href="https://twitter.com/R_Graph_Gallery?lang=fr">@R_Graph_Gallery</a></p>
<p><span><strong>Code | Trick1 | Widget</strong></span></p>
<hr>
<pre># Load libraries
library(shiny)
library(leaflet)

# Make data with several positions
data_red=data.frame(LONG=42+rnorm(10), LAT=23+rnorm(10), PLACE=paste(&quot;Red_place_&quot;,seq(1,10)))
data_blue=data.frame(LONG=42+rnorm(10), LAT=23+rnorm(10), PLACE=paste(&quot;Blue_place_&quot;,seq(1,10)))
    
# Initialize the leaflet map:
leaflet() %>% 
setView(lng=42, lat=23, zoom=8 ) %>%

# Add two tiles
addProviderTiles(&quot;Esri.WorldImagery&quot;, group=&quot;background 1&quot;) %>%
addTiles(options = providerTileOptions(noWrap = TRUE), group=&quot;background 2&quot;) %>%

# Add 2 marker groups
addCircleMarkers(data=data_red, lng=~LONG , lat=~LAT, radius=8 , color=&quot;black&quot;,  fillColor=&quot;red&quot;, stroke = TRUE, fillOpacity = 0.8, group=&quot;Red&quot;) %>%
addCircleMarkers(data=data_blue, lng=~LONG , lat=~LAT, radius=8 , color=&quot;black&quot;,  fillColor=&quot;blue&quot;, stroke = TRUE, fillOpacity = 0.8, group=&quot;Blue&quot;) %>%

# Add the control widget
addLayersControl(overlayGroups = c(&quot;Red&quot;,&quot;Blue&quot;) , baseGroups = c(&quot;background 1&quot;,&quot;background 2&quot;), options = layersControlOptions(collapsed = FALSE))</pre>
<p> </p>
<p><span><strong>Code | Trick2 | Graph depends on click<br>
</strong></span></p>
<hr>
<pre>library(shiny)
library(leaflet)

server &lt;- function(input, output) {
    
    # build data with 2 places
    data=data.frame(x=c(130, 128), y=c(-22,-26), id=c(&quot;place1&quot;, &quot;place2&quot;))
    
    # create a reactive value that will store the click position
    data_of_click &lt;- reactiveValues(clickedMarker=NULL)

    # Leaflet map with 2 markers
    output$map &lt;- renderLeaflet({
        leaflet() %>% 
          setView(lng=131 , lat =-25, zoom=4) %>%
          addTiles(options = providerTileOptions(noWrap = TRUE)) %>%
          addCircleMarkers(data=data, ~x , ~y, layerId=~id, popup=~id, radius=8 , color=&quot;black&quot;,  fillColor=&quot;red&quot;, stroke = TRUE, fillOpacity = 0.8)
    })

    # store the click
    observeEvent(input$map_marker_click,{
        data_of_click$clickedMarker &lt;- input$map_marker_click
    })
    
    # Make a barplot or scatterplot depending of the selected point
    output$plot=renderPlot({
        my_place=data_of_click$clickedMarker$id
        if(is.null(my_place)){my_place=&quot;place1&quot;}
        if(my_place==&quot;place1&quot;){
            plot(rnorm(1000), col=rgb(0.9,0.4,0.1,0.3), cex=3, pch=20)
        }else{
            barplot(rnorm(10), col=rgb(0.1,0.4,0.9,0.3))
        }    
    })
}


ui &lt;- fluidPage(
    br(),
    column(8,leafletOutput(&quot;map&quot;, height=&quot;600px&quot;)),
    column(4,br(),br(),br(),br(),plotOutput(&quot;plot&quot;, height=&quot;300px&quot;)),
    br()
)

shinyApp(ui = ui, server = server)</pre>
<p><span><strong>Code | Trick3 | Search Bar<br>
</strong></span></p>
<hr>
<pre>library(shiny)
library(leaflet)
library(ggmap)

server &lt;- function(input, output) {

    output$map &lt;- renderLeaflet({
    
        # Get latitude and longitude
        if(input$target_zone==&quot;Ex: Bamako&quot;){
            ZOOM=2
            LAT=0
            LONG=0
        }else{
            target_pos=geocode(input$target_zone)
            LAT=target_pos$lat
            LONG=target_pos$lon
            ZOOM=12
        }

        # Plot it!
        leaflet() %>% 
          setView(lng=LONG, lat=LAT, zoom=ZOOM ) %>%
        addProviderTiles(&quot;Esri.WorldImagery&quot;)
    })
}


ui &lt;- fluidPage(
    br(),
    leafletOutput(&quot;map&quot;, height=&quot;600px&quot;),
    absolutePanel(top=20, left=70, textInput(&quot;target_zone&quot;, &quot;&quot; , &quot;Ex: Bamako&quot;)),
    br()
)

shinyApp(ui = ui, server = server)</pre>
<p><span><strong>Code | Trick4 | Geolocalization<br>
</strong></span></p>
<hr>
<pre># ==== libraries
library(shiny)
library(leaflet)
library(shinyjs)

# ==== fonction allowing geolocalisation
jsCode &lt;- '
shinyjs.geoloc = function() {
    navigator.geolocation.getCurrentPosition(onSuccess, onError);
    function onError (err) {
        Shiny.onInputChange(&quot;geolocation&quot;, false);
    }
    function onSuccess (position) {
        setTimeout(function () {
            var coords = position.coords;
            console.log(coords.latitude + &quot;, &quot; + coords.longitude);
            Shiny.onInputChange(&quot;geolocation&quot;, true);
            Shiny.onInputChange(&quot;lat&quot;, coords.latitude);
            Shiny.onInputChange(&quot;long&quot;, coords.longitude);
        }, 5)
    }
};
'


# ==== server
server &lt;- function(input, output) {

    # Basic map 
    output$map &lt;- renderLeaflet({
        leaflet() %>% 
          setView(lng=0, lat=0, zoom=2 ) %>%
        addProviderTiles(&quot;Esri.WorldImagery&quot;)
    })
    
    # Find geolocalisation coordinates when user clicks
    observeEvent(input$geoloc, {
        js$geoloc()
    })


    # zoom on the corresponding area
    observe({
        if(!is.null(input$lat)){
            map &lt;- leafletProxy(&quot;map&quot;)
            dist &lt;- 0.2
            lat &lt;- input$lat
            lng &lt;- input$long
            map %>% fitBounds(lng - dist, lat - dist, lng + dist, lat + dist)
        }
     })
}



# ==== UI
ui &lt;- fluidPage(
    
    # Tell shiny we will use some Javascript
    useShinyjs(),
    extendShinyjs(text = jsCode),

    # One button and one map
    br(),
    actionButton(&quot;geoloc&quot;, &quot;Localize me&quot;, class=&quot;btn btn-primary&quot;, onClick=&quot;shinyjs.geoloc()&quot;),
    leafletOutput(&quot;map&quot;, height=&quot;600px&quot;)
)

shinyApp(ui = ui, server = server)</pre>

<p><a title="Recommend this" target="_blank" rel="nofollow" href="http://www.r-graph-gallery.com/2017/03/14/4-tricks-for-working-with-r-leaflet-and-shiny/#"><span>1</span> <span></span></a></p>
<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://www.r-graph-gallery.com/2017/03/14/4-tricks-for-working-with-r-leaflet-and-shiny/"> Blog – The R graph Gallery</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" rel="nofollow" href="https://www.r-project.org/">R</a> news and <a title="R tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="https://www.r-bloggers.com/search/data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data">Big Data, <a title="R jobs" rel="nofollow" href="https://www.r-users.com/">R jobs</a>, visualization (<a title="ggplot and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="https://www.r-bloggers.com/search/map">maps</a>, <a title="Animation in R" rel="nofollow" href="https://www.r-bloggers.com/search/animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="https://www.r-bloggers.com/search/sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="https://www.r-bloggers.com/search/SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="https://www.r-bloggers.com/search/git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="https://www.r-bloggers.com/search/hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="https://www.r-bloggers.com/search/PCA">PCA</a>, <a title="Time series" rel="nofollow" href="https://www.r-bloggers.com/search/time+series">time series</a>, <a title="finance trading" rel="nofollow" href="https://www.r-bloggers.com/search/trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/tW1r7GJxK_8"></a></div>