您的数据存在问题,对于数据框 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 和库 gridExtra 将数据绘制为单独的图。
首先,将带有所有图例和数据(代码如上)的图保存为对象p。然后使用函数ggplot_build() 和ggplot_gtable() 将绘图保存为grob 对象gp。从 gp 中提取仅绘制图例的部分(保存为对象 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]]
制作两个新图 p1 和 p2 - 首先绘制 subm 的数据,第二个绘制 mcsm 的数据。使用scale_color_manual() 设置与绘图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")
将两个图 p1 和 p2 保存为 grob 对象,然后为两个图设置相同的宽度。
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))