我在ggplot2中制作这个点图:
ggplot(mtcars, aes(x = mpg)) + geom_dotplot()
我希望显示某种平滑的密度适合点图顶部的观察点。这看起来不正确:
ggplot(mtcars, aes(x = mpg)) + geom_dotplot() + geom_density()
我尝试了stat_smooth()
,但我收到错误:
> ggplot(mtcars, aes(x = mpg)) + geom_dotplot() + stat_smooth()
stat_bindot: binwidth defaulted to range/30. Use 'binwidth = x' to adjust this.
Error: stat_smooth requires the following missing aesthetics: y
感谢。
答案 0 :(得分:0)
stat_smooth
函数中的平滑公式需要y
值,并且由于您未指定值,因此您会看到错误。
如果您为y
指定一系列值,则错误将消失,例如:
ggplot(mtcars, aes(x = hp, y = mpg)) + geom_dotplot() + stat_smooth()
修改强>:
stat_smooth()
与大多数其他功能完美配合。您可能需要的近似值(x上的mpg和y上的模型)将是:
qplot(mpg, row.names(mtcars), data=mtcars, group=1, color=mpg, xlab="Miles Per Gallon", ylab="Model") + stat_smooth()
哪会导致:
答案 1 :(得分:0)
我自己遇到了这个问题(尽管我也想按组对点进行着色)。问题是geom_dotplot忽略了y缩放,只是根据x轴和点的宽度堆叠点。这意味着您可以自己设置y轴,然后调整绘图的纵横比,以使点神奇地对齐到正确的高度。
这是我写的一个实用函数:
# Function to generate a normal curve
make.normal.density = function( a, mn=median(a), stdev=sd(a), numpts=500 ) {
x.grid = seq(min(a), max(a), length= numpts)
dens.all = dnorm(x.grid,mean=mn, sd = stdev)
data.frame( x = x.grid, y = dens.all )
}
make.densodot.plot = function( X, group = NULL, binwidth, bw = binwidth, normal.density = FALSE ) {
df = data.frame( X = X )
if ( !is.null( group ) ) {
df$group=group
}
# Hand-bin our dots
scl = 1 / binwidth
mn = round( scl * (min( X ) - binwidth/2 ) ) / scl
breaks = seq( mn - binwidth/2, max( df$X + binwidth), by=binwidth )
df = mutate( df, bin = cut( X, breaks=breaks ) )
mx = max( table(df$bin ) )
# Get density curve to plot
if ( normal.density ) {
dd = make.normal.density( df$X )
} else {
dens = density( df$X, bw=bw )
dd = data.frame( x=dens$x, y=dens$y )
}
dmax = max( dd$y )
# What fraction of density is in tallest histogram bar?
frac = mx / nrow( df )
# How high should density line be through the peak (to get relatively same area
# under density curve (integrate curve over binwidth) vs. histogram bin (# dots in
# the bin over total number of dots)
ratio = (binwidth * dmax) / frac
# Each unit of height is what in terms of dots? (The dots will stack up
# without regard of y-axis, so we want to fix aspect ratio so the dots
# correspond to the density line.)
scaling = binwidth / ( (dmax / ratio) / (mx) )
y.max = max( dmax, mx * binwidth/scaling )
if ( is.null( group ) ) {
plt = ggplot( df )+
geom_dotplot( aes(x=X), method="histodot",
binwidth = binwidth, stackgroups = TRUE)
} else {
plt = ggplot( df )+
geom_dotplot( aes(x=X, fill=group, col=group), method="histodot",
binwidth = binwidth, stackgroups = TRUE)
}
plt = plt +
geom_line( data=dd, aes( x = x, y = y ) ) +
coord_fixed(ratio = scaling, ylim=c(0, y.max ) ) +
scale_y_continuous(name="", breaks=seq(0,by=binwidth/scaling, length.out=(mx+1)), labels=c(0:mx) )
plt
}
make.densodot.plot( X = mtcars$mpg, binwidth=3 )