【问题标题】:ggplot - panel borders alternating black and white rectanglesggplot - 面板边框交替黑白矩形
【发布时间】:2019-02-25 14:16:10
【问题描述】:

使用 ggplot,有没有办法通过黑白矩形交替设置面板边框,如下所示:

【问题讨论】:

  • 据我所知,不是设计使然,但(与 ggplot 相关的许多其他事情一样)可能是可破解的。
  • 给定的绘图有匹配黑色/白色矩形的网格线,绘图之外的数字?你也需要这些功能吗?
  • 是的,我希望矩形与图外的数字匹配
  • 这不会是“在边界上”,但这个想法可能会让你接近:df <- data.frame(x = 1:10, y = 1:10); rects <- data.frame(x_start = seq(1, 10, 2), x_end = seq(1, 10, 2) + 1); ggplot() + geom_rect(data = rects, aes(xmin = x_start, xmax = x_end, ymin = -Inf, ymax = +Inf), fill = "blue", alpha = 0.25) + geom_rect(data = rects, aes(xmin = -Inf, xmax = +Inf, ymin = x_start, ymax = x_end), fill = "red", alpha = 0.25) + geom_line(data = df, aes(x, y)); 它基本上会在你指定的时间间隔内创建一个“棋盘”。

标签: r ggplot2


【解决方案1】:

这很长,但这里是制作边框网格的方法。您可以重复使用此代码,而无需在不同地图之间进行重大更改,只更新您为最小、最大和纬度和经度间隔定义的值。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-29
    • 2017-05-17
    • 1970-01-01
    • 2016-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多