在2x1小平面上具有水平而不是垂直标签并且分割y标签

时间:2014-02-01 16:27:13

标签: r ggplot2

我想在一张图中有两张图。它们都是时间序列,但是不同的尺度(比如说高度和重量)。我想要呈现的方式是将两个数字叠加在一起,分享x标签,但是有不同的y标签。

我有两个不同的问题:

  1. 如果我做2x1刻面,则刻面标签的默认位置在右侧,带有垂直文本,我宁愿将它们放在图形顶部作为(子) - 标题
  2. ylab()为所有方面定义了一个ylabel,但我有两个不同的变量/比例。有可能“拆分”它并有两个不同的ylabel(重量说“克”,高度说“英寸”)?
  3. 谢谢!

    编辑: 好的,这是代码。 mn是根据时间绘制的变量,按风险分组。但mn的含义取决于var。对于var的某些值,它为weight,而对于其他值,则为height

    qplot(time, mn, data=d.plot.long,
      color=risk, group=risk,
      geom=c("line","point"),
      position=position_dodge(.2))+
    geom_point(size=5, position=position_dodge(.2))+
    geom_errorbar(aes(x=time, y=mn, ymin=low, ymax=hi),width=.3 ,position=position_dodge(.2))+
    facet_grid(var~.,scales='free_y')+
    xlab('Time')+ylab('')+
    scale_color_discrete(name="The grouping variable", breaks=c("Hi","Low"), labels=(c("Group A","Group B")))
    

3 个答案:

答案 0 :(得分:7)

使用gtable:::rbind_gtable;其他答案将无法正确对齐轴。

align_plots = function(...){
  pl <- list(...)
  ## test that only passing plots
  stopifnot(do.call(all, lapply(pl, inherits, "gg")))
  gl <- lapply(pl, ggplotGrob)
  bind2 <- function(x,y)
    gtable:::rbind_gtable(x,y,"first") # bug with pmax

  combined <- Reduce(bind2, gl[-1], gl[[1]])

  wl <- lapply(gl, "[[", "widths")
  combined$widths <- do.call(grid::unit.pmax, wl)
  grid::grid.newpage()
  grid::grid.draw(combined)
}

align_plots(qplot(1,1), 
            qplot(100, 100), 
            qplot(1000, 1000) + ylab("two\nlines"))

enter image description here

答案 1 :(得分:2)

正如其他人所说,可重复性使问题更容易回答。但是,这是一个可以通过一般情况轻松回答的问题。

ggplot2为单个印版上的多个图形提供了有限的选项。 R Cookbook提供了一个非常好且易于使用的解决方法here。我可以快速引导您完成您的案例:

首先,数据帧中有两组简单的时间序列:

year<-c(2010:2014)
data1<-c(1:5)
data2<-c(20:24)
df<-data.frame(year,data1,data2)

接下来,创建图表。由于您希望它们共享x轴,我们将从顶部图表中删除它:

library(ggplot2)
p1<-qplot(data=df,x=year,y=data1)+theme(axis.title.x = element_blank(), axis.text.x = element_blank())
p2<-qplot(df,x=year,y=data2)

接下来,运行cookbook中的代码以设置多重绘图功能:

# Multiple plot function ggplot objects can be passed in ..., or to plotlist
# (as a list of ggplot objects) - cols: Number of columns in layout -
# layout: A matrix specifying the layout. If present, 'cols' is ignored.  If
# the layout is something like matrix(c(1,2,3,3), nrow=2, byrow=TRUE), then
# plot 1 will go in the upper left, 2 will go in the upper right, and 3 will
# go all the way across the bottom.
multiplot <- function(..., plotlist = NULL, file, cols = 1, layout = NULL) {
  require(grid)
  # Make a list from the ... arguments and plotlist
  plots <- c(list(...), plotlist)
  numPlots = length(plots)
  # If layout is NULL, then use 'cols' to determine layout
  if (is.null(layout)) {
    # Make the panel ncol: Number of columns of plots nrow: Number of rows
    # needed, calculated from # of cols
    layout <- matrix(seq(1, cols * ceiling(numPlots/cols)), ncol = cols,
                     nrow = ceiling(numPlots/cols))
  }
  if (numPlots == 1) {
    print(plots[[1]])
  } else {
    # Set up the page
    grid.newpage()
    pushViewport(viewport(layout = grid.layout(nrow(layout), ncol(layout))))
    # Make each plot, in the correct location
    for (i in 1:numPlots) {
      # Get the i,j matrix positions of the regions that contain this subplot
      matchidx <- as.data.frame(which(layout == i, arr.ind = TRUE))
      print(plots[[i]], vp = viewport(layout.pos.row = matchidx$row, layout.pos.col = matchidx$col))
    }
  }
}

...并使用新功能将图表叠加在一起。

multiplot(p1,p2,cols=1)

(我想向您展示最终输出,但似乎我没有足够的声誉来发布图像!尝试运行所有这些来自己查看结果。)

这就是你要找的东西吗?

答案 2 :(得分:0)

使用@Joe的数据,使用gridExtra包可能更容易。

代码:

require(ggplot2)
require(gridExtra)

p1 <- ggplot(data=df, aes(x=year, y=data1)) + 
  geom_point() +
  theme_bw() +
  theme(
    axis.title.x = element_blank(),
    axis.text.x = element_blank(),
    axis.ticks.x = element_blank()
  )

p2 <- ggplot(data=df, aes(x=year, y=data2)) + 
  geom_point() + 
  theme_bw()

grid.arrange(p1, p2, ncol=1)

结果: enter image description here