ggplot2:添加几何而不影响限制 [英] ggplot2: Adding a geom without affecting limits

查看:52
本文介绍了ggplot2:添加几何而不影响限制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在ggplot密度图中添加其他几何图形,但不更改数据的显示限制,也不必通过自定义代码计算所需的限制.举个例子:

  set.seed(12345)N = 1000d = data.frame(已测量= ifelse(rbernoulli(N,0.5),rpois(N,100),rpois(N,1)))d $ fit = dgeom(d $ measured,0.6)ggplot(d,aes(x =测量值))+ geom_density()+ geom_line(aes(y =适合),color ="blue")ggplot(d,aes(x =测量值))+ geom_density()+ geom_line(aes(y =适合),color ="blue")+ coord_cartesian(ylim = c(0,0.025)) 

在第一个图中,拟合曲线(非常不适合测量"的数据)使测量数据的形状变得模糊:我想裁剪图以包括来自第一个几何的所有数据,但是裁剪拟合曲线,如第二个图所示:

虽然我可以使用 coord_cartesian 生成第二个图,但这有两个缺点:

  1. 我必须通过自己的代码来计算限制(这很麻烦且容易出错)
  2. 通过我自己的代码计算限制与构面不兼容.(AFAIK)无法使用 coord_cartesian 提供每个方面的轴限制.但是,我需要将情节与 facet_wrap(scales ="free")
  3. 结合使用

如果在计算坐标极限时未考虑第二个几何图形,将实现所需的输出-是否可能不使用自定义R代码计算极限?

问题

这可以与 facet_wrap()组合:

  d $ group<-rep(letters [1:2],500)#fake组ggplot(d,aes(x =测量值))+geom_density(aes(y = ..scaled ..))+geom_line(aes(y = fit_scaled),color ="blue")+facet_wrap(〜group,scales ="free") 

不缩放数据的选项:

您可以使用

如果要比较相邻的组,则可以使用 facet_grid()代替 facet_wrap(),且 cols = 2 multiplot()中:

  multiplot(ggplot(d,aes(x =测量值))+geom_density()+facet_grid(group〜.,scales ="free"),ggplot(d,aes(x =测量值))+geom_line(aes(y = fit),color ="blue")+facet_grid(group〜.,scales ="free"),cols = 2) 

它看起来像这样:

I would like to add additional geoms to a ggplot density plot, but without changing the displayed limits of the data and without having to compute the desired limits by custom code. To give an example:

set.seed(12345)
N = 1000
d = data.frame(measured = ifelse(rbernoulli(N, 0.5), rpois(N, 100), rpois(N,1)))
d$fit = dgeom(d$measured, 0.6)
ggplot(d, aes(x = measured)) + geom_density() + geom_line(aes(y = fit), color = "blue")

ggplot(d, aes(x = measured)) + geom_density() + geom_line(aes(y = fit), color = "blue") + coord_cartesian(ylim = c(0,0.025))

In the first plot, the fit curve (which fits the "measured" data quite badly) obscures the shape of the measured data: I would like to crop the plot to include all data from the first geom, but crop the fit curve, as in the second plot:

While I can produce the second plot with coord_cartesian, this has two disadvantages:

  1. I have to compute the limits by my own code (which is cumbersome and error-prone)
  2. Computing the limits by my own code is not compatible with faceting. It is not possible (AFAIK) to provide per-facet axis limits with coord_cartesian. I however need to combine the plot with facet_wrap(scales = "free")

The desired output would be achieved, if the second geom was not considered when computing coordinate limits - is that possible without computing the limits in custom R code?

The question R: How do I use coord_cartesian on facet_grid with free-ranging axis is related, but does not have a satisfactory answer.

解决方案

One thing you could try is to scale fit and use geom_density(aes(y = ..scaled..)

Scaling fit between 0 and 1:

d$fit_scaled <- (d$fit  - min(d$fit)) / (max(d$fit) - min(d$fit))

Use fit_scaled and ..scaled..:

ggplot(d, aes(x = measured)) + 
  geom_density(aes(y = ..scaled..)) + 
  geom_line(aes(y = fit_scaled), color = "blue")

This can be combined with facet_wrap():

d$group <- rep(letters[1:2], 500) #fake group

ggplot(d, aes(x = measured)) + 
  geom_density(aes(y = ..scaled..)) + 
  geom_line(aes(y = fit_scaled), color = "blue") + 
  facet_wrap(~ group, scales = "free")

An option that does not scale the data:

You can use the function multiplot() from http://www.cookbook-r.com/Graphs/Multiple_graphs_on_one_page_(ggplot2)/

multiplot <- function(..., plotlist=NULL, file, cols=1, layout=NULL) {
  library(grid)
  plots <- c(list(...), plotlist)

  numPlots = length(plots)

  if (is.null(layout)) {

    layout <- matrix(seq(1, cols * ceiling(numPlots/cols)),
                    ncol = cols, nrow = ceiling(numPlots/cols))
  }

 if (numPlots==1) {
    print(plots[[1]])

  } else {

    grid.newpage()
    pushViewport(viewport(layout = grid.layout(nrow(layout), ncol(layout))))

    for (i in 1:numPlots) {

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

With this function you can combine the two plots, which makes it easier to read them:

multiplot(
  ggplot(d, aes(x = measured)) + 
    geom_density() +
    facet_wrap(~ group, scales = "free"),
  ggplot(d, aes(x = measured)) +  
    geom_line(aes(y = fit), color = "blue") + 
    facet_wrap(~ group, scales = "free")
)

This will give you:

And if you want to compare groups next to each other, you can use facet_grid() instead of facet_wrap() with cols = 2 in multiplot():

multiplot(
  ggplot(d, aes(x = measured)) + 
    geom_density() +
    facet_grid(group ~ ., scales = "free"),
  ggplot(d, aes(x = measured)) +  
    geom_line(aes(y = fit), color = "blue") + 
    facet_grid(group ~ ., scales = "free"),
  cols = 2
)

And it looks like this:

这篇关于ggplot2:添加几何而不影响限制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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