Insert US State abbreviation on Map togeter numbers with ggplot2 - r

I have the following data set:
Then with this code:
ggplot(data= data.to.work.final, aes(map_id = State_L)) +
geom_map(aes(fill = Suicide_Rate_By_Pop), color= "white", map = fifty_states) +
expand_limits(x = fifty_states$long, y = fifty_states$lat) +
coord_map() +
geom_text(data = fifty_states %>%
group_by(id) %>%
summarise(lat = mean(c(max(lat), min(lat))),
long = mean(c(max(long), min(long)))) %>%
mutate(State_L = id) %>%
left_join(data.to.work.final, by = "State_L"), size=2,
aes(x = long, y = lat, label = Suicide_Rate_By_Pop)
#aes(x = long, y = lat, label = state)
) +
scale_x_continuous(breaks = NULL) +
scale_y_continuous(breaks = NULL) +
labs(x = "", y = "") +
labs(fill = "Suicides Rate by 100,000 inhabitants")+
scale_fill_gradientn(colours=rev(heat.colors(10)),na.value="grey90",
guide = guide_colourbar(barwidth = 25, barheight = 0.4,
#put legend title on top of legend
title.position = "top")
) +
theme(legend.position = "bottom",
legend.title=element_text(size=10),
legend.text=element_text(size=08))
I produced the following map of us with suicide rate inside of each state:
I would like to insert the abbreviation of each state and below the suicide rate, like:
CA
1433
Somebody would help please?**

Related

Overlap map created in ggplot and shapefile

I am trying to overlap a shp layer on a map created with ggplot, when I plot the two graphs are independent, what do you suggest me to do to overlap both layers?
data.shape<-readOGR(dsn="departamentos",layer="DEPARTAMENTOS")
ggplot()+
geom_tile(data = tx_trend, aes(x = longitude, y = latitude, fill = slope))+
scale_fill_gradientn(colors = rev(pals::linearlhot(100)), name = "ºC/10y", limits = c(0.1,0.5)) +
#scale_fill_gradientn(colors = (pals::isol(100)), name = "ºC/10y", limits = c(0.1,0.45)) +
# geom_point(data = filter(tx_trend, sign < 0.01),aes(x = longitude, y = latitude, color = "Sign. trend \n p-value <0.01"),
geom_point(data = filter(tx_trend, sign < 0.01),aes(x = longitude, y = latitude, color = "Sign. trend \n p-value <0.01"),
size = 0.7, show.legend = T) +
scale_color_manual(values = c("black"), name = "")+
coord_fixed(1.3)+
xlab("Longitude") + ylab("Latitude")+
labs(title = "Decadal trend Summer",
subtitle = "(1981-2016)",
caption = "")+
theme_bw() +
guides(fill = guide_colourbar(barwidth = 9, barheight = 0.5, title.position="right"))+
theme(legend.position = "bottom")
Difficult without a reproducible example but I give it a try! So here are my suggestions:
Install the 'sf' package with install.packages("sf") and load library with library(sf)
Import your layer in sf format with st_read():
data.shape <- st_read(dsn="departamentos", layer="DEPARTAMENTOS")
Use the dedicated geom_sf() to plot your shape on your tile and point layers. You just need to add the following line of code in the ggplot() chunk of code:
geom_sf(data = st_geometry(data.shape), fill = NA, color = "red") +
coord_sf(default_crs = sf::st_crs(4326)) +
So I suggest:
ggplot()+
geom_tile(data = tx_trend, aes(x = longitude, y = latitude, fill = slope))+
scale_fill_gradientn(colors = rev(pals::linearlhot(100)), name = "ºC/10y", limits = c(0.1,0.5)) +
#scale_fill_gradientn(colors = (pals::isol(100)), name = "ºC/10y", limits = c(0.1,0.45)) +
# geom_point(data = filter(tx_trend, sign < 0.01),aes(x = longitude, y = latitude, color = "Sign. trend \n p-value <0.01"),
geom_point(data = filter(tx_trend, sign < 0.01),aes(x = longitude, y = latitude, color = "Sign. trend \n p-value <0.01"),
size = 0.7, show.legend = T) +
geom_sf(data = st_geometry(data.shape), fill = NA, color = "red") + # ADDED HERE
coord_sf(default_crs = sf::st_crs(4326)) + # ADDED HERE
scale_color_manual(values = c("black"), name = "")+
coord_fixed(1.3)+
xlab("Longitude") + ylab("Latitude")+
labs(title = "Decadal trend Summer",
subtitle = "(1981-2016)",
caption = "")+
theme_bw() +
guides(fill = guide_colourbar(barwidth = 9, barheight = 0.5, title.position="right"))+
theme(legend.position = "bottom")

Add label in ggplot

My code with the following output (below in the picture) calculates the average price of the neighbourhood groups.
Beside the mean I also want to add the median price label. How should I add this information to the graph?
{r }
p.nbr <- ny_explor %>%
group_by(neighbourhood_group) %>%
summarise(price = round(mean(price), 2))
ggplot(ny_explor, aes(price)) +
geom_histogram(bins = 30, aes(y = ..density..), fill = "darkslategrey") +
geom_density(alpha = 0.2, fill = "darkslategrey") +
theme_bw() +
ggtitle("Distribution of price by neighbourhood groups",
subtitle = expression("With" ~'log'[10] ~ "transformation of x-axis")) +
geom_vline(data = p.nbr, aes(xintercept = price), size = 2, linetype = 3) +
geom_text(data = p.nbr,y = 1.5, aes(x = price + 1400, label = paste("Mean = ",price)), color = "saddlebrown", size = 4) +
facet_wrap(~neighbourhood_group) +
scale_x_log10()
Though it would have been easier if you could include some sample data, yet it is advised that your existing code may be modified like this, which may work. If not, please incluide some sample data
p.nbr <- ny_explor %>%
group_by(neighbourhood_group) %>%
summarise(price_mean = round(mean(price), 2),
price_median = median(price))
ggplot(ny_explor, aes(price_mean)) +
geom_histogram(bins = 30, aes(y = ..density..), fill = "darkslategrey") +
geom_density(alpha = 0.2, fill = "darkslategrey") +
theme_bw() +
ggtitle("Distribution of price by neighbourhood groups",
subtitle = expression("With" ~'log'[10] ~ "transformation of x-axis")) +
geom_vline(data = p.nbr, aes(xintercept = price_mean), size = 2, linetype = 3) +
geom_text(data = p.nbr,y = 1.5, aes(x = price_mean + 1400, label = paste("Mean = ",price_mean),
"/nMedian = ", price_median), color = "saddlebrown", size = 4) +
facet_wrap(~neighbourhood_group) +
scale_x_log10()

barplot with lineplot - secondary axis

After referring to multiple links i have got to the below code however i still am not succeeding to get the line with labels. I suspect some mistake in sec.axis transformation but i can't figure it out.
# dummy data
df_dummy = data.frame('Plan_code'=c('A','B','C','D','E','F','G'),
'Total'=c(191432,180241,99164,58443,56616,29579,19510),'STP'=c(41,40,44,37,37,37,45))
# creation of plot
[![g <- ggplot(data = df_dummy, aes(x = Plan_code, y = Total)) +
geom_col(aes(fill = 'Total')) +
geom_line(data = df_dummy, aes(x = Plan_code, y = STP,group=1)) +
geom_point(data = df_dummy, aes(x = Plan_code,y=STP)) +
geom_label(data = df_dummy, aes(x = Plan_code, y = STP, fill = Plan_code, label = paste0('%', STP)), color = 'white', vjust = 1.6, size = 3) +
scale_y_continuous(sec.axis = sec_axis(~. / 2000, name = 'PERCENT')) +
labs(fill = NULL, color = NULL) +
theme_minimal()
print(g)][1]][1]
Like that?
g <- ggplot(data = df_dummy, aes(x = Plan_code, y = Total)) +
geom_col(aes(fill = 'Total')) +
geom_point(data = df_dummy, aes(x = Plan_code,y=STP * 2000)) +
geom_label(data = df_dummy, aes(x = Plan_code, y = STP *2000, fill = Plan_code, label = paste0('%', STP)), color = 'white', vjust = 1.6, size = 3) +
scale_y_continuous(sec.axis = sec_axis(~. / 2000, name = 'PERCENT'))+
geom_line(data = df_dummy, aes(x = Plan_code, y = STP * 2000,group=1), col = 'blue') +
theme(axis.text.y.right = element_text(color = 'blue'),axis.title.y.right = element_text(color = 'blue'))
labs(fill = NULL, color = NULL) +
theme_minimal()
I just multiplied your data with 2000, so that the absolute y-coordinates were right.
And I changed the color.

Control colour of geom_text_repel

I would like to change the colour of one of my ggrepel labels to black. I have tried to override the inheritance by specifying ...geom_text_repel(...colour='black') but that doesn't seem to work.
My attempt at a fix to the problem is in the second geom_text_repel function (below).
N.B. If there is a way to control the colour of individual geom_text_repel elements, rather than having to call the function twice, I would prefer that.
library("tidyverse")
library("ggthemes")
library("ggrepel")
df1 <- gather(economics, variable_name, observation, -date) %>%
rename(period = date) %>%
filter(variable_name == 'psavert')
df2 <- gather(economics, variable_name, observation, -date) %>%
rename(period = date) %>%
filter(variable_name == 'uempmed')
ggplot(df1, aes(x = period, y = observation, colour = variable_name)) +
geom_line() +
geom_line(data = df2, colour = 'black', size = .8) +
geom_text_repel(
data = subset(df1, period == max(as.Date(period, "%Y-%m-%d"))),
aes(label = variable_name),
size = 3,
nudge_x = 45,
segment.color = 'grey80'
) +
geom_text_repel(
data = subset(df2, period == max(as.Date(period, "%Y-%m-%d"))),
aes(label = variable_name, colour = 'black'), #How do I set the colour of the label text to black?
size = 3,
nudge_x = 45,
segment.color = 'grey80'
) +
scale_y_continuous(labels = scales::comma) +
theme_minimal(base_size = 16) +
scale_color_tableau() +
scale_fill_tableau() +
theme(legend.position = 'none') +
labs(x="", y="", title = "Economic Data") +
scale_x_date(limits = c(min(df1$period), max(df1$period) + 1200))
Do the same thing you did in your geom_line() layer. You want to set a color, not a mapping. Make colour = 'black' an argument to geom_text_repel(), not aes().
ggplot(df1, aes(x = period, y = observation, colour = variable_name)) +
geom_line() +
geom_line(data = df2, colour = 'black', size = .8) + # just like this layer
geom_text_repel(
data = subset(df1, period == max(as.Date(period, "%Y-%m-%d"))),
aes(label = variable_name),
size = 3,
nudge_x = 45,
segment.color = 'grey80'
) +
geom_text_repel(
data = subset(df2, period == max(as.Date(period, "%Y-%m-%d"))),
aes(label = variable_name) # don't assign it here,
size = 3,
nudge_x = 45,
segment.color = 'grey80',
colour = "black" # assign it here
) +
scale_y_continuous(labels = scales::comma) +
theme_minimal(base_size = 16) +
scale_color_tableau() +
scale_fill_tableau() +
theme(legend.position = 'none') +
labs(x="", y="", title = "Economic Data") +
scale_x_date(limits = c(min(df1$period), max(df1$period) + 1200))
Note that now the first line AND text are now both set manually to "black", so the automatic variable assignment will start over with next line (and text). If you want to set that manually to a different color, you can use the same strategy (set it as an argument to the geom, not as an argument to aes

How to map all the states of US using R with the number of crimes occurred in each state?

I am still learning about R and I want to map the States of US with the labels of number of crimes occurred in each state. I want to create the below image.
I used the below code which was available online but I could not label the No of crimes.
library(ggplot2)
library(fiftystater)
data("fifty_states")
crimes <- data.frame(state = tolower(rownames(USArrests)), USArrests)
p <- ggplot(crimes, aes(map_id = state)) +
# map points to the fifty_states shape data
geom_map(aes(fill = Assault), map = fifty_states) +
expand_limits(x = fifty_states$long, y = fifty_states$lat) +
coord_map() +
scale_x_continuous(breaks = NULL) + scale_y_continuous(breaks = NULL) +
labs(x = "", y = "") + theme(legend.position = "bottom",
panel.background = element_blank())
Please can someone help me ?
To add text to a plot (map in this case) one needs the text label and the coordinates of the text. Here is an approach with your data:
library(ggplot2)
library(fiftystater)
library(tidyverse)
data("fifty_states")
ggplot(data= crimes, aes(map_id = state)) +
geom_map(aes(fill = Assault), color= "black", map = fifty_states) +
expand_limits(x = fifty_states$long, y = fifty_states$lat) +
coord_map() +
geom_text(data = fifty_states %>%
group_by(id) %>%
summarise(lat = mean(c(max(lat), min(lat))),
long = mean(c(max(long), min(long)))) %>%
mutate(state = id) %>%
left_join(crimes, by = "state"), aes(x = long, y = lat, label = Assault ))+
scale_x_continuous(breaks = NULL) + scale_y_continuous(breaks = NULL) +
labs(x = "", y = "") + theme(legend.position = "bottom",
panel.background = element_blank())
Here I used the Assault number as label and mean of the maximum and minimum of lat and long coordinates of each state as text coordinates. The coordinates could be better for some states, one can add them by hand or use chosen city coordinates.
EDIT: with the updated question:
First select the year and type of crime and aggregate the data
homicide %>%
filter(Year == 1980 & Crime.Type == "Murder or Manslaughter") %>%
group_by(State) %>%
summarise(n = n()) %>%
mutate(state = tolower(State)) -> homicide_1980
and then plot:
ggplot(data = homicide_1980, aes(map_id = state)) +
geom_map(aes(fill = n), color= "black", map = fifty_states) +
expand_limits(x = fifty_states$long, y = fifty_states$lat) +
coord_map() +
geom_text(data = fifty_states %>%
group_by(id) %>%
summarise(lat = mean(c(max(lat), min(lat))),
long = mean(c(max(long), min(long)))) %>%
mutate(state = id) %>%
left_join(homicide_1980, by = "state"), aes(x = long, y = lat, label = n))+
scale_x_continuous(breaks = NULL) + scale_y_continuous(breaks = NULL) +
labs(x = "", y = "") + theme(legend.position = "bottom",
panel.background = element_blank())
If one wants to compare all years I suggest doing it without text since it will be very cluttered:
homicide %>%
filter(Crime.Type == "Murder or Manslaughter") %>%
group_by(State, Year) %>%
summarise(n = n()) %>%
mutate(state = tolower(State)) %>%
ggplot(aes(map_id = state)) +
geom_map(aes(fill = n), color= "black", map = fifty_states) +
expand_limits(x = fifty_states$long, y = fifty_states$lat) +
coord_map() +
scale_x_continuous(breaks = NULL) + scale_y_continuous(breaks = NULL) +
labs(x = "", y = "") + theme(legend.position = "bottom",
panel.background = element_blank())+
facet_wrap(~Year, ncol = 5)
One can see not much has changed during the years.
I trust a more informative plot is:
homocide %>%
filter(Crime.Type == "Murder or Manslaughter") %>%
group_by(State, Year) %>%
summarise(n = n()) %>%
mutate(state = tolower(State)) %>%
ggplot()+
geom_line(aes(x = Year, y = n))+
facet_wrap(~state, ncol = 6, scales= "free_y")+
theme_bw()

Resources