使用ggplot2创建散点图矩阵,并且按照面板变化使用不同的主题。

4

我希望使用ggplot2创建散点图矩阵。部分问题已经解决,我已经成功地使用ggplot2创建了三个部分的图表:下三角-散点图,对角线-变量名称和上三角-相关系数(R ^ 2)。以下是我的数据和生成图表的代码。

f = 
C   xval    V   yval    corr    V1
1   1622    1   1622    1       2ng
1   1622    2   1639    0.997   2ng
1   1622    3   1584    0.992   2ng
1   1622    4   1549    0.99    2ng
1   1622    5   1541    0.993   2ng
1   1622    6   1543    0.994   2ng
1   1622    7   1530    0.988   2ng
2   1639    1   1622    0.997   5ng
2   1639    2   1639    1       5ng
2   1639    3   1584    0.997   5ng
2   1639    4   1549    0.997   5ng
2   1639    5   1541    0.998   5ng
2   1639    6   1543    0.998   5ng
2   1639    7   1530    0.995   5ng
3   1584    1   1622    0.992   10ng
3   1584    2   1639    0.997   10ng
3   1584    3   1584    1       10ng
3   1584    4   1549    0.997   10ng
3   1584    5   1541    0.995   10ng
3   1584    6   1543    0.999   10ng
3   1584    7   1530    0.999   10ng
4   1549    1   1622    0.99    15ng
4   1549    2   1639    0.997   15ng
4   1549    3   1584    0.997   15ng 
4   1549    4   1549    1       15ng
4   1549    5   1541    0.998   15ng
4   1549    6   1543    0.998   15ng
4   1549    7   1530    0.998   15ng
5   1541    1   1622    0.993   30ng
5   1541    2   1639    0.998   30ng
5   1541    3   1584    0.995   30ng
5   1541    4   1549    0.998   30ng
5   1541    5   1541    1       30ng
5   1541    6   1543    0.998   30ng
5   1541    7   1530    0.995   30ng
6   1543    1   1622    0.994   60ng
6   1543    2   1639    0.998   60ng
6   1543    3   1584    0.999   60ng
6   1543    4   1549    0.998   60ng
6   1543    5   1541    0.998   60ng
6   1543    6   1543    1       60ng
6   1543    7   1530    0.998   60ng
7   1530    1   1622    0.988   100ng
7   1530    2   1639    0.995   100ng
7   1530    3   1584    0.999   100ng
7   1530    4   1549    0.998   100ng
7   1530    5   1541    0.995   100ng
7   1530    6   1543    0.998   100ng
7   1530    7   1530    1       100ng

并且代码:

g <- ggplot(data = f, aes(x=xval, y=yval))+ 
  geom_point(data = f[(xtfrm(f$C)<xtfrm(f$V)),], colour = "darkblue", size = 1.5)+
  geom_smooth(data = f[(xtfrm(f$C)<xtfrm(f$V)),], aes(colour = "red"), method="lm", size = 0.1)+
  geom_text(data = f[(xtfrm(f$C)==xtfrm(f$V)),], aes(x = 4000, y = 4000, label = paste(V1)), size = 10, colour="red")+
  geom_tile(aes(fill=corr))+
  geom_text(data = f[(xtfrm(f$C)>xtfrm(f$V)), ], aes(x = 4000, y = 4000, label = corr), size = 10)+
  coord_cartesian(xlim=c(0,8000), ylim=c(0,8000))+
  facet_grid(V~C, space = "fixed") + 
  theme(panel.grid.major = element_blank(), strip.background = element_blank(), strip.text.y = element_blank(), strip.text.x = element_blank(), legend.position = "none")

g

enter image description here 然而,我在改善图表外观方面遇到了问题。我想用不同的背景颜色分隔部分图形,例如:散点图使用白色背景,变量名称使用灰色背景,相关系数使用蓝色背景。有人知道如何做到这一点吗?是否可能或者我必须单独创建每个图形部分?


我认为您无法修改单个分面的主题选项(例如背景颜色)。不过,您可以将其默认为白色背景,并绘制geom_rect来欺骗它。您还可以查看GGally::ggpairs如何实现 - Gregor Thomas
1个回答

7
一种方法是分别创建每个图表,然后将它们放在一起。这样可以独立设置每个图表的所有元素,包括主题元素,如背景填充颜色。
下面的函数使用 mapply 创建每个 V 和 C 组合的单独图表,并使用 if 语句为每个图表分配所需的背景颜色。
library(gridExtra)

p.list = mapply(FUN=function(v,c) {

    fvc = f[f$V==v & f$C==c, ]

    g <- ggplot(data=fvc, aes(x=xval, y=yval))+ 
      coord_cartesian(xlim=c(0,8000), ylim=c(0,8000))+
      theme(axis.title=element_blank(),
            axis.text=element_text(size=8))

    if (c == v) {
      g = g + geom_text(aes(x = 4000, y = 4000, label=V1),
                        size = 6, colour="red")
    }

    if (c < v) {
      g = g + geom_text(aes(x = 4000, y = 4000, label=corr), size = 6) +
        theme(panel.background=element_rect(fill=hcl(180,100,60, alpha=0.3)))
    }

    if (c > v) {
      g = g + geom_point(colour = "darkblue", size = 1.5) +
              geom_smooth(aes(colour = "red"), method="lm", size = 0.1) +
        theme(panel.background=element_blank(),
              panel.grid.major=element_line(colour="grey80", size=0.3))
    }

    if(v != 1) {
      g = g + theme(axis.text.y=element_blank(),
                    axis.ticks.y=element_blank())
    }

    if(c != max(f$C)) {
      g = g + theme(axis.text.x=element_blank(),
                    axis.ticks.x=element_blank())
    }

    return(g) }, 
    expand.grid(V=unique(f$V), C=unique(f$C))[[1]], 
    expand.grid(V=unique(f$V), C=unique(f$C))[[2]], SIMPLIFY=FALSE)

现在将所有的图形放在一起,并添加 x 轴和 y 轴标签:
grid.arrange(
  arrangeGrob(
    arrangeGrob(textGrob("Y vals", rot=90),
                do.call(arrangeGrob, c(p.list, ncol=7)), widths=c(0.05,0.95)),
    textGrob("X vals"), heights=c(0.95,0.05)))

enter image description here

如您在上图中所见,仍有一个问题:由于轴标签的原因,第一列和最后一行中的面板具有较小的绘图区域。此SO答案显示了如何使绘图区域的大小相等,但您必须单独列出每个绘图对象。
幸运的是,在大型绘图网格中使所有绘图区域的大小相等时,我们不必自己编写函数,因为来自cowplot包的plot_grid可以实现这一点。但是,我认为在运行plot_grid之后,每个图形之间的边距太大了。您可以通过在创建图形时更改绘图边距来调整此参数。要执行此操作,请按以下方式在绘图函数的return行中调整绘图边距:
return(g + theme(plot.margin=unit(c(0,-0.15,0,-0.15), "lines"))) },

然后使用plot_grid绘图:
library(cowplot)

grid.arrange(
  arrangeGrob(
    arrangeGrob(textGrob("Y vals", rot=90),
                do.call(plot_grid, c(p.list, align="hv")), widths=c(0.05,0.95)),
    textGrob("X vals"), heights=c(0.95,0.05)))

enter image description here


太好了!!非常感谢!! - gosia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接