在ggplot中用facet绘制连续和离散的系列 [英] Plotting continuous and discrete series in ggplot with facet

查看:133
本文介绍了在ggplot中用facet绘制连续和离散的系列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  require(ggplot2)
require(reshape2 )
$ b $ subm < - melt(经济学,id ='date',c('psavert','uempmed','unemploy'))
mcsm < - frame(date = economics $ date,q = quarterers(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 = mcsm,aes(date,value))+
scale_y_discrete(breaks = levels(mcsm $ value))

如果我忽略scale_y_discrete,R抱怨说我试图将离散值与连续比例组合起来。如果我包含scale_y_discreate,我的连续系列文件就会错过它们的比例。



是否有任何解决这个问题的方法,即。让所有的尺度正确?我也看到这个图例是按字母顺序排列的,我可以改变它吗,所以图例的排序顺序与子图的顺序相同吗?

数据的问题在于数据帧 subm value 是数字(连续),但是对于 mcsm 是因子(离散)。您不能对数值和连续值使用相同的比例尺,并且仅为最后一个方面(离散)获取y值。也不可能在一个图中使用两个 scale_y ...()函数。



我的方法是将数值保存为 mcsm value (保存为 value2 ),然后使用它们 - 它将绘制四分区作为1,2,3和4.为了解决图例中的问题,使用 scale_color_discrete()并提供 break = 以满足您的需求。

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



更新 - 解决方案使用grobs



另一种方法是使用grobs和库 gridExtra 将您的数据分开绘制首先,将所有图例和数据(代码如上)保存为对象 p 。然后使用函数 ggplot_build() ggplot_gtable()将plot保存为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' ,'q'))
gp< -ggplot_gtable(ggplot_build(p))
gp.leg< -gp $ grobs [[17]]
pre>

制作两张新图 p1 p2 - 首先绘制 subm 的数据和仅次于 mcsm 的数据。使用 scale_color_manual()设置颜色与绘图 p 所用的颜色相同。对于第一个绘图,删除X轴标题,文本和刻度并使用 plot.margin = 将较低的边距设置为负数。对于第二个阴谋将上边缘改为负数。 faces_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)
$ b

使用函数 grid.arrange() arrangeGrob() b
$ b

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


I have data that plots over time with four different variables. I would like to combine them in one plot using facet_grid, where each variable gets its own sub-plot. The following code resembles my data and the way I'm presenting it:

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))

If I leave out scale_y_discrete, R complains that I'm trying to combine discrete value with continuous scale. If I include scale_y_discreate my continuous series miss their scale.

Is there any neat way of solving this issue ie. getting all scales correct ? I also see that the legend is alphabetically sorted, can I change that so the legend is ordered in the same order as the sub-plots ?

解决方案

Problem with your data is that that for data frame subm value is numeric (continuous) but for the mcsm value is factor (discrete). You can't use the same scale for numeric and continuous values and you get y values only for the last facet (discrete). Also it is not possible to use two scale_y...() functions in one plot.

My approach would be to make mcsm value as numeric (saved as value2) and then use them - it will plot quarters as 1,2,3 and 4. To solve the problem with legend, use scale_color_discrete() and provide breaks= in order you need.

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'))

UPDATE - solution using grobs

Another approach is to use grobs and library gridExtra to plot your data as separate plots.

First, save plot with all legends and data (code as above) as object p. Then with functions ggplot_build() and ggplot_gtable() save plot as grob object gp. Extract from gp only part that plots legend (saved as object gp.leg) - in this case is list element number 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]]

Make two new plot p1 and p2 - first plots data of subm and second only data of mcsm. Use scale_color_manual() to set colors the same as used for plot p. For the first plot remove x axis title, texts and ticks and with plot.margin= set lower margin to negative number. For the second plot change upper margin to negative number. faced_grid() should be used for both plots to get faceted look.

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")

Save both plots p1 and p2 as grob objects and then set for both plots the same widths.

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)

With functions grid.arrange() and arrangeGrob() arrange both plots and legend in one plot.

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

这篇关于在ggplot中用facet绘制连续和离散的系列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆