I plotted a dot density map of the Australian states and am now trying to plot a chloropleth map of the Australian states using the leaflet package and color each state by the count value. I have the following data frame
state count latitude longitude
Australian Capital Territory 125 ... ...
New South Wales 45
Northern Territory 75
Queensland 12
South Australia 245
Tasmania 4895
Victoria 279
The following is the code I used to plot the dot density map
leaflet(aus_state_counts) %>%
addTiles() %>%
addCircleMarkers(
layerId = ~state,
label = ~state,
radius = ~count
) %>%
fitBounds(lng1 = max(aus_state_counts$longitude) ,lat1 = max(aus_state_counts$latitude),
lng2 = min(aus_state_counts$longitude) ,lat2 = min(aus_state_counts$latitude)
)
I am unsure how to plot the states on the map? Do I need additional information for this?
For a choropleth map you will need some spatial polygon data in the form of a shape file (.shp) or GeoJSON (.geojson). Below should work.
library(sf)
library(leaflet)
library(dplyr)
# GeoJSON Data
states <- read_sf("https://raw.githubusercontent.com/rowanhogan/australian-states/master/states.geojson")
counts <- data.frame(state=c("Australian Capital Territory", "New South Wales", "Northern Territory", "Queensland",
"South Australia", "Tasmania", "Victoria"), count=c(125,45,75,12,245,4895,279))
# Join to count data
data <- states %>%
dplyr::left_join(counts, by=c("STATE_NAME" = "state"))
# Specify choropleth colors
pal <- colorQuantile("Blues", domain = data$count)
# Plot Map
leaflet(data) %>%
addTiles() %>%
addPolygons(fillColor=~pal(count), fillOpacity=0.8, color="white", weight=1)
Related
I started working with a shapefile in R. In this shapefile, each "boundary" is uniquely defined by a value in "col1" (e.g. ABC111, ABC112 , ABC113, etc.):
library(sf)
library(igraph)
sf <- sf::st_read("C:/Users/me/OneDrive/Documents/shape5/myshp.shp", options = "ENCODING=WINDOWS-1252")
head(sf)
Simple feature collection with 6 features and 3 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 7201955 ymin: 927899.4 xmax: 7484015 ymax: 1191414
Projected CRS: PCS_Lambert_Conformal_Conic
col1 col2 col3 geometry
620 ABC111 99 Region1 MULTIPOLYGON (((7473971 119...
621 ABC112 99 Region1 MULTIPOLYGON (((7480277 118...
622 ABC113 99 Region1 MULTIPOLYGON (((7477124 118...
627 ABC114 99 Region1 MULTIPOLYGON (((7471697 118...
638 ABC115 99 Region1 MULTIPOLYGON (((7209908 928...
639 ABC116 99 Region1 MULTIPOLYGON (((7206683 937...
> dim(sf)
[1] 500 4
sf_trans = st_transform(sf, 4326)
I then plotted this data using the leaflet library:
library(leaflet)
map = leaflet(sf_trans) %>% addPolygons( stroke = FALSE) %>% addTiles(group = "OSM") %>% addProviderTiles("CartoDB.DarkMatter", group = "Carto") %>% addPolygons(data = st_trans, weight=5, col = 'blue')
What I want to do is to try and make a "searchable" map. For example, imagine that "ABC111" is like an American ZIP Code. I want to make a map in which you can search for "ABC111" and the geographical outline of "ABC111" will be highlighted.
As an example, the ZIP Code of the Space Needle Tower in Seattle, Washington (USA) is "98109". If I search for this ZIP Code on Google Maps, the outline of this ZIP code is highlighted in red:
I was able to find a question on stackoverflow that explains how to add a search bar on a leaflet map for individual points (R leaflet search marker NOT work):
libary(dplyr)
library(leaflet)
library(leaflet.extras)
# using the same reproducible data from the question/example
cities <- read.csv(
textConnection("City,Lat,Long,Pop
Boston,42.3601,-71.0589,645966
Hartford,41.7627,-72.6743,125017
New York City,40.7127,-74.0059,8406000
Philadelphia,39.9500,-75.1667,1553000
Pittsburgh,40.4397,-79.9764,305841
Providence,41.8236,-71.4222,177994
"))
leaflet(cities) %>%
addProviderTiles(providers$OpenStreetMap) %>%
addResetMapButton() %>%
# these markers will be "invisible" on the map:
addMarkers(
data = cities, lng = ~Long, lat = ~Lat, label = cities$City,
group = 'cities', # this is the group to use in addSearchFeatures()
# make custom icon that is so small you can't see it:
icon = makeIcon(
iconUrl = "http://leafletjs.com/examples/custom-icons/leaf-green.png",
iconWidth = 1, iconHeight = 1
)
) %>%
addSearchFeatures(
targetGroups = 'cities', # group should match addMarkers() group
options = searchFeaturesOptions(
zoom=12, openPopup = TRUE, firstTipSubmit = TRUE,
autoCollapse = TRUE, hideMarkerOnCollapse = TRUE
)
)
But is there a way that the above code can be modified such that when you enter a term in the search bar (e.g. ABC111, ABC112), the entire boundaries of this region are highlighted in red?
Thank you!
I ran 2 aggregate commands:
Outright_owners = aggregate(csv_data$Owned...outright~csv_data$State, csv_data, FUN = sum)
and
Mortgage_owners = aggregate(csv_data$Owned...with.a.mortgage~csv_data$State, csv_data, FUN = sum)
This is the output of Outright_owners aggregate:
csv_data$State
csv_data$Owned...outright
New South Wales
819828
Northern Territory
9297
Queensland
448627
South Australia
202917
Tasmania
69784
Victoria
665363
Western Australia
234608
This is the output of Mortgage_owners aggregate:
csv_data$State
csv_data$Owned...with.a.mortgage
New South Wales
824168
Northern Territory
18497
Queensland
533879
South Australia
218264
Tasmania
65921
Victoria
697520
Western Australia
300355
I want code that would create a stacked bar-plot that would look something like this
I haven't tried anything specific yet, so I don't have any minimum reproducible code. I'm not sure where even to begin.
Thanks in advance :)
Update:
Something like this:
To show the data better I would log the y scale:
join the data with left_join
bring it to long form with pivot_longer
apply geom_col
use log y.
With ggplot2
library(tidyverse)
left_join(df1, df2, by="State") %>%
pivot_longer(
cols = -State
) %>%
ggplot(aes(x = State, y=log(value), fill=name, label=value))+
geom_col() +
geom_text(size = 5, position = position_stack(vjust = 0.9))
With base R before base R, I used tidyr package to bring it to wide format.
df1_w <- df1 %>%
pivot_wider(
names_from = State,
values_from = mortgage
)
df2_w <- df2 %>%
pivot_wider(
names_from = State,
values_from = mortgage
)
Plot with base R
data <- as.matrix(data.frame(rbind(df1_w, df2_w)))
rownames(data) <- c("outright", "mortgage")
barplot(data,
col = c("green", "red"))
legend("topright",
legend = c("outright", "mortgage"),
fill = c("green", "red"))
data:
df1 <- structure(list(State = c("New South Wales", "Northern Territory",
"Queensland", "South Australia", "Tasmania", "Victoria", "Western Australia"
), outright = c(819828L, 9297L, 448627L, 202917L, 69784L, 665363L,
234608L)), class = "data.frame", row.names = c(NA, -7L))
df2 <- structure(list(State = c("New South Wales", "Northern Territory",
"Queensland", "South Australia", "Tasmania", "Victoria", "Western Australia"
), mortgage = c(824168L, 18497L, 533879L, 218264L, 65921L, 697520L,
300355L)), class = "data.frame", row.names = c(NA, -7L))
below is an example of finding route, travel time and travel distance from 'One World Trade Center, NYC' to 'Madison Square Park, NYC' using osrm package in R. (I learnt it from Road Routing in R). The travel time here is 10.37 minutes.
Q. How can I interpolate and find location after 5 minutes.
library(sf)
library(dplyr)
library(tidygeocoder)
library(osrm)
# 1. One World Trade Center, NYC
# 2. Madison Square Park, NYC
adresses <- c("285 Fulton St, New York, NY 10007",
"11 Madison Ave, New York, NY 10010")
# geocode the two addresses & transform to {sf} data structure
data <- tidygeocoder::geo(adresses, method = "osm") %>%
st_as_sf(coords = c("long", "lat"), crs = 4326)
osroute <- osrm::osrmRoute(loc = data,
returnclass = "sf")
summary(osroute)
library(leaflet)
leaflet(data = data) %>%
addProviderTiles("CartoDB.Positron") %>%
addMarkers(label = ~address) %>%
addPolylines(data = osroute,
label = "OSRM engine",
color = "red")
Use the osrm::osrmIsochrone() function to find the five minute travel distance polygon, and then find the point that the route intersects the polygon.
It looks like its on Clarkson Street between Hudson & Varick.
library(sf)
library(dplyr)
library(tidygeocoder)
library(osrm)
# 1. One World Trade Center, NYC
# 2. Madison Square Park, NYC
adresses <- c("285 Fulton St, New York, NY 10007",
"11 Madison Ave, New York, NY 10010")
# geocode the two addresses & transform to {sf} data structure
data <- tidygeocoder::geo(adresses, method = "osm") %>%
st_as_sf(coords = c("long", "lat"), crs = 4326)
# get route from 285 fulton to 11 madison
osroute <- osrmRoute(src = data[1,], dst = data[2,], returnclass = 'sf')
# five minute isochrone from 285 fulton
five_min_isochrone <- osrmIsochrone(data[1,], breaks = 5, returnclass = 'sf')
# isochrone has to be cast to MULTILINESTRING to find intersection as a point
intersection <- five_min_isochrone %>%
st_cast('MULTILINESTRING') %>%
st_intersection(osroute)
library(leaflet)
leaflet(data = data) %>%
addProviderTiles("CartoDB.Positron") %>%
addMarkers(label = ~address) %>%
addPolylines(data = osroute,
label = "OSRM engine",
color = "red") %>%
addPolygons(data = five_min_isochrone) %>%
addMarkers(data = intersection,
label = '5 minute distance')
I have written the following code:
library(ozmaps)
oz(states = TRUE, coast = TRUE,
ylim = NULL, add = FALSE, ar = 1, eps = 0.25)
That generates:
I wonder how to add the names of the states on the map? If the whole process can be done by "map" package, it is fine as well.
Thanks.
I'm not familiar with package ozmaps. I could not find data for the state names and latitude and longitude values for state centroids within the package.
A quick internet search produced some representative state data from https://www.distancelatlong.com/distancecalculator/country/australia/
You can adjust this data or find a better source, so this should be a start.
library(tibble)
library(ggplot2)
library(ozmaps)
ggplot(ozmap_states)+
geom_sf()+
geom_text(data = oz_states, aes(long, lat, label = state))+
theme_void()
data
oz_states <- tribble(
~state, ~lat, ~long,
"Australian Capital Territory", -35.3546004, 149.2113468,
"New South Wales", -33.42004148, 151.3000048,
"Northern Territory", -13.81617348, 131.816698,
"Queensland", -26.67998777, 153.0500272,
"South Australia", -34.28293455, 140.6000378,
"Tasmania", -40.83292234, 145.1166613,
"Victoria", -37.73119953, 142.0234135,
"Western Australia", -33.58287392, 120.0333345
)
Created on 2021-03-29 by the reprex package (v1.0.0)
Hello all experts out there,
I am very new to R and leaflet
I would like to create a shiny dashboard and within it, I want to create a map with leaflet. Here is how I want it to be, first, the user will pick a state, then, you may or may not pick a county. So if they pick a state I would like to use setview() to just look at the chosen state, and if they pick a state and a county, then setview() to look at the chosen county.
So first I want to make sure my leaflet code works first, before I embed it into shiny server. So I ran the following code assuming that the user picks California state and county Los Angeles.
I got the following error and not sure how to fix it.
Any suggestion? Thank you so much in advance!
Error in cut.default(x, binsToUse, labels = FALSE, include.lowest = TRUE, :
'breaks' are not unique
> head(lonlat)
STATE COUNTY county.State lon lat
1 AK KENAI PENINSULA KENAI PENINSULA,AK -151.3044 60.58293
2 AK ANCHORAGE ANCHORAGE,AK -149.8557 61.22002
3 AK DENALI DENALI,AK -145.8662 63.04024
4 AK BETHEL BETHEL,AK -161.7558 60.79222
5 AK MATANUSKA-SUSITNA MATANUSKA-SUSITNA,AK -150.5125 61.54361
6 AK KODIAK ISLAND KODIAK ISLAND,AK -152.3539 57.80459
>
states <- readOGR("cb_2015_us_state_20m.shp",
layer = "cb_2015_us_state_20m", GDAL1_integer64_policy = TRUE)
states <- subset(states, states$STUSPS %in% c("CA"))
class(states)
leaflet(data = map_dat[map_dat$STATE %in% "CA" &
map_dat$COUNTY %in% "LOS ANGELES",]) %>%
addProviderTiles(
providers$Stamen.TonerLite,
options = providerTileOptions(noWrap = TRUE)
) %>%
addPolygons(data=states,color = "#444444", weight = 1, smoothFactor = 0.5,
opacity = 1.0, fillOpacity = 0.5,
fillColor = ~colorQuantile("YlOrRd", ALAND)(ALAND),
highlightOptions = highlightOptions(color = "white", weight = 2,
bringToFront = TRUE))
selectedCounty <- lonlat[lonlat$COUNTY == "LOS ANGELES" &&
lonlat$STATE == "CA", ]
#leafletProxy(mapId = "allmap") %>%
setView(lng = selectedCounty$lon, lat = selectedCounty$lat, zoom = 5)