I'm trying to create a map of the world and US states, colored by some categorical variable. My idea was to draw the world map, then draw the US state map over it:
library(maps)
library(ggplot2)
library(dplyr)
states_map <- map_data("state")
world_map <- map_data("world")
world_map <- world_map %>%
filter(region != "Antarctica")
states <- c("texas")
world <- c("Alaska",
"Canada",
"France")
world_map$region <- ifelse(world_map$subregion == "Alaska", "Alaska", world_map$region)
world_map$status <- ifelse(world_map$region %in% world, TRUE, FALSE)
states_map$status <- ifelse(states_map$region %in% states, TRUE, FALSE)
ggplot() +
geom_map(aes(map_id = region, fill = status),
map = world_map,
data = world_map,
color = "black") +
geom_map(aes(map_id = region, fill = status),
map = states_map,
data = states_map,
color = "black") +
expand_limits(x = world_map$long, y = world_map$lat)
But none of France is colored correctly, and most of Canada isn't (some of the islands are):
Any idea where I'm going wrong here? Note that if you remove Canada from "world", all goes well...
The problem is that the country data set you are using is ill suited for this purpose. It contains many overlapping shapes which causes issues with colouring, and countries are poorly labeled
France proper is actually group 558, and has no data in it's region or sub-region column:
ggplot() +
geom_map(aes(map_id = region, fill = status),
map = world_map[world_map$group == 558,],
data = world_map[world_map$group == 558,],
color = "black") +
expand_limits(x = world_map$long, y = world_map$lat)
This is also under a few shapes that describe Europe, which hide it's colouring even if you directly colour group 558.
map_data("world2") does not seem to have this problem, but the perspective used is different:
I would suggest downloading better documented shapefiles, and using those to map instead.
Related
I'm trying to build a map showing a gradient of scores attributed to a selection of countries, these scores are stored in a dataframe (scores) alongside the corresponding country name:
Country Score
United States 0.4
France 0.2
India 0.6 etc.
I've tried the following (based on How do you get geom_map to show all parts of a map?) but get an error (Error in FUN(X[[i]], ...) : object 'region' not found)
world_map <- map_data('world')
gg <- ggplot(scores) +
geom_map(dat = world_map, map = world_map, aes(map_id = region),
fill = 'white', color = 'black' +
geom_map(map = world_map, aes(map_id = region, fill = Score)
Grateful for any help as I can't seem to get anywhere with this.
Based on the question you linked, you should be calling upon Country and Score in your second geom_map call. Also there are a few parentheses missing from your code and please note that world_map uses "USA", not "United States".
library(maps)
library(tidyverse)
scores <- read_table("
Country Score
USA 0.4
France 0.2
India 0.6")
world_map <- map_data("world")
gg <- ggplot(scores) +
geom_map(dat=world_map, map=world_map,
aes(map_id=region), fill="white", color="black") +
geom_map(map=world_map,
aes(map_id=Country, fill=Score), color="black") +
expand_limits(x = world_map$long, y = world_map$lat)
gg
Suppose I have a dataframe with every country and infection rates:
country infection
Sweden 1332
Norway 24
USA 24224
UK 53534
Is there a way to obtain a simple world map and on that plot bubbles on each country that vary in size depending on the infection rate proportions? E.g. in this case the UK would have the largest bubble and Norway the smallest.
Here's an approach with ggplot2 and the wonderful ggh4x package by #teunbrand.
library(dplyr)
library(ggplot2)
library(ggh4x)
WorldMap <- map_data("world") %>%
filter(region != "Antarctica") %>%
fortify
WorldData <- left_join(WorldData,data, by = c("region" = "country"))
ggplot(WorldData, aes(x = long, y = lat, group = group)) +
geom_polygon(color="black", fill="white") +
stat_centroid(data = subset(WorldData, region %in% data$country),
aes(size = infection, group = region),
geom = "point",
alpha = 0.75, color = "red")
The reason the point for the US is in a strange place is because of Alaska and all of the non-continental territories. Good luck fixing that.
Hi I'm trying to plot the map of King County in Washington because I'm having few data points which need to be placed in the map. The following is what I used.
long <- c(47.5112,47.7210 ,47.3684,44)
lat <- c(-122.257, -122.319, -122.031,-120)
price <- c(287655,456355,662500,234563)
House <- data.frame(long, lat, price)
states <- map_data("state")
# west_coast <- states %>%
# filter(region %in% c("washington"))
wa_df <- states %>%
filter(region == "washington", subregion == 'king')
counties <- map_data("county")
wa_county <- counties %>%
filter(region == "washington", subregion == 'king')
wa_base <-
ggplot(data = wa_df,
mapping = aes(x = long, y = lat, group = group)) +
geom_point(
data = House,
mapping = aes(x = long, y = lat),
color = "red",
inherit.aes = FALSE
) +
coord_fixed(1.3) +
geom_polygon(color = "black", fill = "gray")
#geom_point(data = House, mapping = aes(x = long, y = lat), color = "red")
wa_base + theme_nothing() +
geom_polygon(data = wa_county, fill = NA, color = "black") +
geom_polygon(color = "black", fill = NA) # get the state border back on top
The following is the map I received. I do not find that the map looks good. Please help
I am new to R and this is my first response, but I might have found a solution to this problem. The boundaries downloaded from the maps package are not exact. You can download correct boundary data as a shapefile here: https://gis-kingcounty.opendata.arcgis.com/datasets/kingcounty::king-county-political-boundary-no-waterbodies-kingco-area/explore?location=47.477749%2C-121.920728%2C9.83
Use:
library(ggmap)
library(mapdata)
library(rgdal)
library(tidyverse)
After that, read the shapefile into R and use map_data() to convert it into a data frame:
kc_bound <- readOGR(dsn="~/Desktop/King_County",layer="King_County_Political_Boundary_(no_waterbodies)___kingco_area")
kc_bound_df <- map_data(kc_bound)
Assuming that you also work on the house price prediction data set from kaggle (https://www.kaggle.com/harlfoxem/housesalesprediction) you can run the following code to get a plot of the houses with the King County boundary around it (df is your data frame):
ggplot() + geom_point(df,mapping=aes(x=long,y=lat),color="red") + geom_polygon(kc_bound_df,mapping=aes(x=long,y=lat),fill=NA, color="black")
See this picture for the result: Houses in King County plotted with county boundary
Hope this helps, let me know what you think!
I want to visualize violent crimes by county in North Carolina
My dataset looks a little like this:
subregion violent_crime
alamance 396.39
alexander 130.38
alleghany 137.48
anson 513.65
ashe 78.32
avery 138.51
beaufort 328.74
...
Here is my code - so far only the map of North Carolina and its county lines are visualizing.
I was attempting to use only ggplot and maps but I'm running into dead ends
...
library(plotly)
library(ggplot2)
library(maps)
library(dplyr)
crime.df <- read.csv(file="B:/Data/visualization/violent_crimes.csv", header=TRUE, sep=",")
vcdExtra::datasets
nc <- subset(states, region == "north carolina")
head(nc)
counties <- map_data("county")
nc_county <- subset(counties, region == "north carolina")
head(nc_county)
choropleth <- inner_join(nc_county, crime.df, by = "subregion")
choropleth <- chloropleth[!duplicated(chloropleth$order),]
ggplot(data = nc, mapping = aes(x = long, y = lat, group = group)) +
coord_fixed(1.2) +
geom_polygon(color = "black", fill = "gray") +
geom_polygon(data = nc_county, fill = NA, color = "white") +
geom_polygon(color = "black", fill = NA)
...
Thanks!
library(ggplot2)
library(dplyr)
# Get NC counties
nc_map <- tbl_df(map_data("county", region = "north carolina"))
# Simulate data since you didn't use dput() as the R section of SO instructs you to do
set.seed(1492)
data_frame(
subregion = unique(nc_map$subregion),
crime = sample(50:500, length(unique(nc_map$subregion)))
) -> crime_df
# Join the values to the map
nc_map <- left_join(nc_map, crime_df)
# Plot it
ggplot() +
geom_polygon(data=nc_map, color="black",
aes(x=long, y=lat, group=subregion, fill=crime)) +
viridis::scale_fill_viridis(name="Crime ", direction=-1) +
coord_map("polyconic") +
ggthemes::theme_map() +
theme(legend.position="bottom")
Consider:
Binning the crime data into ~5 groups
Ensuring you're using per-capita info (based on county population since you're focusing on NC)
Using dput() as the SO R section instructs so you can include data
Trying to isolate errors and provide better error descriptions
Reading up on projections and try using ggalt::coord_proj() with this PROJ.4 string: +proj=aea +lat_1=34.0207760236743 +lat_2=36.37811477607033 +lon_0=-80.716552734375 vs my lazy way out example.
I'm trying to plot ecological distribution of some species of organisms I'm studying over the Arabian/Persian Gulf. Here is a sample of a code I've tried:
Backround layer
library(ggplot2)
library(ggmap)
nc <- get_map("Persian Gulf", zoom = 6, maptype = 'terrain', language = "English")
ncmap <- ggmap(nc, extent = "device")
Other layers
ncmap+
stat_density2d(data=sample.data3, aes(x=long, y=lat, fill=..level.., alpha=..level..),geom="polygon")+
geom_point(data=sample.data3, aes(x=long, y=lat))+
geom_point(aes(x =50.626444, y = 26.044472), color="red", size = 4)+
scale_fill_gradient(low = "green", high = "red") + scale_alpha(range = c(0.00, 0.25), guide = FALSE)
but, I will like to use the stat_density2d to show the distributions of hundreds of species (which are recorded in columns e.g SP1....SPn) over the water body rather than just displaying latitude and longitude.
Also, is it possible to restrict my heat map to just the water body?
I'll appreciate any help and recommendations I can get on this please
My approach to your question is a pragmatic one: simply put the layer of gulf countries over the heatmap distribution. This crops the heatmap accordingly. Note, however, that the heatmap is still calculated as if it weren't cropped. That means the density calculation is not restricted to the water body only, but it is simply cropped visually.
For the sake of reproducibility, the following code assumes that you've unzipped the .rar file provided by #Hammao and execute the code in the resulting Persian Gulf folder.
# get sample data
sample.data <- read.csv("sample.data3.csv")
Now, we need to get the country shapes for the Gulf countries. I use the rworldmap package for this.
# loading country shapes
library(rworldmap)
# download map of the world
worldmap <- getMap(resolution = "high") # note that for 'resolution="high"'
# you also need the "rworldxtra" pkg
# extract Persian Gulf countries...
gulf_simpl <- worldmap[worldmap$SOVEREIGNT == "Oman" |
worldmap$SOVEREIGNT == "Qatar" |
worldmap$SOVEREIGNT == "United Arab Emirates" |
worldmap$SOVEREIGNT == "Bahrain" |
worldmap$SOVEREIGNT == "Saudi Arabia" |
worldmap$SOVEREIGNT == "Kuwait" |
worldmap$SOVEREIGNT == "Iraq" |
worldmap$SOVEREIGNT == "Iran", ]
# ... and fortify the data for plotting in ggplot2
gulf_simpl_fort <- fortify(gulf_simpl)
# Now read data for the Persian Gulf, which we need to get the distances for
# the extension of the map
PG <- readOGR(dsn = ".", "iho")
PG <- readShapePoly("iho.shp")
PG <- fortify(PG)
Now, it's simply a matter of plotting the layers in the correct order.
# generate plot
ggplot(sample.data) +
# first we plot the density...
stat_density_2d(aes(x = long, y = lat,
fill = ..level..),
geom="polygon",
alpha = 0.5) +
# ... then we plot the points
geom_point(aes(x = long, y = lat)) +
# gradient options
scale_fill_gradient(low = "green", high = "red") +
scale_alpha(range = c(0.00, 0.25), guide = FALSE) +
# and now put the shapes of the gulf states on top
geom_polygon(data = gulf_simpl_fort,
aes(x = long,
y = lat, group = group),
color = "black", fill = "white",
inherit.aes = F) +
# now, limit the displayed map only to the gulf
coord_equal(xlim = c(min(PG_fort$long), max(PG_fort$long)),
ylim = c(min(PG_fort$lat), max(PG_fort$lat))) +
theme_bw()