Reputation: 324
I have an R script which highlights certain states on the US Map. I want to highlight two features and I have been having trouble with the 2nd feature. I attached what the current map looks like below.
Any help is much appreciated. Thanks.
#cleanup
statedata <- read.csv(file = "statebondratingsmelted.csv", header = TRUE)
head(statedata)
summary(statedata)
statedata <- subset(statedata, Year==2017)
statedata$Rank = as.numeric(levels(statedata$Rank))[statedata$Rank]
statedata$region <- tolower(statedata$region)
snames <- data.frame(region=tolower(state.name), long=state.center$x, lat=state.center$y)
snames <- merge(snames, statedata, by="region")
dtrend <- filter(mergestate, downwardtrendflag==1)
aaflag <- filter(mergestate, aa_flag==1)
us <- map_data("state")
mergestate <- merge(statedata, us, by="region")
library(ggplot2)
library(ggmap)
# Map Code
ggplot(color="black") +
geom_map(data=us, map=us, aes(long, lat, map_id=region), fill="white", color = "#000000")+
geom_map(data=dtrend, map=us, aes(fill="red", map_id=region), color ="#000000")+
geom_map(data=aaflag, map=us, aes(fill="red", map_id=region), color ="#000000")+
geom_text(data=snames, aes(long, lat, label=Rating), size=3.0, color = "black")+
coord_map()
This is the current output:
statedata <- structure(list(region = c("alabama", "alaska", "arizona", "arkansas",
"california", "colorado", "connecticut", "delaware", "florida",
"georgia", "hawaii", "idaho", "illinois", "indiana", "iowa",
"kansas", "kentucky", "louisiana", "maine", "maryland", "massachusetts",
"michigan", "minnesota", "mississippi", "missouri", "montana",
"nebraska", "nevada", "new hampshire", "new jersey", "new mexico",
"new york", "north carolina", "north dakota", "ohio", "oklahoma",
"oregon", "pennsylvania", "rhode island", "south carolina", "south dakota",
"tennessee", "texas", "utah", "vermont", "virginia", "washington",
"west virginia", "wisconsin", "wyoming"), Year = c(2017L, 2017L,
2017L, 2017L, 2017L, 2017L, 2017L, 2017L, 2017L, 2017L, 2017L,
2017L, 2017L, 2017L, 2017L, 2017L, 2017L, 2017L, 2017L, 2017L,
2017L, 2017L, 2017L, 2017L, 2017L, 2017L, 2017L, 2017L, 2017L,
2017L, 2017L, 2017L, 2017L, 2017L, 2017L, 2017L, 2017L, 2017L,
2017L, 2017L, 2017L, 2017L, 2017L, 2017L, 2017L, 2017L, 2017L,
2017L, 2017L, 2017L), Rating = structure(c(4L, 4L, 4L, 4L, 5L,
4L, 5L, 7L, 7L, 7L, 6L, 6L, 9L, 7L, 7L, 5L, 3L, 4L, 4L, 7L, 6L,
5L, 6L, 4L, 7L, 4L, 7L, 4L, 4L, 2L, 6L, 6L, 7L, 6L, 6L, 6L, 6L,
5L, 4L, 6L, 7L, 7L, 7L, 7L, 6L, 7L, 6L, 5L, 4L, 6L), .Label = c("A",
"A-", "A+", "AA", "AA-", "AA+", "AAA", "BBB", "BBB-", "N/A"), class = "factor"),
Rank = c(3, 3, 3, 3, 4, 3, 4, 1, 1, 1, 2, 2, 10, 1, 1, 4,
5, 3, 3, 1, 2, 4, 2, 3, 1, 3, 1, 3, 3, 7, 2, 2, 1, 2, 2,
2, 2, 4, 3, 2, 1, 1, 1, 1, 2, 1, 2, 4, 3, 2), downwardtrendflag = structure(c(1L,
2L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 2L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L,
1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 2L, 1L, 2L), .Label = c("0", "1", "FALSE"), class = "factor"),
aa_flag = c(0L, 0L, 0L, 0L, 1L, 0L, 1L, 0L, 0L, 0L, 0L, 0L,
1L, 0L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L,
0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L,
0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L)), .Names = c("region", "Year",
"Rating", "Rank", "downwardtrendflag", "aa_flag"), row.names = c(NA,
50L), class = "data.frame")
Upvotes: 0
Views: 3562
Reputation: 15369
The key part of the question is asking how to plot ticks. Symbols behave just like text within ggplot if you use the unicode for the symbol, and is answered previously here: Adding arrow symbols in ggplot text in R
Your problem was a bit more complex, as you wanted to plot the arrow in a different colour. This script, therefore, adds another layer to the plot for the arrows.
Your data had a column downwardtrendflag
of either 1 or 0. I have used this to make a label for the data using the unicode "\u2193". I changed the way you subset the data as it was a bit confusing.
# Assign arrow to flagged states
library(plyr)
library(ggplot2)
library(ggmap)
us <- map_data("state")
# Format the data
statedata <- subset(statedata, Year==2017)
statedata$Rank = as.numeric(levels(statedata$Rank))[statedata$Rank]
statedata$region <- tolower(statedata$region)
snames <- data.frame(region=tolower(state.name), long=state.center$x, lat=state.center$y)
snames <- merge(snames, statedata, by="region")
# Find states which have either a downward trend or aa flag
highlight <- filter(mergestate, downwardtrendflag==1 | aa_flag==1)
# Create label for snames
snames$downwardtrendflag <- mapvalues(snames$downwardtrendflag, from = c(0,1), to = c("", '\u2193'))
To plot the arrow, I have had to make another geom layer as you want the colour to be red. I have used the argument nudge_x
to offset the arrow.
# Map Code
ggplot(color="black") +
geom_map(data=us, map=us, aes(long, lat, map_id=region), fill="white", color = "#000000") +
geom_map(data=highlight, map=us, aes(map_id=region), fill="#F8766D", color ="#000000") +
geom_text(data=snames, aes(long, lat, label=Rating), size=3.0, color = "black") +
geom_text(data=snames, aes(long, lat, label=downwardtrendflag), size=3.0, color = "red", nudge_x = 2)+
coord_map() +
theme_nothing()
Visually, this map is not fantastic, as the two sets of labels conflict. You would be better off plotting the rating as a choropleth map and then overlaying the arrow on problematic states, like this:
# First we must order the levels in the factor
snames$Rating <- factor(snames$Rating, levels = rev(c("BBB-", "A-","A+","AA-","AA","AA+" ,"AAA")))
# Map Code
ggplot(color="black") +
geom_map(data=snames, map=us, aes(map_id=region, fill = Rating), color = "#000000") +
geom_map(data=highlight, map=us, aes(map_id=region), fill="#F8766D", color ="#000000") +
geom_text(data=snames, aes(long, lat, label=downwardtrendlabel), size=3.0, color = "red")+
scale_fill_brewer(palette = "Reds") +
coord_map(ylim = c(25, 50)) +
labs(title = " US States Debt Rating", subtitle = " Arrows highlights states which have a dowward trend", caption = "Source: Add source of data") +
theme_nothing(legend = TRUE)
Upvotes: 1