我自己也遇到了这个问题(尽管我也想按组给我的点上色)。问题是 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 )