ggplot2:自动缩放以包含geom_density_2d中的完整轮廓线

时间:2016-03-13 19:35:09

标签: r ggplot2 scale contour

希望这会很快。

我使用ggplot绘制了下面的图表。

ggplot chart

代码:

ggplot(ContourDummy,aes(x=Measure.Name1,y=Measure.Name2,colour=Category.Name))
+geom_density_2d()

我的问题是有些轮廓线不完整。

现在,如果我通过添加以下内容来缩放我的轴...

+ scale_x_continuous(minor_breaks=0, breaks=seq(14,26,12),limits=c(14,26)) 
+ scale_y_continuous(minor_breaks=0, breaks=seq(50,100,50),limits=c(50,100)

我得到了所需的输出。

但有没有办法自动设定限制?我希望能够通过切换数据源,x,y和颜色自动复制此图表类型。

我并不特别想每次都在摆弄音阶。

1 个答案:

答案 0 :(得分:5)

这是一个扩展x和y范围以包括密度等值线最大范围的函数。该功能的工作原理如下:

  1. 创建一个绘图对象,其x和y范围扩展到数据范围之外,这样我们就可以确定绘图将包含完整的轮廓线。

  2. 使用ggplot_build确定所有密度等值线中的最小和最大x和y值。

  3. 将图表的x和y范围设置为步骤2中确定的最小和最大x和y值。

  4. exp参数用于扩展最终范围一小部分(默认为1%),因为在没有那么多额外填充的情况下,仍然可以切断一小段轮廓线(在示例中)在下面,尝试使用mtcars绘制exp=0数据框,您将看到我的意思。

    d2d = function(data, var1, var2, col, exp=0.005) {
    
      # If the colour variable is numeric, convert to factor
      if(is.numeric(data[,col])) {
        data[,col] = as.factor(data[,col])
      }
    
      # Create plot, but expand x and y ranges well beyond data
      p=ggplot(data, aes_string(var1, var2, colour=col)) +
        geom_density_2d() +
        scale_x_continuous(limits=c(min(data[,var1]) - 2*diff(range(data[,var1])),
                                    max(data[,var1]) + 2*diff(range(data[,var1])))) +
        scale_y_continuous(limits=c(min(data[,var2]) - 2*diff(range(data[,var2])),
                                    max(data[,var2]) + 2*diff(range(data[,var2]))))
    
      # Get min and max x and y values among all density contours
      pb = ggplot_build(p)
    
      xyscales = lapply(pb$data[[1]][,c("x","y")], function(var) {
        rng = range(var)
        rng + c(-exp*diff(rng), exp*diff(rng))
      })
    
      # Set x and y ranges to include complete density contours
      ggplot(data, aes_string(var1, var2, colour=col)) +
        geom_density_2d() +
        scale_x_continuous(limits=xyscales[[1]]) +
        scale_y_continuous(limits=xyscales[[2]]) 
    }
    

    在两个内置数据集上试用该功能:

    d2d(mtcars, "wt","mpg", "cyl")
    d2d(iris, "Petal.Width", "Petal.Length", "Species")
    

    enter image description here

    以下是使用默认x和y范围的图表:

    ggplot(mtcars, aes(wt, mpg, colour=factor(cyl))) + geom_density_2d()
    
    ggplot(iris, aes(Petal.Width, Petal.Length, colour=Species)) + geom_density_2d()
    

    enter image description here

    如果你想控制轴刻度线的数量,你可以做一下这样的事情:

    d2d = function(data, var1, var2, col, nx=5, ny=5, exp=0.01) {
    
      require(scales)
    
      # If the colour variable is numeric, convert to factor
      if(is.numeric(data[,col])) {
        data[,col] = as.factor(data[,col])
      }
    
      # Create plot, but expand x and y ranges well beyond data
      p=ggplot(data, aes_string(var1, var2, colour=col)) +
        geom_density_2d() +
        scale_x_continuous(limits=c(min(data[,var1]) - 2*diff(range(data[,var1])),
                                    max(data[,var1]) + 2*diff(range(data[,var1])))) +
        scale_y_continuous(limits=c(min(data[,var2]) - 2*diff(range(data[,var2])),
                                    max(data[,var2]) + 2*diff(range(data[,var2]))))
    
      # Get min and max x and y values among all density curves
      pb = ggplot_build(p)
    
      xyscales = lapply(pb$data[[1]][,c("x","y")], function(var) {
        rng = range(var)
        rng + c(-exp*diff(rng), exp*diff(rng))
      })
    
      # Set x and y ranges to include all of outer density curves
      ggplot(data, aes_string(var1, var2, colour=col)) +
        geom_density_2d() +
        scale_x_continuous(limits=xyscales[[1]], breaks=pretty_breaks(n=nx)) +
        scale_y_continuous(limits=xyscales[[2]], breaks=pretty_breaks(n=ny)) 
    }