7
7
# ' columns have an equal relative width.
8
8
# ' @param heights relative height of each row on a 0-1 scale. By default all
9
9
# ' rows have an equal relative height.
10
- # ' @param share determines whether x/y/both axes are shared.
11
- # ' @param which_layout adopt the layout of which plot? If the default value of
12
- # ' "merge" is used, all plot level layout options will be included in the final
13
- # ' layout. This argument also accepts a numeric vector which will restric
10
+ # ' @param shareX should the x-axis be shared amongst the subplots?
11
+ # ' @param shareY should the y-axis be shared amongst the subplots?
14
12
# ' @param margin either a single value or four values (all between 0 and 1).
15
13
# ' If four values are provided, the first is used as the left margin, the second
16
14
# ' is used as the right margin, the third is used as the top margin, and the
17
15
# ' fourth is used as the bottom margin.
18
16
# ' If a single value is provided, it will be used as all four margins.
17
+ # ' @param which_layout adopt the layout of which plot? If the default value of
18
+ # ' "merge" is used, all plot level layout options will be included in the final
19
+ # ' layout. This argument also accepts a numeric vector specifying
19
20
# ' @return A plotly object
20
21
# ' @export
21
22
# ' @author Carson Sievert
25
26
# ' subplot(p1, p2, p1, p2, nrows = 2)
26
27
# ' }
27
28
28
- subplot <- function (... , nrows = 1 , widths = NULL , heights = NULL , share = NULL ,
29
- which_layout = " merge " , margin = 0.02 ) {
29
+ subplot <- function (... , nrows = 1 , widths = NULL , heights = NULL , shareX = FALSE ,
30
+ shareY = FALSE , margin = 0.02 , which_layout = " merge " ) {
30
31
# build each plot and collect relevant info
31
32
plots <- lapply(list (... ), plotly_build )
32
33
traces <- lapply(plots , " [[" , " data" )
@@ -51,13 +52,24 @@ subplot <- function(..., nrows = 1, widths = NULL, heights = NULL, share = NULL,
51
52
xAxisN <- vapply(xAxes , length , numeric (1 ))
52
53
yAxisN <- vapply(yAxes , length , numeric (1 ))
53
54
# old -> new axis name dictionary
55
+ ncols <- ceiling(length(plots ) / nrows )
56
+ xAxisID <- if (shareX ) {
57
+ rep(rep(1 : ncols , length.out = length(plots )), xAxisN )
58
+ } else {
59
+ seq_len(sum(xAxisN ))
60
+ }
61
+ yAxisID <- if (shareY ) {
62
+ rep(rep(1 : nrows , each = ncols , length.out = length(plots )), yAxisN )
63
+ } else {
64
+ seq_len(sum(yAxisN ))
65
+ }
54
66
xAxisMap <- setNames(
55
67
unlist(lapply(xAxes , names )),
56
- paste0(" xaxis" , sub(" ^1$" , " " , seq_len(sum( xAxisN )) ))
68
+ paste0(" xaxis" , sub(" ^1$" , " " , xAxisID ))
57
69
)
58
70
yAxisMap <- setNames(
59
71
unlist(lapply(yAxes , names )),
60
- paste0(" yaxis" , sub(" ^1$" , " " , seq_len(sum( yAxisN )) ))
72
+ paste0(" yaxis" , sub(" ^1$" , " " , yAxisID ))
61
73
)
62
74
# split the map by plot ID
63
75
xAxisMap <- split(xAxisMap , rep(seq_along(plots ), xAxisN ))
@@ -109,7 +121,7 @@ subplot <- function(..., nrows = 1, widths = NULL, heights = NULL, share = NULL,
109
121
# start merging the plots into a single subplot
110
122
p <- list (
111
123
data = Reduce(c , traces ),
112
- layout = Reduce(c , c(xAxes , yAxes ))
124
+ layout = Reduce(modifyList , c(xAxes , rev( yAxes ) ))
113
125
)
114
126
p $ layout $ annotations <- Reduce(c , annotations )
115
127
p $ layout $ shapes <- Reduce(c , shapes )
0 commit comments