5

我有四个不同变量随时间绘制的数据。我想使用 facet_grid 将它们组合在一个图中,其中每个变量都有自己的子图。以下代码类似于我的数据和我呈现它的方式:

require(ggplot2)
require(reshape2)

subm <- melt(economics, id='date', c('psavert','uempmed','unemploy'))
mcsm <- melt(data.frame(date=economics$date, q=quarters(economics$date)), id='date')
mcsm$value <- factor(mcsm$value)


ggplot(subm, aes(date, value, col=variable, group=1)) + geom_line() + 
       facet_grid(variable~., scale='free_y') + 
       geom_step(data=mcsm, aes(date, value)) + 
       scale_y_discrete(breaks=levels(mcsm$value))

如果我忽略 scale_y_discrete,R 会抱怨我正在尝试将离散值与连续比例相结合。如果我包括 scale_y_discreate 我的连续系列会错过他们的规模。

有没有解决这个问题的巧妙方法,即。让所有秤都正确吗?我还看到图例是按字母顺序排序的,我可以更改它,以便图例按照与子图相同的顺序排列吗?

4

1 回答 1

9

您的数据的问题在于数据框的数据subm value是数字(连续),但对于mcsm value因素(离散)。您不能对数值和连续值使用相同的比例,并且您只能获得最后一个方面(离散)的 y 值。此外,不可能scale_y...()在一个图中使用两个函数。

我的方法是制作mcsm value为数字(另存为value2)然后使用它们 - 它将四分之一绘制为 1、2、3 和 4。要解决图例问题,请按您需要的顺序使用scale_color_discrete()和提供breaks=

mcsm$value2<-as.numeric(mcsm$value)
ggplot(subm, aes(date, value, col=variable, group=1)) + geom_line()+
 facet_grid(variable~., scale='free_y') + geom_step(data=mcsm, aes(date, value2)) +
  scale_color_discrete(breaks=c('psavert','uempmed','unemploy','q'))

在此处输入图像描述

更新 - 使用 grobs 的解决方案

另一种方法是使用 grobs 和 librarygridExtra将您的数据绘制为单独的图。

首先,将带有所有图例和数据(代码如上)的绘图保存为 object p。然后使用函数ggplot_build()并将ggplot_gtable()绘图保存为 grob object gp。从 gp 中提取仅绘制图例的部分(另存为 object gp.leg) - 在这种情况下是列表元素编号 17。

library(gridExtra)
p<-ggplot(subm, aes(date, value, col=variable, group=1)) + geom_line()+
  facet_grid(variable~., scale='free_y') + geom_step(data=mcsm, aes(date, value2)) +
  scale_color_discrete(breaks=c('psavert','uempmed','unemploy','q'))
gp<-ggplot_gtable(ggplot_build(p))
gp.leg<-gp$grobs[[17]]

制作两个新的绘图p1p2- 第一个绘图数据subm和第二个数据mcsm。用于scale_color_manual()设置与 plot 相同的颜色p。对于第一个绘图,删除 x 轴标题、文本和刻度,plot.margin=并将下边距设置为负数。对于第二个图,将上边距更改为负数。faced_grid()应该用于两个情节以获得多面外观。

p1 <- ggplot(subm, aes(date, value, col=variable, group=1)) + geom_line()+
   facet_grid(variable~., scale='free_y')+
  theme(plot.margin = unit(c(0.5,0.5,-0.25,0.5), "lines"),
        axis.text.x=element_blank(),
        axis.title.x=element_blank(),
        axis.ticks.x=element_blank())+
  scale_color_manual(values=c("#F8766D","#00BFC4","#C77CFF"),guide="none")

p2 <- ggplot(data=mcsm, aes(date, value,group=1,col=variable)) + geom_step() +
  facet_grid(variable~., scale='free_y')+
  theme(plot.margin = unit(c(-0.25,0.5,0.5,0.5), "lines"))+ylab("")+
  scale_color_manual(values="#7CAE00",guide="none")

将两个图都保存为 grob 对象,p1然后p2为两个图设置相同的宽度。

gp1 <- ggplot_gtable(ggplot_build(p1))
gp2 <- ggplot_gtable(ggplot_build(p2))
maxWidth = grid::unit.pmax(gp1$widths[2:3],gp2$widths[2:3])
gp1$widths[2:3] <- as.list(maxWidth)
gp2$widths[2:3] <- as.list(maxWidth)

具有功能grid.arrange()并将arrangeGrob()图和图例安排在一个图中。

grid.arrange(arrangeGrob(arrangeGrob(gp1,gp2,heights=c(3/4,1/4),ncol=1),
       gp.leg,widths=c(7/8,1/8),ncol=2))

在此处输入图像描述

于 2013-04-14T13:17:12.640 回答