Вот функция, которая расширяет диапазоны x и y, чтобы включить максимальную степень контуров плотности. Функция работает следующим образом:
Создайте объект участка с й и у диапазонов вспененных далеко за пределами диапазона данных, так что мы можем быть уверены, что сюжет будет включать в себя полные линии контура.
Используйте ggplot_build
для определения значений min и max x и y среди всех контуров плотности.
Установите х и у диапазоны участка до минимального и максимального х и у значений, определенной в шаге 2.
Параметр exp
находится там, чтобы расширить окончательный выбор с помощью небольшого количества (1% по умолчанию), потому что небольшая часть контурной линии все же может быть отрезана без этого небольшого бита дополнительного заполнения (в приведенном ниже примере попробуйте построить кадр данных с 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")

Вот что участки выглядят с й по умолчанию и у диапазонов:
ggplot(mtcars, aes(wt, mpg, colour=factor(cyl))) + geom_density_2d()
ggplot(iris, aes(Petal.Width, Petal.Length, colour=Species)) + geom_density_2d()

Если вы хотите, чтобы контролировать количество делений оси, а также, вы можете, например, сделать что-то вроде этого:
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))
}
Можете ли вы сделать [воспроизводимый пример] (http://stackoverflow.com/вопросы/5963269/как в изготовлении, а-пра-р-воспроизводимая-пример)? – Heroka
'geom_density_2d()' использует значения по умолчанию. Вам нужно будет вычислить плотности вне ggplot, рассчитать требуемые лимиты на основе соответствующего уровня плотности и обеспечить их весы в ggplot. – Thierry