ggplot2:自动缩放以包含 geom_density_2d 中的完整轮廓线
ggplot2: Automatic scaling to include complete contour lines in geom_density_2d
希望这会很快。
我使用 ggplot 绘制了以下图表。
使用代码:
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 和颜色来自动复制这种图表类型。
我不是特别想每次都摆弄秤
这是一个扩展 x 和 y 范围以包括密度等高线的最大范围的函数。该函数的工作原理如下:
创建一个 x 和 y 范围扩展到数据范围之外的绘图对象,这样我们就可以确定绘图将包含完整的等高线。
使用ggplot_build
确定所有密度等高线中的最小和最大x和y值。
将绘图的 x 和 y 范围设置为在步骤 2 中确定的最小和最大 x 和 y 值。
exp
参数用于将最终范围扩大一点点(默认为 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")
这是默认 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()
如果您还想控制轴刻度线的数量,例如,您可以这样做:
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))
}
希望这会很快。
我使用 ggplot 绘制了以下图表。
使用代码:
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 和颜色来自动复制这种图表类型。
我不是特别想每次都摆弄秤
这是一个扩展 x 和 y 范围以包括密度等高线的最大范围的函数。该函数的工作原理如下:
创建一个 x 和 y 范围扩展到数据范围之外的绘图对象,这样我们就可以确定绘图将包含完整的等高线。
使用
ggplot_build
确定所有密度等高线中的最小和最大x和y值。将绘图的 x 和 y 范围设置为在步骤 2 中确定的最小和最大 x 和 y 值。
exp
参数用于将最终范围扩大一点点(默认为 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")
这是默认 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()
如果您还想控制轴刻度线的数量,例如,您可以这样做:
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))
}