与ggplot2 geom_violin非常奇怪的图表

时间:2013-10-10 17:00:30

标签: r ggplot2

我只能使用相当大的数据集可靠地重建此问题,因此我粘贴了整个代码to a pastebin 这是没有数据部分的代码:

    # read tmp from the pastebin  

library(ggplot2)
plt <- ggplot(tmp, aes(region, score))
plt1 <- plt + geom_violin(aes(region, score), scale='width', trim=F)  + ylim(0, 1) + ggtitle('with ylim')
plt2 <- plt + geom_violin(aes(region, score), scale='width', trim=F)  + ggtitle('without ylim')

为此剧情设定y限制会产生相当难看的“小提琴”:

enter image description here

enter image description here

这是什么,为什么会发生这种情况以及如何避免这个丑陋的问题呢?

顺便说一句,设置trim=T可以解决问题。

1 个答案:

答案 0 :(得分:5)

从一些挖掘中,我认为问题的技术来源是这样的:你的y变量几乎不在[0,1]范围内,所以你当然会有密度超出范围。使用stat_density时,这个多余的密度会被切断,但是geom_violin / stat_ydensity会留下多余的密度,并且允许扩展。但是,使用ylimtrim=FALSE,[0,1]之外的这些y值会被保留,只会设置为NA,这会使geom_polygon中的图形搞砸}。您可以使用[0,1]中的数据的较小示例来实际看到这一点:

x <- runif(1e4, 0, 1)
ggplot(mapping=aes(1, x)) + geom_violin(trim=FALSE) + ylim(0, 1)

a broken violin plot

有很多方法可以解决这个问题。第一种是保留默认trim=TRUE

ggplot(mapping=aes(1, x)) + geom_violin() + ylim(0, 1)

a violin plot with ylim and trim=TRUE

请注意,在这种情况下,ylimscale_y_continuous)实际上会删除[0,1]之外的原始数据。在你的例子中,除此之外你没有任何要点,我也不在这里。但这是需要注意的事情。顶部和底部也会有一些填充物,可能会误导观众认为[0,1]之外没有密度。

也许更好的解决方案是使用coord_cartesian,它只是“放大”到图表中,保持数据和生成的密度不变:

ggplot(mapping=aes(1, x)) + geom_violin(trim=FALSE) + coord_cartesian(ylim=c(0, 1))

a violin plot with coord_cartesian