2016-03-13 32 views
2

希望這會很快。ggplot2:自動縮放以在geom_density_2d中包含完整的輪廓線

我用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和顏色自動複製此圖表類型。

我不是特別想每次都在用秤來擺弄。

+0

能否請您做一個[重複的例子(http://stackoverflow.com /問題/ 5963269 /如何對做 - 一個偉大-R-重複性,例如)? – Heroka

+0

'geom_density_2d()'默認使用數據的限制。您需要計算ggplot以外的密度,根據相關密度水平計算所需限值並將其提供給ggplot中的比例。 – Thierry

回答

4

這是一個擴展x和y範圍以包括密度等高線的最大範圍的函數。該功能的工作原理如下:

  1. 創建擴展遠遠超出了數據範圍x和y的範圍情節的對象,讓我們可以肯定的情節將包括完整的輪廓線。

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

  3. 設置X和情節在步驟2確定

exp的參數的最小值和最大值x和y值的y的範圍是有擴大通過一個微小的量的最終範圍(默認情況下爲1%),因爲一小段輪廓線仍然可以在沒有少量額外填充的情況下被切斷(在下面的示例中,請嘗試使用exp=0繪製mtcars數據幀,您將看到我的意思)。

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

感謝您提供這樣的詳細回覆。 我通過使用以下代碼創建了自己的臨時解決方案,它可以找到每個軸上點的最大值和最小值,然後延伸+ -20% + scale_x_continuous(limits = c(min(ContourDummy $ Measure.Name1 )* 0.8,max(ContourDummy $ Measure.Name1)* 1.2) + scale_y_continuous(limits = c(min(ContourDummy $ Measure.Name2)* 0.8,max(ContourDummy $ Measure.Name2)* 1.2) 在所有的情況下,我通過它,但我認爲長期存在潛在的問題(例如負數)。 我會嘗試將上面的這一塊整合到我的流程明天 –

+0

我原來的答案使用了一個功能,工作在類似方式,以擴展因子作爲參數功能。在我更新的答案中,範圍是自動找到的,因此您無需手動調整百分比擴展。 – eipi10