I want to plot Electric grid map for U.S. So I need to merge specific states together . I want to plot border for those state together but it not working. Also just one label per each group. This is my data : [https://iastate.box.com/s/12xru62lvmbbkrohsn7b4wwexq11umn7] This is my code:
# Join and arrange
states <- us_map(exclude = c("AK", "HI"))
states_data <- left_join(states, myinput, by = c("abbr" = "region")) |>
arrange(emission, growth, group, order)
ggplot(states_data, aes(x, y, fill = value, group = group, subgroup = grid))
geom_polygon()
scale_fill_continuous(low = "white", high = "red", name = "Ele gen (EJ)", label =
scales::comma)
facet_grid(emission~growth)
coord_equal()
ggthemes::theme_map()
theme(legend.position = "bottom")
geom_text(aes(x, y, label = grid),size = 5,family = "serif",
data = states_data, vjust = 1.2, nudge_y = -100000,check_overlap = T)
geom_polygon(aes(color = "Border", group=grid),fill = NA,color = "black")
And this the output which is not what I have in my mid:
I want to plot these regions (plus borders to specify because I can't show them with different color)
CodePudding user response:
I couldn't find an overly simple way of making this happen, but I can help you make it happen.
First, I calculated the median x and y for each of the groups and facets.
mm <- states_data %>%
group_by(growth, emission, grid) %>%
summarise(x = median(x), y = median(y))
Then I looked for the closest line row of data that matched these coordinates for placing the label. I created a function, a vector of NA (to be updated), and then went through each of the medians to find the corresponding row in the data (states_data
). This creates another column for the data, but the grid strings are only in the rows that were identified as the quasi-center of each grid.
mdist <- function(mm, df1) { #vector mm contains medians; df1 contains points to compare
x = mm$x
y = mm$y
df2 <- df1 %>% mutate(rn = 1:nrow(.)) %>%
filter(grid == mm$grid, growth == mm$growth, emission == mm$emission)
df3 <- data.frame(V1 = sqrt((abs(df2$x) - abs(x))^2 (abs(df2$y) - abs(y))^2),
rn = df2$rn,
grid = mm$grid) %>%
filter(V1 == min(V1))
return(df3[1, ])
}
arr <- rep(NA, nrow(states_data))
invisible(
map(1:nrow(mm),
function(j) {
gimme <- mdist(mm[j, ], states_data)
arr[gimme$rn] <<- gimme$grid
}))
Now, this column grid2
is used for the labels.
I noticed that you have group and subgroup in your call for ggplot
. However, your subgroup has more divisions than group, that's what's causing the scribbling (for lack of a better word). This is what I mean:
I switched the group/subgroup calls in ggplot
for this reason. (You may have wanted that, so I just wanted to explain what and why I did what I did.)
I also noticed that your grid is on top of the text and the same color, which sort of drowns out the words. You used nudge_y
, but I think you might get a bit more bang with hjust
, as well.
This is what I used:
ggplot(states_data, aes(x, y, fill = value, subgroup = group, group = grid))
geom_polygon()
scale_fill_continuous(low = "white", high = "red", name = "Ele gen (EJ)", label =
scales::comma)
facet_grid(emission~growth)
coord_equal()
ggthemes::theme_map()
theme(legend.position = "bottom")
geom_polygon(aes(color = "Border", group = grid),fill = NA, color = "lightgray")
geom_text(aes(label = grid2),size = 4, family = "serif", fontface = "bold",
data = states_data, vjust = 1.2, hjust = .5, check_overlap = T)
It's not perfect. You're right-most labels are still running off the "page". However, this should get you going in the right direction.
CodePudding user response:
Similarly to the thread ggplot centered names on a map, you can use the ggh4x package for that.
library(ggh4x)
#> Loading required package: ggplot2
library(dplyr)
myinput <- readxl::read_excel("your data path")
states <- usmap::us_map(exclude = c("AK", "HI"))
states_data <- left_join(states, myinput, by = c("abbr" = "region")) |>
arrange(emission, growth, group, order)
## changing the group and subgroup
ggplot(states_data, aes(x, y, fill = value, group = grid, subgroup = group))
geom_polygon()
scale_fill_continuous(low = "white", high = "red", name = "Ele gen (EJ)", label =
scales::comma)
facet_grid(emission~growth)
coord_equal()
ggthemes::theme_map()
## using ggh4x
stat_midpoint(aes(label = grid), geom = "text", size=2, check_overlap = T)
theme(legend.position = "bottom")
geom_polygon(aes(color = "Border", group=grid),fill = NA,color = "black")