

{"id":3563,"date":"2015-07-26T11:33:20","date_gmt":"2015-07-26T16:33:20","guid":{"rendered":"http:\/\/rud.is\/b\/?p=3563"},"modified":"2018-03-10T07:54:15","modified_gmt":"2018-03-10T12:54:15","slug":"making-staticinteractive-voronoi-map-layers-in-ggplotleaflet","status":"publish","type":"post","link":"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/","title":{"rendered":"Making Static\/Interactive Voronoi Map Layers In ggplot\/leaflet"},"content":{"rendered":"<p>Despite having shown various ways to overcome <a href=\"https:\/\/rud.is\/b\/2014\/09\/26\/overcoming-d3-cartographic-envy-with-r-ggplot\/\">D3 cartographic envy<\/a>, there are always more examples that can cause the green monster to rear it&#8217;s ugly head.<\/p>\n<p>Take the <a href=\"https:\/\/bl.ocks.org\/mbostock\/7608400\">Voronoi Arc Map<\/a> example.<\/p>\n<p><center><br \/>\n<a target=\"_blank\" href=\"https:\/\/bl.ocks.org\/mbostock\/7608400\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"3565\" data-permalink=\"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/voronoi_arc_map\/\" data-orig-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2015\/07\/Voronoi_Arc_Map.png?fit=600%2C314&amp;ssl=1\" data-orig-size=\"600,314\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Voronoi_Arc_Map\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2015\/07\/Voronoi_Arc_Map.png?fit=300%2C157&amp;ssl=1\" data-large-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2015\/07\/Voronoi_Arc_Map.png?fit=510%2C267&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2015\/07\/Voronoi_Arc_Map.png?resize=510%2C267&#038;ssl=1\" alt=\"Voronoi_Arc_Map\" width=\"510\" height=\"267\" class=\"aligncenter size-full wp-image-3565\" \/><\/a><br \/>\n<\/center><\/p>\n<p>For those in need of a primer, a Voronoi tesslation\/diagram is:<\/p>\n<blockquote><p>\n  &hellip;<em>a partitioning of a plane into regions based on distance to points in a specific subset of the plane. That set of points (called seeds, sites, or generators) is specified beforehand, and for each seed there is a corresponding region consisting of all points closer to that seed than to any other.<\/em> <sup><a href=\"https:\/\/en.wikipedia.org\/wiki\/Voronoi_diagram\">Wikipedia<\/a><\/sup>\n<\/p><\/blockquote>\n<p>We can overlay a Voronoi tessalation on top of a map in R as well thanks to the <code>deldir<\/code> package (which has been around since the &#8220;S&#8221; days!). Let&#8217;s get (most of) the package requirements cruft out of the way, first:<\/p>\n<pre lang=\"rsplus\">library(sp)\nlibrary(rgdal)\nlibrary(deldir)\nlibrary(dplyr)\nlibrary(ggplot2)\nlibrary(ggthemes)<\/pre>\n<p>Now we&#8217;ll [ab]use the data from the Arc Map example:<\/p>\n<pre lang=\"rsplus\">flights <- read.csv(\"http:\/\/bl.ocks.org\/mbostock\/raw\/7608400\/flights.csv\", stringsAsFactors=FALSE)\nairports <- read.csv(\"http:\/\/bl.ocks.org\/mbostock\/raw\/7608400\/airports.csv\", stringsAsFactors=FALSE)<\/pre>\n<p>Since the D3 example cheats and only uses the continental US (CONUS) we'll do the same and we'll also filter out only those airports mentioned in the <code>flights<\/code> data and get the total &#35; of incoming\/outgoing flights for each airport:<\/p>\n<pre lang=\"rsplus\">conus <- state.abb[!(state.abb %in% c(\"AK\", \"HI\"))]\nairports <- filter(airports,\n                   state %in% conus,\n                   iata %in% union(flights$origin, flights$destination))\norig <- select(count(flights, origin), iata=origin, n1=n)\ndest <- select(count(flights, destination), iata=destination, n2=n)\nairports <- left_join(airports,\n                      select(mutate(left_join(orig, dest),\n                                    tot=n1+n2),\n                             iata, tot)) %>% \n            filter(!is.na(tot))<\/pre>\n<p>Since we're going to initially plot polygons in ggplot (and, eventually, in leaflet), we'll need to work with <code>Spatial<\/code> objects, so let's make those airport lat\/lon pairs into a <code>SpatialPointsDataFrame<\/code>:<\/p>\n<pre lang=\"rsplus\">vor_pts <- SpatialPointsDataFrame(cbind(airports$longitude,\n                                        airports$latitude),\n                                  airports, match.ID=TRUE)<\/pre>\n<p>The <code>deldir<\/code> function returns a pretty complex object. Thankfully, the authors of the package realized that one might just want the polygons from the computation and pre-made a function: <code>tile.list<\/code> for computing\/extracting them. Those polygons aren't, however, closed and we really want to keep the airport data associatd with them, so we need to close the polygons and associate the data. Since we're likely going to repeat this task, let's make it a (very badly named) function:<\/p>\n<pre lang=\"rsplus\">SPointsDF_to_voronoi_SPolysDF <- function(sp) {\n\n  # tile.list extracts the polygon data from the deldir computation\n  vor_desc <- tile.list(deldir(sp@coords[,1], sp@coords[,2]))\n\n  lapply(1:(length(vor_desc)), function(i) {\n\n    # tile.list gets us the points for the polygons but we\n    # still have to close them, hence the need for the rbind\n    tmp <- cbind(vor_desc[[i]]$x, vor_desc[[i]]$y)\n    tmp <- rbind(tmp, tmp[1,])\n\n    # now we can make the Polygon(s)\n    Polygons(list(Polygon(tmp)), ID=i)\n\n  }) -> vor_polygons\n\n  # hopefully the caller passed in good metadata!\n  sp_dat <- sp@data\n\n  # this way the IDs _should_ match up w\/the data &#038; voronoi polys\n  rownames(sp_dat) <- sapply(slot(SpatialPolygons(vor_polygons),\n                                  'polygons'),\n                             slot, 'ID')\n\n  SpatialPolygonsDataFrame(SpatialPolygons(vor_polygons),\n                           data=sp_dat)\n\n}<\/pre>\n<p>Before we can make the plots, we need to put the <code>Spatial<\/code> objects into the proper form for ggplot2 (and get the U.S. state map):<\/p>\n<pre lang=\"rsplus\">vor <- SPointsDF_to_voronoi_SPolysDF(vor_pts)\n\nvor_df <- fortify(vor)\n\nstates <- map_data(\"state\")<\/pre>\n<p><em>Now<\/em> we can have some fun. Let's try to mimic the D3 example map as closely as possible. We'll lay down the CONUS map, add a points layer for the the airports, sizing &amp; styling them just like the D3 example. Note that we order the points so that the smallest ones appear on top (so we can still see them).<\/p>\n<p>We'll then lay down our newly created Voronoi layer. We'll also use the same projection (Albers) that the D3 examples uses:<\/p>\n<pre lang=\"rsplus\">gg <- ggplot()\n# base map\ngg <- gg + geom_map(data=states, map=states,\n                    aes(x=long, y=lat, map_id=region),\n                    color=\"white\", fill=\"#cccccc\", size=0.5)\n# airports layer\ngg <- gg + geom_point(data=arrange(airports, desc(tot)),\n                      aes(x=longitude, y=latitude, size=sqrt(tot)),\n                      shape=21, color=\"white\", fill=\"steelblue\")\n# voronoi layer\ngg <- gg + geom_map(data=vor_df, map=vor_df,\n                    aes(x=long, y=lat, map_id=id),\n                    color=\"#a5a5a5\", fill=\"#FFFFFF00\", size=0.25)\ngg <- gg + scale_size(range=c(2, 9))\ngg <- gg + coord_map(\"albers\", lat0=30, lat1=40)\ngg <- gg + theme_map()\ngg <- gg + theme(legend.position=\"none\")\ngg<\/pre>\n<p><a href=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2015\/07\/ggplot-1.png?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"3564\" data-permalink=\"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/ggplot-1\/\" data-orig-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2015\/07\/ggplot-1.png?fit=1920%2C1152&amp;ssl=1\" data-orig-size=\"1920,1152\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"ggplot-1\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2015\/07\/ggplot-1.png?fit=300%2C180&amp;ssl=1\" data-large-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2015\/07\/ggplot-1.png?fit=510%2C306&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2015\/07\/ggplot-1.png?resize=510%2C306&#038;ssl=1\" alt=\"ggplot-1\" width=\"510\" height=\"306\" class=\"aligncenter size-full wp-image-3564\" \/><\/a><\/p>\n<p>While that's pretty, it's not exactly <em>useful<\/em>. I'm sure there are times when it's important to show the Voronoi polygons, but they are especially useful when they are used to help with user interface interactions.<\/p>\n<p>In the case of this map, some airport \"bubbles\" are very small and many overlap, making a \"click\" (or even \"hover\") a potentially painstaking task for someone looking to get more data out of the visualization. The D3 example uses Voronoi polygons to make it super-easy for the user to hover over a map area and get more info about the flights for the closest airport to the mouse pointer.<\/p>\n<p>We'll use the leaflet htmlwidget to do something similar. Until I can figure out \"hover\" events for R+leaflet, you'll have to live with \"click\".<\/p>\n<p>First we'll need some additional packages:<\/p>\n<pre lang=\"rsplus\">library(leaflet)\nlibrary(rgeos)\nlibrary(htmltools)<\/pre>\n<p>And, we'll also need a U.S. shapefile (which we simplify since the polygons are pretty detailed and that's not necessary for this vis):<\/p>\n<pre lang=\"rsplus\">url <- \"http:\/\/eric.clst.org\/wupl\/Stuff\/gz_2010_us_040_00_500k.json\"\nfil <- \"gz_2010_us_040_00_500k.json\"\n\nif (!file.exists(fil)) download.file(url, fil, cacheOK=TRUE)\n\nstates_m <- readOGR(\"gz_2010_us_040_00_500k.json\", \n                    \"OGRGeoJSON\", verbose=FALSE)\nstates_m <- subset(states_m, \n                   !NAME %in% c(\"Alaska\", \"Hawaii\", \"Puerto Rico\"))\ndat <- states_m@data # gSimplify whacks the data bits\nstates_m <- SpatialPolygonsDataFrame(gSimplify(states_m, 0.05,\n                                               topologyPreserve=TRUE),\n                                     dat, FALSE)<\/pre>\n<p>The leaflet vis idiom is similar to the ggplot idiom. I'm using a base tile layer since I was too lazy to figure out how to change the leaflet default gray background map color. The map polygons are added, then the circles\/bubbles (note that you work in <em>meters<\/em> with <code>addCircles<\/code> which lets leaflet scale the bubbles as you zoom in\/out). Finally, the Voronoi layer is added. I kept the stroke visible purely for demonstration purposes. You <em>need<\/em> to keep <code>fill=TRUE<\/code> otherwise the Voronoi layer won't get click\/hover events and once I figure out how to trigger popups on hover and use a static popup layer, this will let users hover around the map to get the underlying airport flight information.<\/p>\n<pre lang=\"rsplus\">leaflet(width=900, height=650) %>%\n  # base map\n  addProviderTiles(\"Hydda.Base\") %>%\n  addPolygons(data=states_m,\n              stroke=TRUE, color=\"white\", weight=1, opacity=1,\n              fill=TRUE, fillColor=\"#cccccc\", smoothFactor=0.5) %>%\n  # airports layer\n  addCircles(data=arrange(airports, desc(tot)),\n             lng=~longitude, lat=~latitude,\n             radius=~sqrt(tot)*5000, # size is in m for addCircles O_o\n             color=\"white\", weight=1, opacity=1,\n             fillColor=\"steelblue\", fillOpacity=1) %>%\n  # voronoi (click) layer\n  addPolygons(data=vor,\n              stroke=TRUE, color=\"#a5a5a5\", weight=0.25,\n              fill=TRUE, fillOpacity = 0.0,\n              smoothFactor=0.5, \n              popup=sprintf(\"Total In\/Out: %s\",\n                            as.character(vor@data$tot)))<\/pre>\n<p><iframe seamless frameborder=\"0\" src=\"\/b\/iframes\/voronoi\/vorono_leaflet.html\" width=900 height=650><\/iframe><\/p>\n<p>I made the Voronoi layer very light, so you may want to keep it there as a cue for the user. How you work with it is completely up to you.<\/p>\n<p>Now you have one less reason to be envious of the D3 cartographers!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Despite having shown various ways to overcome D3 cartographic envy, there are always more examples that can cause the green monster to rear it&#8217;s ugly head. Take the Voronoi Arc Map example. For those in need of a primer, a Voronoi tesslation\/diagram is: &hellip;a partitioning of a plane into regions based on distance to points [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":true,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":3,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":""},"categories":[721,666,678,673,674,706,91],"tags":[810],"class_list":["post-3563","post","type-post","status-publish","format-standard","hentry","category-cartography","category-d3","category-data-visualization","category-datavis-2","category-dataviz","category-maps","category-r","tag-post"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.2 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Making Static\/Interactive Voronoi Map Layers In ggplot\/leaflet - rud.is<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Making Static\/Interactive Voronoi Map Layers In ggplot\/leaflet - rud.is\" \/>\n<meta property=\"og:description\" content=\"Despite having shown various ways to overcome D3 cartographic envy, there are always more examples that can cause the green monster to rear it&#8217;s ugly head. Take the Voronoi Arc Map example. For those in need of a primer, a Voronoi tesslation\/diagram is: &hellip;a partitioning of a plane into regions based on distance to points [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/\" \/>\n<meta property=\"og:site_name\" content=\"rud.is\" \/>\n<meta property=\"article:published_time\" content=\"2015-07-26T16:33:20+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2018-03-10T12:54:15+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/rud.is\/b\/wp-content\/uploads\/2015\/07\/Voronoi_Arc_Map.png\" \/>\n<meta name=\"author\" content=\"hrbrmstr\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"hrbrmstr\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/\"},\"author\":{\"name\":\"hrbrmstr\",\"@id\":\"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886\"},\"headline\":\"Making Static\/Interactive Voronoi Map Layers In ggplot\/leaflet\",\"datePublished\":\"2015-07-26T16:33:20+00:00\",\"dateModified\":\"2018-03-10T12:54:15+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/\"},\"wordCount\":760,\"commentCount\":4,\"publisher\":{\"@id\":\"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886\"},\"image\":{\"@id\":\"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/rud.is\/b\/wp-content\/uploads\/2015\/07\/Voronoi_Arc_Map.png\",\"keywords\":[\"post\"],\"articleSection\":[\"cartography\",\"d3\",\"Data Visualization\",\"DataVis\",\"DataViz\",\"maps\",\"R\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/\",\"url\":\"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/\",\"name\":\"Making Static\/Interactive Voronoi Map Layers In ggplot\/leaflet - rud.is\",\"isPartOf\":{\"@id\":\"https:\/\/rud.is\/b\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/rud.is\/b\/wp-content\/uploads\/2015\/07\/Voronoi_Arc_Map.png\",\"datePublished\":\"2015-07-26T16:33:20+00:00\",\"dateModified\":\"2018-03-10T12:54:15+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/#primaryimage\",\"url\":\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2015\/07\/Voronoi_Arc_Map.png?fit=600%2C314&ssl=1\",\"contentUrl\":\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2015\/07\/Voronoi_Arc_Map.png?fit=600%2C314&ssl=1\",\"width\":600,\"height\":314},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/rud.is\/b\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Making Static\/Interactive Voronoi Map Layers In ggplot\/leaflet\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/rud.is\/b\/#website\",\"url\":\"https:\/\/rud.is\/b\/\",\"name\":\"rud.is\",\"description\":\"&quot;In God we trust. All others must bring data&quot;\",\"publisher\":{\"@id\":\"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/rud.is\/b\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886\",\"name\":\"hrbrmstr\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1\",\"url\":\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1\",\"contentUrl\":\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1\",\"width\":460,\"height\":460,\"caption\":\"hrbrmstr\"},\"logo\":{\"@id\":\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1\"},\"description\":\"Don't look at me\u2026I do what he does \u2014 just slower. #rstats avuncular \u2022 ?Resistance Fighter \u2022 Cook \u2022 Christian \u2022 [Master] Chef des Donn\u00e9es de S\u00e9curit\u00e9 @ @rapid7\",\"sameAs\":[\"http:\/\/rud.is\"],\"url\":\"https:\/\/rud.is\/b\/author\/hrbrmstr\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Making Static\/Interactive Voronoi Map Layers In ggplot\/leaflet - rud.is","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/","og_locale":"en_US","og_type":"article","og_title":"Making Static\/Interactive Voronoi Map Layers In ggplot\/leaflet - rud.is","og_description":"Despite having shown various ways to overcome D3 cartographic envy, there are always more examples that can cause the green monster to rear it&#8217;s ugly head. Take the Voronoi Arc Map example. For those in need of a primer, a Voronoi tesslation\/diagram is: &hellip;a partitioning of a plane into regions based on distance to points [&hellip;]","og_url":"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/","og_site_name":"rud.is","article_published_time":"2015-07-26T16:33:20+00:00","article_modified_time":"2018-03-10T12:54:15+00:00","og_image":[{"url":"https:\/\/rud.is\/b\/wp-content\/uploads\/2015\/07\/Voronoi_Arc_Map.png","type":"","width":"","height":""}],"author":"hrbrmstr","twitter_card":"summary_large_image","twitter_misc":{"Written by":"hrbrmstr","Est. reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/#article","isPartOf":{"@id":"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/"},"author":{"name":"hrbrmstr","@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"headline":"Making Static\/Interactive Voronoi Map Layers In ggplot\/leaflet","datePublished":"2015-07-26T16:33:20+00:00","dateModified":"2018-03-10T12:54:15+00:00","mainEntityOfPage":{"@id":"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/"},"wordCount":760,"commentCount":4,"publisher":{"@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"image":{"@id":"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/#primaryimage"},"thumbnailUrl":"https:\/\/rud.is\/b\/wp-content\/uploads\/2015\/07\/Voronoi_Arc_Map.png","keywords":["post"],"articleSection":["cartography","d3","Data Visualization","DataVis","DataViz","maps","R"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/","url":"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/","name":"Making Static\/Interactive Voronoi Map Layers In ggplot\/leaflet - rud.is","isPartOf":{"@id":"https:\/\/rud.is\/b\/#website"},"primaryImageOfPage":{"@id":"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/#primaryimage"},"image":{"@id":"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/#primaryimage"},"thumbnailUrl":"https:\/\/rud.is\/b\/wp-content\/uploads\/2015\/07\/Voronoi_Arc_Map.png","datePublished":"2015-07-26T16:33:20+00:00","dateModified":"2018-03-10T12:54:15+00:00","breadcrumb":{"@id":"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/#primaryimage","url":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2015\/07\/Voronoi_Arc_Map.png?fit=600%2C314&ssl=1","contentUrl":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2015\/07\/Voronoi_Arc_Map.png?fit=600%2C314&ssl=1","width":600,"height":314},{"@type":"BreadcrumbList","@id":"https:\/\/rud.is\/b\/2015\/07\/26\/making-staticinteractive-voronoi-map-layers-in-ggplotleaflet\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/rud.is\/b\/"},{"@type":"ListItem","position":2,"name":"Making Static\/Interactive Voronoi Map Layers In ggplot\/leaflet"}]},{"@type":"WebSite","@id":"https:\/\/rud.is\/b\/#website","url":"https:\/\/rud.is\/b\/","name":"rud.is","description":"&quot;In God we trust. All others must bring data&quot;","publisher":{"@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/rud.is\/b\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886","name":"hrbrmstr","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1","url":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1","contentUrl":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1","width":460,"height":460,"caption":"hrbrmstr"},"logo":{"@id":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1"},"description":"Don't look at me\u2026I do what he does \u2014 just slower. #rstats avuncular \u2022 ?Resistance Fighter \u2022 Cook \u2022 Christian \u2022 [Master] Chef des Donn\u00e9es de S\u00e9curit\u00e9 @ @rapid7","sameAs":["http:\/\/rud.is"],"url":"https:\/\/rud.is\/b\/author\/hrbrmstr\/"}]}},"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p23idr-Vt","jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":3054,"url":"https:\/\/rud.is\/b\/2014\/09\/26\/overcoming-d3-cartographic-envy-with-r-ggplot\/","url_meta":{"origin":3563,"position":0},"title":"Overcoming D3 Cartographic Envy With R + ggplot","author":"hrbrmstr","date":"2014-09-26","format":false,"excerpt":"When I used one of the Scotland TopoJSON files for a recent post, it really hit me just how much D3 cartography envy I had\/have as an R user. Don't get me wrong, I can conjure up D3 maps pretty well [1] [2] and the utility of an interactive map\u2026","rel":"","context":"In &quot;Charts &amp; Graphs&quot;","block_context":{"text":"Charts &amp; Graphs","link":"https:\/\/rud.is\/b\/category\/charts-graphs\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2846,"url":"https:\/\/rud.is\/b\/2013\/12\/27\/points-polygons-and-power-outages\/","url_meta":{"origin":3563,"position":1},"title":"Points, Polygons and Power Outages","author":"hrbrmstr","date":"2013-12-27","format":false,"excerpt":"Most of my free coding time has been spent tweaking a D3-based live power outage tracker for Central Maine Power customers (there's also a woefully less-featured Shiny app for it, too). There is some R associated with the D3 vis, but it's limited to a cron job that's makes the\u2026","rel":"","context":"In &quot;Data Visualization&quot;","block_context":{"text":"Data Visualization","link":"https:\/\/rud.is\/b\/category\/data-visualization\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2816,"url":"https:\/\/rud.is\/b\/2013\/11\/28\/one-more-timemapping-maine-power-outages-with-d3\/","url_meta":{"origin":3563,"position":2},"title":"One More Time\u2026Mapping Maine Power Outages with D3","author":"hrbrmstr","date":"2013-11-28","format":false,"excerpt":"It started with a local R version and migrated to a Shiny version and is now in full D3 glory. Some down time gave me the opportunity to start a basic D3 version of the outage map, but it needs a bit of work as it relies on a page\u2026","rel":"","context":"In &quot;d3&quot;","block_context":{"text":"d3","link":"https:\/\/rud.is\/b\/category\/d3\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2013\/11\/Central_Maine_Power_Live_Outage_Map-2.png?fit=757%2C649&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2013\/11\/Central_Maine_Power_Live_Outage_Map-2.png?fit=757%2C649&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2013\/11\/Central_Maine_Power_Live_Outage_Map-2.png?fit=757%2C649&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2013\/11\/Central_Maine_Power_Live_Outage_Map-2.png?fit=757%2C649&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":1611,"url":"https:\/\/rud.is\/b\/2012\/10\/05\/more-diy-zeroaccess-geoip-fun-jqueryd3-choropleths\/","url_meta":{"origin":3563,"position":3},"title":"More DIY ZeroAccess GeoIP Fun : jQuery\/D3 Choropleths","author":"hrbrmstr","date":"2012-10-05","format":false,"excerpt":"In the spirit of the previous example this one shows you how to do a quick, country-based choropleth in D3\/jQuery with some help from the command-line since not everyone is equipped to kick out some R and most folks I know are very handy at a terminal prompt. I took\u2026","rel":"","context":"In &quot;Charts &amp; Graphs&quot;","block_context":{"text":"Charts &amp; Graphs","link":"https:\/\/rud.is\/b\/category\/charts-graphs\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":3117,"url":"https:\/\/rud.is\/b\/2014\/11\/16\/moving-the-earth-well-alaska-hawaii-with-r\/","url_meta":{"origin":3563,"position":4},"title":"Moving The Earth (well, Alaska &#038; Hawaii) With R","author":"hrbrmstr","date":"2014-11-16","format":false,"excerpt":"In a previous post we looked at how to use D3 TopoJSON files with R and make some very D3-esque maps. I mentioned that one thing missing was moving Alaska & Hawaii a bit closer to the continental United States and this post shows you how to do that. The\u2026","rel":"","context":"In &quot;d3&quot;","block_context":{"text":"d3","link":"https:\/\/rud.is\/b\/category\/d3\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":4209,"url":"https:\/\/rud.is\/b\/2016\/03\/27\/nuclear-animations-in-d3\/","url_meta":{"origin":3563,"position":5},"title":"Nuclear Animations in D3","author":"hrbrmstr","date":"2016-03-27","format":false,"excerpt":"As I said, I'm kinda obsessed with the \"nuclear\" data set. So much so that I made a D3 version that's similar to the R version I made the other day. I tried not to code much today (too much Easter fun going on), so I left off the size\u2026","rel":"","context":"In &quot;cartography&quot;","block_context":{"text":"cartography","link":"https:\/\/rud.is\/b\/category\/cartography\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2016\/03\/ogimg.png?fit=1200%2C946&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2016\/03\/ogimg.png?fit=1200%2C946&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2016\/03\/ogimg.png?fit=1200%2C946&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2016\/03\/ogimg.png?fit=1200%2C946&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2016\/03\/ogimg.png?fit=1200%2C946&ssl=1&resize=1050%2C600 3x"},"classes":[]}],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts\/3563","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/comments?post=3563"}],"version-history":[{"count":0,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts\/3563\/revisions"}],"wp:attachment":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/media?parent=3563"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/categories?post=3563"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/tags?post=3563"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}