【问题标题】:How to plot stacked point histograms?如何绘制堆积点直方图?
【发布时间】:2013-04-25 13:38:51
【问题描述】:

ggplot2 等价于“dotplot”直方图是什么?使用堆叠点而不是条形?类似于R中的这个解决方案:

Plot Histogram with Points Instead of Bars

是否可以在 ggplot2 中执行此操作?理想情况下,点显示为堆栈,一条微弱的线显示平滑线“适合”这些点(这将形成直方图形状。)

【问题讨论】:

  • 也许您正在寻找geom_dotplot

标签: r plot ggplot2


【解决方案1】:

ggplot2 绘制点图Link to the manual

这是一个例子:

library(ggplot2)

set.seed(789); x <- data.frame(y = sample(1:20, 100, replace = TRUE))

ggplot(x, aes(y)) + geom_dotplot()

为了让它表现得像一个简单的点图,我们应该这样做:

ggplot(x, aes(y)) + geom_dotplot(binwidth=1, method='histodot')    

你应该得到这个:

要解决密度问题,您必须添加另一个术语 ylim(),以便您的绘图调用将具有 ggplot() + geom_dotplot() + ylim() 的形式

更具体地说,您将编写ylim(0, A),其中A 将是计数1.00 密度所需的堆叠点数。在上面的示例中,您能做的最好的事情就是看到 7.5 个点达到 0.50 密度标记。从那里,您可以推断出 15 个点将达到 1.00。

所以你的新调用看起来像这样:

ggplot(x, aes(y)) + geom_dotplot(binwidth=1, method='histodot') + ylim(0, 15)

这会给你这个:

通常,这种眼球估计适用于点图,但当然您可以尝试其他值来微调您的比例。

请注意更改 ylim 值不会影响数据的显示方式,它只会更改 y 轴上的标签。

【讨论】:

  • 可以动态地对“A”进行编程,这样就不需要通过目测来设置了吗?
  • 如果您需要 binwidth 为 1 以外的值(例如 binwidth=z),您仍然可以通过将宽高比设置为匹配来控制缩放:coord_fixed(z)
【解决方案2】:

正如@joran 指出的,我们可以使用 geom_dotplot

require(ggplot2)
ggplot(mtcars, aes(x = mpg)) + geom_dotplot()


编辑: (将有用的 cmets 移到帖子中)

标签“计数”具有误导性,因为这实际上是一个密度估计值,您可能建议我们将此标签默认更改为“密度”。 dotplot 的 ggplot 实现遵循 Leland Wilkinson 的原始实现,因此如果您想清楚地了解它是如何工作的,请使用 look at this paper

使 y 轴实际计数的简单转换,即“观察次数”。 From the help page 上面写着:

当沿 x 轴分箱并沿 y 轴堆叠时,由于 ggplot2 的技术限制,y 轴上的数字没有意义。您可以隐藏 y 轴,如示例之一,或手动缩放它以匹配点数。

所以你可以使用这段代码来隐藏y轴:

ggplot(mtcars, aes(x = mpg)) + 
  geom_dotplot(binwidth = 1.5) + 
  scale_y_continuous(name = "", breaks = NULL)

【讨论】:

  • 你能解释一下缩放吗? x 轴是分箱的,但是 y 轴是否代表实际数据点(标签“计数”会暗示)?如果是这样,为什么它是从 0 到 1?这是非常违反直觉的
  • 您对“计数”标签是正确的,它具有误导性,因为这实际上是一个密度估计值,您可能会建议我们默认将此标签更改为“密度”。 dotplot 的 ggplot 实现遵循 Leland Wilkinson 的原始实现,所以如果你想清楚地了解它是如何工作的,请查看这篇论文 cs.uic.edu/~wilkinson/Publications/dots.pdf
  • 是否有一个简单的转换可以使 y 轴真正被计数,即“观察次数”?
  • 从帮助页面上写着When binning along the x axis and stacking along the y axis, the numbers on y axis are not meaningful, due to technical limitations of ggplot2. You can hide the y axis, as in one of the examples, or manually scale it to match the number of dots.所以你可以用这段代码隐藏y轴ggplot(mtcars, aes(x = mpg)) + geom_dotplot(binwidth = 1.5) + + scale_y_continuous(name = "", breaks = NULL)
  • 实际的实现有一个毫无意义的 y_axis (这对点图来说没什么大不了的)所以没有创建你自己的函数(调整geom_dotplot)我不知道如何实现你想要的。我真的很想帮忙,但现在没有太多时间去做这件事。试试 ggplot 邮件列表,那里有很多 ggplot2 专家。如果你愿意,我可以删除我的答案
【解决方案3】:

我介绍了一种使用@Waldir Leoncio 的后一种方法的精确方法。

library(ggplot2); library(grid)

set.seed(789)
x <- data.frame(y = sample(1:20, 100, replace = TRUE))

g <- ggplot(x, aes(y)) + geom_dotplot(binwidth=0.8)
g  # output to read parameter

### calculation of width and height of panel
grid.ls(view=TRUE, grob=FALSE)
real_width <- convertWidth(unit(1,'npc'), 'inch', TRUE)
real_height <- convertHeight(unit(1,'npc'), 'inch', TRUE)

### calculation of other values
width_coordinate_range <- diff(ggplot_build(g)$panel$ranges[[1]]$x.range)
real_binwidth <- real_width / width_coordinate_range * 0.8  # 0.8 is the argument binwidth
num_balls <- real_height / 1.1 / real_binwidth  # the number of stacked balls. 1.1 is expanding value.
   # num_balls is the value of A

g + ylim(0, num_balls)

【讨论】:

    【解决方案4】:

    道歉:我没有足够的声誉来“评论”。

    我喜欢 cuttlefish44 的“精确方法”,但为了使其工作(使用 ggplot2 [2.2.1]),我必须更改以下行:

    ### calculation of other values
    width_coordinate_range <- diff(ggplot_build(g)$panel$ranges[[1]]$x.range)
    

    ### calculation of other values
    width_coordinate_range <- diff(ggplot_build(g)$layout$panel_ranges[[1]]$x.range)
    

    【讨论】:

    • diff(g$layout$panel_params[[1]]$x.range)
    猜你喜欢
    • 1970-01-01
    • 2017-07-08
    • 1970-01-01
    • 2018-06-05
    • 1970-01-01
    • 2019-06-11
    • 1970-01-01
    • 2012-09-17
    • 2021-12-27
    相关资源
    最近更新 更多