答案 0 :(得分:7)
这很长,但是这里是制作边框的方法。您可以重用此代码,而不必在不同的地图之间进行重大更改,只需更新您定义的最小,最大和纬度和经度间隔的值即可。
require(ggplot2)
require(maps)
world <- map_data("world2") #get map data
首先,定义纬度和经度的最小,最大和网格间隔。这些数字将用于为边框网格矩形创建数据框,并在绘图中创建轴断点和界限。
min.lat <- -40
max.lat <- 40
interval.lat <- 20
min.long <- 0
max.long <- 90
interval.long <- 30
接下来,创建两个数据框,其中包含将形成网格的矩形的坐标,一个数据框用于黑色矩形,一个数据框用于白色矩形。为每种网格矩形颜色创建了单独的数据框,因此您无需使用scale_fill_manual()
进行边界网格填充,因此可以根据需要对数据使用填充美学。编写此代码都是为了使用上面定义的值,而不是实际数字,因此,您无需更改下面的代码即可绘制不同区域的地图,只需更新上面定义的值即可。>
#define a constant (scaled to map size) width for grid rectangles
#may need to adjust number to get width you prefer
grid.width <- (max.lat - min.lat)/90
is.even <- function(x) x %% 2 == 0 #function to test if number is even
#dataframe of longitude rectangles
rects.long <- data.frame(x_start = rep(seq(min.long, max.long - interval.long,
by = interval.long), 2))
rects.long$x_end <- rects.long$x_start + interval.long
rects.long$y_start <- c(rep(min.lat, nrow(rects.long)/2),
rep(max.lat - grid.width, nrow(rects.long)/2))
rects.long$y_end <- c(rep(min.lat + grid.width, nrow(rects.long)/2),
rep(max.lat, nrow(rects.long)/2))
rects.long$color <- if(is.even(nrow(rects.long)/2)) { #even/odd test
rep(c("black", "white"), nrow(rects.long)/2) #pattern for even
} else {
rep(c(rep(c("black", "white"), (nrow(rects.long) - 2)/4),"black"), 2)} #odd
#dataframe of latitude rectangles
rects.lat <- data.frame(y_start = rep(seq(min.lat, max.lat - interval.lat,
by = interval.lat), 2))
rects.lat$y_end <- rects.lat$y_start + interval.lat
rects.lat$x_start <- c(rep(min.long, nrow(rects.lat)/2),
rep(max.long - grid.width, nrow(rects.lat)/2))
rects.lat$x_end <- c(rep(min.long + grid.width, nrow(rects.lat)/2),
rep(max.long, nrow(rects.lat)/2))
rects.lat$color <- if(is.even(nrow(rects.lat)/2)) { #even/odd test
rep(c("black", "white"), nrow(rects.lat)/2) #pattern for even
} else {
rep(c(rep(c("black", "white"), (nrow(rects.lat) - 2)/4),"black"), 2)} #odd
#combine latitude and longitude grid
rects.grid <- rbind(rects.lat, rects.long)
#split into black dataframe and white dataframe
rects.black <- rects.grid[rects.grid$color == "black",]
rects.white <- rects.grid[rects.grid$color == "white",]
最后,让你的情节!
#define axis breaks to match grid
axis.breaks.x <- seq(min.long, max.long, interval.long)
axis.breaks.y <- seq(min.lat, max.lat, interval.lat)
ggplot(data = world) +
geom_polygon(aes(x = long, y = lat, group = group),
color = "black", fill = "gray50") +
#set limits to your previously defined limits
coord_fixed(1, xlim = c(min.long, max.long), ylim = c(min.lat, max.lat),
expand = FALSE) +
#define breaks same as grid, duplicate axes for lat/long labels on all sides
scale_y_continuous(breaks = axis.breaks.y, sec.axis = dup_axis()) +
scale_x_continuous(breaks = axis.breaks.x, sec.axis = dup_axis()) +
#use geom_rect() to add border grid
geom_rect(data = rects.white, inherit.aes = FALSE, #white grid rectangles
aes(xmin = x_start, xmax = x_end, ymin = y_start, ymax = y_end),
color = "black", fill = "white") +
geom_rect(data = rects.black, inherit.aes = FALSE, #black grid rectangles
aes(xmin = x_start, xmax = x_end, ymin = y_start, ymax = y_end),
color = "black", fill = "black") +
theme_minimal() + #theme edits to make plot look like a map
theme(axis.title = element_blank(),
legend.position = "none")
这是一项测试,以检查此代码在不同的限制和间隔下是否有效:
min.lat <- -10
max.lat <- 50
interval.lat <- 10
min.long <- 60
max.long <- 150
interval.long <- 15
#run same code as above to create grid dataframes and plot