根据因子使用不同的比例作为填充

时间:2013-12-09 15:36:34

标签: r ggplot2

cnt = 100
df <- data.frame(x = c(rnorm(cnt, mean=3), rnorm(cnt, mean=0)), y=rnorm(2 * cnt), g=rep(0:1, each=cnt))

ggplot(df, aes(x, y, color=as.factor(g))) + stat_density2d(aes(fill=..level..), alpha=.3, geom="polygon")

这会根据这样的因子创建一个填充的等高线图。 plot

我想为每个轮廓使用不同的填充比例,使得g = 0具有红色填充,而g = 1具有蓝色填充。这是可能的,如果是的话,怎么样?

1 个答案:

答案 0 :(得分:6)

正如@joran所评论的那样,ggplot中的基本设计是每个aes主题的一个比例。因此需要解决各种程度的丑陋问题。它们通常涉及创建一个或多个绘图对象,操纵对象的各个组件,然后从操纵对象生成新绘图。

这里有两个具有不同fill调色板的绘图对象 - 一个红色和一个蓝色 - 通过设置scale_fill_continuous中的颜色来创建。在“红色”绘图对象中,属于其中一个组的行中的红色填充颜色将替换为“蓝色”绘图对象中相应行的蓝色。

library(ggplot2)
library(grid)
library(gtable)

# plot with red fill
p1 <- ggplot(data = df, aes(x, y, color = as.factor(g))) +
  stat_density2d(aes(fill = ..level..), alpha = 0.3, geom = "polygon") +
  scale_fill_continuous(low = "grey", high = "red", space = "Lab", name = "g = 0") +
  scale_colour_discrete(guide = FALSE) +
  theme_classic()

# plot with blue fill
p2 <- ggplot(data = df, aes(x, y, color = as.factor(g))) +
  stat_density2d(aes(fill = ..level..), alpha = 0.3, geom = "polygon") +
  scale_fill_continuous(low = "grey", high = "blue", space = "Lab", name = "g = 1") +
  scale_colour_discrete(guide = FALSE) +
  theme_classic()


# grab plot data
pp1 <- ggplot_build(p1)
pp2 <- ggplot_build(p2)$data[[1]]


# replace red fill colours in pp1 with blue colours from pp2 when group is 2
pp1$data[[1]]$fill[grep(pattern = "^2", pp2$group)] <- pp2$fill[grep(pattern = "^2", pp2$group)]


# build plot grobs
grob1 <- ggplot_gtable(pp1)
grob2 <- ggplotGrob(p2)

# build legend grobs
leg1 <- gtable_filter(grob1, "guide-box") 
leg2 <- gtable_filter(grob2, "guide-box") 
leg <- gtable:::rbind_gtable(leg1[["grobs"]][[1]],  leg2[["grobs"]][[1]], "first")


# replace legend in 'red' plot
grob1$grobs[grob1$layout$name == "guide-box"][[1]] <- leg


# plot
grid.newpage()
grid.draw(grob1)

enter image description here