|
5 | 5 | #' |
6 | 6 | #' @inheritParams stat_density |
7 | 7 | #' @inheritParams stat_identity |
8 | | -#' @param trim If \code{TRUE} (default), trim the tails of the violins |
9 | | -#' to the range of the data. If \code{FALSE}, don't trim the tails. |
10 | 8 | #' @param scale if "area" (default), all violins have the same area (before trimming |
11 | 9 | #' the tails). If "count", areas are scaled proportionally to the number of |
12 | 10 | #' observations. If "width", all violins have the same maximum width. |
@@ -60,52 +58,29 @@ StatYdensity <- proto(Stat, { |
60 | 58 | } |
61 | 59 |
|
62 | 60 | calculate <- function(., data, scales, width=NULL, adjust=1, kernel="gaussian", |
63 | | - trim=TRUE, na.rm = FALSE, ...) { |
| 61 | + trim = FALSE, na.rm = FALSE, ...) { |
| 62 | + data <- remove_missing(data, na.rm, "x", name = "stat_density", |
| 63 | + finite = TRUE) |
64 | 64 |
|
65 | | - n <- nrow(data) |
66 | | - |
67 | | - # if less than 3 points, return a density of 1 everywhere |
68 | | - if (n < 3) { |
69 | | - return(data.frame(data, density = 1, scaled = 1, count = 1)) |
70 | | - } |
71 | | - |
72 | | - # initialize weights if they are not supplied by the user |
73 | | - if (is.null(data$weight)) { data$weight <- rep(1, n) / n } |
74 | | - |
75 | | - # compute the density |
76 | | - dens <- stats::density(data$y, adjust = adjust, kernel = kernel, |
77 | | - weight = data$weight, n = 200) |
78 | | - |
79 | | - # NB: stat_density restricts to the scale range, here we leave that |
80 | | - # free so violins can extend the y scale |
81 | | - densdf <- data.frame(y = dens$x, density = dens$y) |
82 | | - |
83 | | - # scale density to a maximum of 1 |
84 | | - densdf$scaled <- densdf$density / max(densdf$density, na.rm = TRUE) |
85 | | - |
86 | | - # trim density outside of the data range |
87 | 65 | if (trim) { |
88 | | - densdf <- subset(densdf, y > min(data$y, na.rm = TRUE) & y < max(data$y, na.rm = TRUE)) |
| 66 | + range <- range(data$y, na.rm = TRUE) |
| 67 | + } else { |
| 68 | + range <- scale_dimension(scales$y, c(0, 0)) |
89 | 69 | } |
90 | | - # NB: equivalently, we could have used these bounds in the from and |
91 | | - # to arguments of density() |
92 | | - |
93 | | - # scale density by the number of observations |
94 | | - densdf$count <- densdf$density * n |
95 | | - # record the number of observations to be able to scale the density later |
96 | | - densdf$n <- n |
97 | | - |
98 | | - # coordinate on the x axis |
99 | | - densdf$x <- if (is.factor(data$x)) data$x[1] else mean(range(data$x)) |
| 70 | + dens <- compute_density(data$y, data$w, from = range[1], to = range[2], |
| 71 | + adjust = adjust, kernel = kernel) |
100 | 72 |
|
101 | | - # width of the bounding box of the violin plot on the x axis for continuous x |
102 | | - if (length(unique(data$x)) > 1) { width <- diff(range(data$x)) * 0.9 } |
103 | | - densdf$width <- width |
| 73 | + dens$y <- dens$x |
| 74 | + dens$x <- mean(range(data$x)) |
104 | 75 |
|
105 | | - densdf |
| 76 | + # Compute width if x has multiple values |
| 77 | + if (length(unique(data$x)) > 1) { |
| 78 | + width <- diff(range(data$x)) * 0.9 |
| 79 | + } |
| 80 | + dens$width <- width |
| 81 | + dens |
106 | 82 | } |
107 | 83 |
|
108 | 84 | default_geom <- function(.) GeomViolin |
109 | 85 | required_aes <- c("x", "y") |
110 | | - |
111 | 86 | }) |
0 commit comments