1- # ' Jitter-dodge points to align them with a boxplot including fill aesthetic
1+ # ' Adjust position by simultaneously dodging and jittering
2+ # '
3+ # ' This is primarily used for aligning points generated through
4+ # ' \code{geom_point()} with dodged boxplots (e.g., a \code{geom_boxplot()} with
5+ # ' a fill aesthetic supplied).
26# '
37# ' @family position adjustments
4- # ' @param width degree of jitter in x direction. Defaults to 40\% of the
8+ # ' @param jitter. width degree of jitter in x direction. Defaults to 40\% of the
59# ' resolution of the data.
6- # ' @param height degree of jitter in y direction. Defaults to 40\% of the
7- # ' resolution of the data
10+ # ' @param jitter.height degree of jitter in y direction. Defaults to 0.
11+ # ' @param dodge.width the amount to dodge in the x direction. Defaults to 0.75,
12+ # ' the default \code{position_dodge()} width.
813# ' @export
914# ' @examples
10- # ' dsub <- diamonds[ sample(1: nrow(diamonds), 1000), ]
11- # ' ggplot(dsub, aes(x= cut, y= carat, fill= clarity)) +
12- # ' geom_boxplot(outlier.size= 0) +
13- # ' geom_point( pch= 21, position= position_jitterdodge() )
14- position_jitterdodge <- function (width = NULL , height = NULL ) {
15- PositionJitterDodge $ new( width = width , height = height )
16- }
15+ # ' dsub <- diamonds[ sample(nrow(diamonds), 1000), ]
16+ # ' ggplot(dsub, aes(x = cut, y = carat, fill = clarity)) +
17+ # ' geom_boxplot(outlier.size = 0) +
18+ # ' geom_point(pch = 21, position = position_jitterdodge())
19+ position_jitterdodge <- function (jitter. width = NULL ,
20+ jitter. height = NULL ,
21+ dodge.width = NULL ) {
1722
18- # ' @rdname position_jitterdodge
19- # ' @export
20- position_jd <- position_jitterdodge
23+ PositionJitterDodge $ new(jitter.width = jitter.width ,
24+ jitter.height = jitter.height ,
25+ dodge.width = dodge.width )
26+ }
2127
2228PositionJitterDodge <- proto(Position , {
29+
30+ jitter.width <- NULL
31+ jitter.height <- NULL
32+ dodge.width <- NULL
33+
34+ new <- function (. ,
35+ jitter.width = NULL ,
36+ jitter.height = NULL ,
37+ dodge.width = NULL ) {
38+
39+ . $ proto(jitter.width = jitter.width ,
40+ jitter.height = jitter.height ,
41+ dodge.width = dodge.width )
42+
43+ }
44+
2345 objname <- " jitterdodge"
2446
2547 adjust <- function (. , data ) {
@@ -34,22 +56,31 @@ PositionJitterDodge <- proto(Position, {
3456 }
3557
3658 # # Adjust the x transformation based on the number of 'fill' variables
37- nfill <- length( levels(data $ fill ) )
59+ nfill <- length(levels(data $ fill ))
3860
39- if (is.null(. $ width )) . $ width <- resolution(data $ x , zero = FALSE ) * 0.4
40- if (is.null(. $ height )) . $ height <- resolution(data $ y , zero = FALSE ) * 0.4
61+ if (is.null(. $ jitter.width )) {
62+ . $ jitter.width <- resolution(data $ x , zero = FALSE ) * 0.4
63+ }
64+
65+ if (is.null(. $ jitter.height )) {
66+ . $ jitter.height <- 0
67+ }
4168
4269 trans_x <- NULL
4370 trans_y <- NULL
44- if (. $ width > 0 ) {
45- trans_x <- function (x ) jitter(x , amount = . $ width / (nfill + 2 ))
71+ if (. $ jitter.width > 0 ) {
72+ trans_x <- function (x ) jitter(x , amount = . $ jitter.width / (nfill + 2 ))
73+ }
74+ if (. $ jitter.height > 0 ) {
75+ trans_y <- function (x ) jitter(x , amount = . $ jitter.height )
4676 }
47- if (. $ height > 0 ) {
48- trans_y <- function (x ) jitter(x , amount = . $ height )
77+
78+ if (is.null(. $ dodge.width )) {
79+ . $ dodge.width <- 0.75
4980 }
5081
5182 # # dodge, then jitter
52- data <- collide(data , 0.75 , . $ my_name(), pos_dodge , check.width = FALSE )
83+ data <- collide(data , . $ dodge.width , . $ my_name(), pos_dodge , check.width = FALSE )
5384 transform_position(data , trans_x , trans_y )
5485 }
5586
0 commit comments