{"id":1740,"date":"2015-11-07T11:10:26","date_gmt":"2015-11-07T10:10:26","guid":{"rendered":"http:\/\/pzd.hmy.temporary.site\/?p=1740"},"modified":"2017-04-28T18:24:51","modified_gmt":"2017-04-28T22:24:51","slug":"building-interactive-maps-with-leaflet","status":"publish","type":"post","link":"https:\/\/datascienceplus.com\/building-interactive-maps-with-leaflet\/","title":{"rendered":"Building Interactive Maps with Leaflet"},"content":{"rendered":"<p><a href=\"http:\/\/leafletjs.com\/\" target=\"_blank\">Leaflet<\/a> is an JavaScript library for building interactive maps. <a href=\"https:\/\/rstudio.github.io\/leaflet\/\" target=\"_blank\">RStudio<\/a> released a package that allows us to build these maps in R! You can do some really cool things in Leaflet, and I will demonstrate a few of those below. Leaflet is compatible with Shiny apps and R Markdown documents.<\/p>\n<p>As mentioned on the RStudio page, the basic steps to create a Leaflet map are:<\/p>\n<blockquote><p>1. Create a map widget using <code>leaflet()<\/code><br \/>\n\t2. Add layers to the map using <code>addTiles()<\/code>, <code>addMarkers()<\/code>, etc.<br \/>\n\t3. Print the map.\n<\/p><\/blockquote>\n<p>Okay, let&#8217;s get started. We will need the <code>leaflet<\/code> and <code>magrittr<\/code> packages for this. <\/p>\n<p>Let&#8217;s create a basic map centered at San Francisco. First, we create a widget by calling <code>leaflet()<\/code>. Then, we add tiles to the map using <code>addTiles()<\/code>. By default, it uses <a href=\"http:\/\/www.openstreetmap.org\" target=\"_blank\">Open Street Map<\/a> tiles. If you would like to use other tiles, please refer <a href=\"https:\/\/rstudio.github.io\/leaflet\/basemaps.html\" target=\"_blank\">here<\/a>. We can set the desired longitude and latitude that we want the map to be centered at, and also set the zoom level using the <code>setView()<\/code> function. The <code>addMarker()<\/code> function allows us to add a marker at our desired location, with it&#8217;s own popup message!<\/p>\n<pre>\r\nlibrary(leaflet)\r\nlibrary(magrittr)\r\n\r\nSFmap &lt;- leaflet() %&gt;% \r\n  addTiles() %&gt;% \r\n  setView(-122.42, 37.78, zoom = 13) %&gt;% \r\n  addMarkers(-122.42, 37.78, popup = 'Bay Area')\r\nSFmap<\/pre>\n<p>This gives the following map:<br \/>\n<a href=\"https:\/\/datascienceplus.com\/wp-content\/uploads\/2015\/11\/Screen-Shot-2015-11-06-at-2.08.04-PM.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/datascienceplus.com\/wp-content\/uploads\/2015\/11\/Screen-Shot-2015-11-06-at-2.08.04-PM-490x281.png\" alt=\"SFmap\" width=\"490\" height=\"281\" class=\"alignnone size-medium wp-image-1755\" srcset=\"https:\/\/datascienceplus.com\/wp-content\/uploads\/2015\/11\/Screen-Shot-2015-11-06-at-2.08.04-PM-490x281.png 490w, https:\/\/datascienceplus.com\/wp-content\/uploads\/2015\/11\/Screen-Shot-2015-11-06-at-2.08.04-PM-300x172.png 300w, https:\/\/datascienceplus.com\/wp-content\/uploads\/2015\/11\/Screen-Shot-2015-11-06-at-2.08.04-PM.png 709w\" sizes=\"auto, (max-width: 490px) 100vw, 490px\" \/><\/a><br \/>\nIf you click the blue marker, you will see a small popup with the text &#8216;Bay Area&#8217;. There are a variety of options to customize the marker. For example, <code>addCircleMarkers()<\/code> lets you use circle shaped markers instead of the default ones. You can even add your own icons to use as markers (more info <a href=\"http:\/\/leafletjs.com\/examples\/custom-icons.html\" target=\"_blank\">here<\/a> and <a href=\"https:\/\/rstudio.github.io\/leaflet\/markers.html\" target=\"_blank\">here<\/a>)!<\/p>\n<p>The above map with a circle marker can be built as follows:<\/p>\n<pre>\r\nSFmap &lt;- leaflet() %&gt;% \r\n  addTiles() %&gt;% \r\n  setView(-122.42, 37.78, zoom = 13) %&gt;% \r\n  addCircleMarkers(-122.42, 37.78, popup = 'Bay Area', radius = 5, color = 'red')<\/pre>\n<p>and looks likes this:<br \/>\n<a href=\"https:\/\/datascienceplus.com\/wp-content\/uploads\/2015\/11\/Screen-Shot-2015-11-06-at-2.16.50-PM.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/datascienceplus.com\/wp-content\/uploads\/2015\/11\/Screen-Shot-2015-11-06-at-2.16.50-PM-490x327.png\" alt=\"SFmap\" width=\"490\" height=\"327\" class=\"alignnone size-medium wp-image-1757\" srcset=\"https:\/\/datascienceplus.com\/wp-content\/uploads\/2015\/11\/Screen-Shot-2015-11-06-at-2.16.50-PM-490x327.png 490w, https:\/\/datascienceplus.com\/wp-content\/uploads\/2015\/11\/Screen-Shot-2015-11-06-at-2.16.50-PM-300x200.png 300w, https:\/\/datascienceplus.com\/wp-content\/uploads\/2015\/11\/Screen-Shot-2015-11-06-at-2.16.50-PM.png 675w\" sizes=\"auto, (max-width: 490px) 100vw, 490px\" \/><\/a><\/p>\n<p>Let&#8217;s plot an interactive map showing the location of incidents reported to the San Francisco Police Department. The data is available <a href=\"https:\/\/data.sfgov.org\/Public-Safety\/SFPD-Incidents-Current-Year-2015-\/ritf-b9ki\" target=\"_blank\">here<\/a>. Let&#8217;s read in the data and see what it looks like.<\/p>\n<pre>SFdata &lt;- read.csv(&#039;SFPD_Incidents_-_Current_Year__2015_.csv&#039;)\r\nhead(SFdata)<em>\r\n  IncidntNum               Category                                              Descript DayOfWeek       Date  Time PdDistrict      Resolution                Address         X        Y\r\n1  150927700               BURGLARY           BURGLARY OF APARTMENT HOUSE, UNLAWFUL ENTRY  Thursday 10\/22\/2015 23:59    CENTRAL            NONE 900 Block of SUTTER ST -122.4160 37.78823\r\n2  150927700 SEX OFFENSES, FORCIBLE                                        SEXUAL BATTERY  Thursday 10\/22\/2015 23:59    CENTRAL            NONE 900 Block of SUTTER ST -122.4160 37.78823\r\n3  150926570                ASSAULT                                               BATTERY  Thursday 10\/22\/2015 23:45   RICHMOND            NONE   100 Block of 19TH AV -122.4787 37.78508\r\n4  150925312        STOLEN PROPERTY STOLEN PROPERTY, POSSESSION WITH KNOWLEDGE, RECEIVING  Thursday 10\/22\/2015 23:40   SOUTHERN JUVENILE BOOKED    0 Block of SPEAR ST -122.3949 37.79311\r\n5  156262768          LARCENY\/THEFT                               PETTY THEFT OF PROPERTY  Thursday 10\/22\/2015 23:40   SOUTHERN            NONE     MARKET ST \/ 6TH ST -122.4103 37.78223\r\n6  150925312                ROBBERY                ROBBERY, ARMED WITH A DANGEROUS WEAPON  Thursday 10\/22\/2015 23:40   SOUTHERN JUVENILE BOOKED    0 Block of SPEAR ST -122.3949 37.79311<\/em><\/pre>\n<p>(There is another location column at the end which I omitted here as it is just a concatenation of the X and Y columns.)<\/p>\n<p>Now let us look at how many incidents of each category were reported.<\/p>\n<pre>table(SFdata$Category)<em>\r\n                      ARSON                     ASSAULT                  BAD CHECKS                     BRIBERY                    BURGLARY          DISORDERLY CONDUCT DRIVING UNDER THE INFLUENCE \r\n                        255                       10711                          26                          59                        4749                         396                         360 \r\n              DRUG\/NARCOTIC                 DRUNKENNESS                EMBEZZLEMENT                   EXTORTION             FAMILY OFFENSES      FORGERY\/COUNTERFEITING                       FRAUD \r\n                       3315                         473                         115                          25                          54                         561                        2523 \r\n                   GAMBLING                  KIDNAPPING               LARCENY\/THEFT                 LIQUOR LAWS                   LOITERING              MISSING PERSON                NON-CRIMINAL \r\n                         22                         286                       34683                         133                          24                        3755                       15360 \r\n             OTHER OFFENSES     PORNOGRAPHY\/OBSCENE MAT                PROSTITUTION                     ROBBERY                     RUNAWAY             SECONDARY CODES      SEX OFFENSES, FORCIBLE \r\n                      16143                           4                         261                        3054                         124                        1676                         687 \r\n SEX OFFENSES, NON FORCIBLE             STOLEN PROPERTY                     SUICIDE              SUSPICIOUS OCC                        TREA                    TRESPASS                   VANDALISM \r\n                         15                         777                          64                        4367                           1                        1093                        6309 \r\n              VEHICLE THEFT                    WARRANTS                 WEAPON LAWS \r\n                       6361                        5378                        1346 <\/em><\/pre>\n<p>To ensure that the map is plotted quickly, I am going to subset the data to only include observations pertaining to bribery or suicide.<\/p>\n<pre>data &lt;- subset(SFPDdata, Category == &#039;BRIBERY&#039; | Category == &#039;SUICIDE&#039;)<\/pre>\n<p>Now, let us plot all these incidents on the map!<\/p>\n<pre>SFMap %&gt;% \r\n  addTiles() %&gt;% \r\n  setView(-122.42, 37.78, zoom = 13) %&gt;% \r\n  addMarkers(data = data, lng = ~ X, lat = ~ Y, popup = data$Category)\r\nSFMap<\/pre>\n<p>The map looks like this:<br \/>\n<a href=\"https:\/\/datascienceplus.com\/wp-content\/uploads\/2015\/11\/Screen-Shot-2015-11-06-at-2.31.18-PM.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/datascienceplus.com\/wp-content\/uploads\/2015\/11\/Screen-Shot-2015-11-06-at-2.31.18-PM-490x423.png\" alt=\"SFMap\" width=\"490\" height=\"423\" class=\"alignnone size-medium wp-image-1764\" srcset=\"https:\/\/datascienceplus.com\/wp-content\/uploads\/2015\/11\/Screen-Shot-2015-11-06-at-2.31.18-PM-490x423.png 490w, https:\/\/datascienceplus.com\/wp-content\/uploads\/2015\/11\/Screen-Shot-2015-11-06-at-2.31.18-PM-300x259.png 300w, https:\/\/datascienceplus.com\/wp-content\/uploads\/2015\/11\/Screen-Shot-2015-11-06-at-2.31.18-PM.png 523w\" sizes=\"auto, (max-width: 490px) 100vw, 490px\" \/><\/a><br \/>\nHere, clicking on each marker will give a popup showing whether the incident which occurred at that particular location was bribery or suicide.<\/p>\n<p>A lot of the markers are clumped together rather closely. We can cluster them together by specifying <code>clusterOptions<\/code> as follows:<\/p>\n<pre>SFMap %&gt;%\r\n  addTiles() %&gt;% \r\n  setView(-122.42, 37.78, zoom = 13) %&gt;% \r\n  addCircleMarkers(data = data, lng = ~ X, lat = ~ Y, radius = 5, \r\n                   color = ~ ifelse(Category == 'BRIBERY', 'red', 'blue'),\r\n                   clusterOptions = markerClusterOptions())<\/pre>\n<p>which will give the following map:<br \/>\n<a href=\"https:\/\/datascienceplus.com\/wp-content\/uploads\/2015\/11\/Screen-Shot-2015-11-06-at-2.37.38-PM.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/datascienceplus.com\/wp-content\/uploads\/2015\/11\/Screen-Shot-2015-11-06-at-2.37.38-PM-490x314.png\" alt=\"SFMap\" width=\"490\" height=\"314\" class=\"alignnone size-medium wp-image-1766\" srcset=\"https:\/\/datascienceplus.com\/wp-content\/uploads\/2015\/11\/Screen-Shot-2015-11-06-at-2.37.38-PM-490x314.png 490w, https:\/\/datascienceplus.com\/wp-content\/uploads\/2015\/11\/Screen-Shot-2015-11-06-at-2.37.38-PM-300x192.png 300w, https:\/\/datascienceplus.com\/wp-content\/uploads\/2015\/11\/Screen-Shot-2015-11-06-at-2.37.38-PM.png 695w\" sizes=\"auto, (max-width: 490px) 100vw, 490px\" \/><\/a><br \/>\nThe number inside each circle represents the total number of incidents in that area. Areas with higher incidents are marked by yellow circles and areas with lower incidents are marked by green circles. When you click on a cluster, the map will automatically zoom into that area and split into smaller clusters or show the individual incidents depending on how zoomed in you are. The circle markers are colored red for incidents corresponding to bribery, and blue for incidents corresponding to suicide.<\/p>\n<p>That brings us to the end of the article. I hope you enjoyed it. If you have any questions\/feedback, please feel free to leave a comment or reach out to me on <a href=\"https:\/\/twitter.com\/tejaykodali\" target=\"_blank\">Twitter<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Leaflet is an JavaScript library for building interactive maps. RStudio released a package that allows us to build these maps in R! You can do some really cool things in Leaflet, and I will demonstrate a few of those below. Leaflet is compatible with Shiny apps and R Markdown documents. As mentioned on the RStudio [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":1749,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[97,98,96,232],"class_list":["post-1740","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-visualizing-data","tag-leaflet","tag-maps","tag-plot","tag-rstats"],"views":12917,"_links":{"self":[{"href":"https:\/\/datascienceplus.com\/wp-json\/wp\/v2\/posts\/1740","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/datascienceplus.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/datascienceplus.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/datascienceplus.com\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/datascienceplus.com\/wp-json\/wp\/v2\/comments?post=1740"}],"version-history":[{"count":0,"href":"https:\/\/datascienceplus.com\/wp-json\/wp\/v2\/posts\/1740\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/datascienceplus.com\/wp-json\/wp\/v2\/media\/1749"}],"wp:attachment":[{"href":"https:\/\/datascienceplus.com\/wp-json\/wp\/v2\/media?parent=1740"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/datascienceplus.com\/wp-json\/wp\/v2\/categories?post=1740"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/datascienceplus.com\/wp-json\/wp\/v2\/tags?post=1740"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}