ggplot:使用离散变量绘制图块/矩形

时间:2019-12-09 20:25:08

标签: r ggplot2

我试图绘制图块/矩形以获得以下结果:

library(tidyverse)
library(plotly)

set.seed(0)
df <- tibble(
  a = runif(5),
  b = runif(5),
  c = runif(5),
  d = runif(5),
  case_id = 1:5
) %>% tidyr::pivot_longer(cols = -case_id)

plot <- ggplot2::ggplot(
  data = df,
  mapping = aes(
    x = name,
    y = value,
    group = case_id
  )
) + geom_point()

plot_boxes_y <- seq(from = 0, to = 1, by = .2)
plot_boxes_x <- unique(df$name) %>% length()

for (x in 1:plot_boxes_x) {
  for (y in plot_boxes_y) {
    plot <- plot + geom_rect(
      mapping = aes_(
        xmin = x - .5,
        xmax = x + .5,
        ymin = y - .5,
        ymax = y + .5
      ),
      color = "red",
      fill = NA
    ) 
  }
}

plotly::ggplotly(plot)

desired output

如您所见,我目前通过遍历坐标并分别绘制每个矩形来实现此目的。问题在于,这会生成许多层,这使得plotly::ggplotly()在大型数据集上的速度非常慢。

因此,我正在寻找一种更有效的方法。 请注意,我不能使用panel.grid,因为我打算稍后通过填充矩形来可视化z-数据。

我的方法是在散点图的上方绘制geom_tile()

# my attempt
df$z <- rep(0, nrow(df))

plot2 <- ggplot2::ggplot(
  data = df,
  mapping = aes(
    x = name,
    y = value,
    color = z,
    group = case_id
  )
) + geom_point() + geom_tile()

我认为由于name是一个离散变量这一事实而失败了吗?那么,除了散点图之外,我如何才能有效地绘制图块? 谢谢

2 个答案:

答案 0 :(得分:2)

这是使用geom_tile选项的解决方案。此处的关键是创建一个数据框以保存网格的坐标,然后在每个函数调用中分别指定外观。

library(ggplot2)
library(tidyr)

set.seed(0)
df <- tibble(
  a = runif(5),
  b = runif(5),
  c = runif(5),
  d = runif(5),
  case_id = 1:5
) %>% pivot_longer(cols = -case_id)

df$z <- rep(0, nrow(df))

#make data frame for the grid corrdinates
grid<-data.frame(x=factor( ordered( 1:4), labels = c("a", "b", "c", "d" )),
                  y=rep(seq(0, 1, .1), each=4))

#plot using geom_tile & geom_point
plot2 <- ggplot2::ggplot() + geom_tile(data=grid, aes(x=x, y=y), fill=NA, col="red") +
   geom_point(data = df,
                 mapping = aes(
                   x = name,
                   y = value,
                   color = z,
                   group = case_id)) 

print(plot2)

enter image description here

答案 1 :(得分:1)

如果您不介意它们超出轴心范围

ggplot(df,aes(x=name,y=value)) + geom_point() + 
geom_vline(xintercept=seq(0.5,4.5,by=1)) +
geom_hline(yintercept=seq(0,2,by=.2))

其他:

#make a new data frame
GRIDS = rbind(
# the vertical lines
data.frame(x=seq(0.5,4.5,by=1),xend=seq(0.5,4.5,by=1),y=0,yend=2),
# the horizontal lines
data.frame(x=0.5,xend=4.5,y=seq(0,2,by=.2),yend=seq(0,2,by=.2))
)

ggplot(df,aes(x=name,y=value)) + geom_point() +
geom_segment(data=GRIDS,aes(x=x,y=y,xend=xend,yend=yend),col="red")

enter image description here