r - ggplot2: Automatic scaling to include complete contour lines in geom_density_2d -
hopefully quick.
i have plotted following chart using ggplot.
with code:
ggplot(contourdummy,aes(x=measure.name1,y=measure.name2,colour=category.name)) +geom_density_2d()
my issue of contour lines not complete.
now if scale axis adding following...
+ 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)
i desired output.
but there way of automatically setting limits? want able replicate chart type automatically switching data source, x, y , colour.
i don't particularly want fiddling around scales every time.
here's function expands x , y ranges include maximum extent of density contours. function works follows:
create plot object x , y ranges expanded beyond data range, can sure plot include complete contour lines.
use
ggplot_build
determine min , max x , y values among density contours.set x , y ranges of plot min , max x , y values determined in step 2.
the exp
parameter there expand final range tiny amount (1% default) because small piece of contour line can still cut off without small bit of padding (in example below, try plotting mtcars
data frame exp=0
, you'll see mean).
d2d = function(data, var1, var2, col, exp=0.005) { # if colour variable numeric, convert factor if(is.numeric(data[,col])) { data[,col] = as.factor(data[,col]) } # create plot, expand x , y ranges 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])))) # min , max x , y values among 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 , y ranges 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]]) }
try out function on 2 built-in data sets:
d2d(mtcars, "wt","mpg", "cyl") d2d(iris, "petal.width", "petal.length", "species")
here's plots default x , y ranges:
ggplot(mtcars, aes(wt, mpg, colour=factor(cyl))) + geom_density_2d() ggplot(iris, aes(petal.width, petal.length, colour=species)) + geom_density_2d()
if want control number of axis tick marks well, can, example, this:
d2d = function(data, var1, var2, col, nx=5, ny=5, exp=0.01) { require(scales) # if colour variable numeric, convert factor if(is.numeric(data[,col])) { data[,col] = as.factor(data[,col]) } # create plot, expand x , y ranges 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])))) # min , max x , y values among 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 , y ranges include 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)) }
Comments
Post a Comment