r - ggplot 点图 : What is the proper use of geom_dotplot?

标签 r ggplot2

我的目的是用 ggplot2 重现这个数字(Douglas A. Lind、William G Marchal、Samuel A. Wathen,商业和经济统计技术,McGraw-Hill,第 17 版)。 (作者:哈德利·威克姆)。

enter image description here

这是我基于 geom_point 所做的努力以及一些丑陋的数据准备(请参阅下面的代码):

enter image description here

我怎样才能用 geom_dotplot() 做到这一点? ?

在我的尝试中,我遇到了几个问题:(1)将 geom_dotplot 生成的默认密度映射到计数,(2)切断轴,(3)没有意外的孔。我放弃并破解了geom_point()相反。

我期望(并且仍然希望)它会像这样简单

ggplot(data, aes(x,y)) + geom_dotplot(stat = "identity")

但是没有。这是我的尝试和输出:

# Data
df <- structure(list(x = c(79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105), y = c(1, 0, 0, 2, 1, 2, 7, 3, 7, 9, 11, 12, 15, 8, 10, 13, 11, 8, 9, 2, 3, 2, 1, 3, 0, 1, 1)), class = "data.frame", row.names = c(NA, -27L))

# dotplot based on geom_dotplot
geom_dots <- function(x, count, round = 10, breaks = NULL, ...) {
    require(ggplot2)
    n = sum(count) # total number of dots to be drawn
    b = round*round(n/round) # prettify breaks
    x = rep(x, count) # make x coordinates for dots
    if (is.null(breaks))  breaks = seq(0, 1, b/4/n)
    ggplot(data.frame(x = x), aes(x = x)) +
        geom_dotplot(method = "histodot", ...) +
        scale_y_continuous(breaks = breaks, 
                        #limits = c(0, max(count)+1), # doesn't work
                        labels = breaks * n) 
} 

geom_dots(x = df$x, count = df$y) 

# dotplot based on geom_point
ggplot_dot <- function(x, count, ...) {
    require(ggplot2)
    message("The count variable must be an integer")
    count = as.integer(count) # make sure these are counts
    n = sum(count) # total number of dots to be drawn
    x = rep(x, count) # make x coordinates for dots
    count = count[count > 0]  # drop zero cases 
    y = integer(0)  # initialize y coordinates for dots
    for (i in seq_along(count)) 
        y <- c(y, 1:(count[i]))  # compute y coordinates
    ggplot(data.frame(x = x, y = y), aes(x = x, y = y)) +
        geom_point(...)  # draw one dot per positive count
}

ggplot_dot(x = df$x, count = df$y, 
    size = 11, shape = 21, fill = "orange", color = "black") + theme_gray(base_size = 18)
# ggsave("dotplot.png") 
ggsave("dotplot.png", width = 12, height = 5.9)

简短的随机评论:随着geom_point()解决方案,保存绘图需要调整大小以确保点接触(点大小和绘图高度/宽度)。随着geom_dotplot()解决方案,我将标签圆角化以使它们更漂亮。不幸的是,我无法在大约 100 处切断轴:使用 limits()coord_cartesian()结果是整个图的重新缩放而不是剪切。另请注意,要使用 geom_dotplot()我根据计数创建了一个数据向量,因为我无法直接使用计数变量(我预计 stat="identity" 可以做到这一点,但我无法使其工作)。

enter image description here

最佳答案

巧合的是,过去一天我也一直在与 geom_dotplot() 进行斗争,并试图让它显示计数。我还没有找到让 y 轴显示实际数字的方法,但我已经找到了一种截断 y 轴的方法。正如您所提到的,coord_cartesian()limits 不起作用,但 coord_fixed() 起作用,因为它强制执行 x:y 的比率单位:

library(tidyverse)
df <- structure(list(x = c(79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105), y = c(1, 0, 0, 2, 1, 2, 7, 3, 7, 9, 11, 12, 15, 8, 10, 13, 11, 8, 9, 2, 3, 2, 1, 3, 0, 1, 1)), class = "data.frame", row.names = c(NA, -27L))
df <- tidyr::uncount(df, y) 

ggplot(df, aes(x)) +
  geom_dotplot(method = 'histodot', binwidth = 1) +
  scale_y_continuous(NULL, breaks = NULL) + 
  # Make this as high as the tallest column
  coord_fixed(ratio = 15)

这里使用 15 作为比率是可行的,因为 x 轴也采用相同的单位(即单个整数)。如果 x 轴是百分比或对数美元或日期或其他任何值,则必须修改该比率,直到 y 轴被截断得足够多。

<小时/>

使用组合图的方法进行编辑

正如我在下面的评论中提到的,使用 patchwork 将绘图与 coord_fixed() 结合起来效果不佳。但是,如果您手动将组合图的高度(或宽度)设置为与 coord_fixed() 中的比率相同的值,请确保每个图具有相同的 x轴,您可以获得伪多面图

# Make a subset of df
df2 <- df %>% slice(1:25)

plot1 <- ggplot(df, aes(x)) +
  geom_dotplot(method = 'histodot', binwidth = 1) +
  scale_y_continuous(NULL, breaks = NULL) + 
  # Make this as high as the tallest column
  # Make xlim the same on both plots
  coord_fixed(ratio = 15, xlim = c(75, 110))

plot2 <- ggplot(df2, aes(x)) +
  geom_dotplot(method = 'histodot', binwidth = 1) +
  scale_y_continuous(NULL, breaks = NULL) + 
  coord_fixed(ratio = 7, xlim = c(75, 110))

# Combine both plots in a single column, with each sized incorrectly
library(patchwork)
plot1 + plot2 +
  plot_layout(ncol = 1)

# Combine both plots in a single column, with each sized appropriately
library(patchwork)
plot1 + plot2 +
  plot_layout(ncol = 1, heights = c(15, 7) / (15 + 7))

关于r - ggplot 点图 : What is the proper use of geom_dotplot?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53697235/

相关文章:

linux - RStudio Server 的默认组权限

r - 如何在保留 x 轴标签的同时抑制 ggplot2 图中的垂直网格线?

r - ggplot2 中的 qqline 与 facets

regex - 根据r中的模式提取部分字符串

r - 在 r 中尝试创建甘特图

r - Shiny 的应用程序不更新隐藏的 slider

r - <NA> 和 NA 有什么区别?

r - 当使用 coord_map 设置限制时,ggplot map 绘制失败

r - 按降序排列两个变量条形图

r - 具有 geom_smooth 的对数 y