Skip to content

Commit 01c3f83

Browse files
committed
plot_crowns() [WIP]
1 parent 0e0999c commit 01c3f83

2 files changed

Lines changed: 58 additions & 23 deletions

File tree

R/plot_crowns.R

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
1-
#' Display modeled tree crowns vertically projected on subplot boundaries
1+
#' Display modeled tree crowns projected vertically on subplot boundaries
22
#'
33
#' `plot_crowns()` draws vertically projected tree crowns as discs overlaid on
44
#' subplot or microplot boundaries. The full four-subplot cluster, or
55
#' individual subplots, can be displayed with trees `>= 5.0` in. (`12.7` cm)
6-
#' diameter, or individual microplots can be display with saplings (i.e., trees
7-
#' `< 5` in. diameter).
6+
#' diameter. Individual microplots can also be displayed with saplings (i.e.,
7+
#' trees `< 5` in. diameter).
88
#'
99
#' @param tree_list A data frame with tree records for one FIA plot. Must have
1010
#' columns `SUBP` (FIA subplot number), `STATUSCD` (FIA integer tree status,
1111
#' `1` = live), `DIA` (tree diameter), `HT` (tree height), `ACTUALHT` (tree
1212
#' actual height, `ACTUALHT < HT` indicating a broken top), `DIST` (stem
1313
#' distance from subplot/microplot center), `AZIMUTH` (horizontal angle from
14-
#' subplot/microplot center to the stem location, in the range `0:359`), and
14+
#' subplot/microplot center to the stem location, in range `0:359`), and
1515
#' `CRWIDTH` (tree crown width).
1616
#' @param subplot Optional integer subplot number in the range `1:4` indicating
17-
#' a specific subplot for display. May be `NULL` or `NA` to display the full
18-
#' four-point cluster.
17+
#' a specific subplot for display. May be `NULL` or `NA` to display the whole
18+
#' four-point cluster plot.
1919
#' @param microplot A logical value, `TRUE` to display the modeled crowns of
2020
#' saplings overlaid of the microplot boundary of `subplot = n`. The default is
2121
#' `FALSE`. Ignored if `subplot` is not specified.
@@ -26,6 +26,11 @@
2626
#' given in meters, and tree diameters are assumed to be given in centimeters.
2727
#' **TODO: not currently implemented**
2828
#' @param main Character string giving the main plot title (on top).
29+
#' @param crown_col The color of tree crowns.
30+
#' @param stem_col The color of tree stems when plotting an individual subplot
31+
#' or microplot.
32+
#' @param subp_border_lwd The line width of subplot boundaries, a _positive_
33+
#' number, defaulting to `3`.
2934
#' @return
3035
#' The input, invisibly.
3136
#'
@@ -40,7 +45,26 @@
4045
#' main = "plantation microplot 4")
4146
#' @export
4247
plot_crowns <- function(tree_list, subplot = NULL, microplot = FALSE,
43-
linear_unit = "ft", main = "") {
48+
linear_unit = "ft", main = "", crown_col = "#328e13",
49+
stem_col = "#b85e00", subp_border_lwd = 3){
50+
51+
if (missing(tree_list) || is.null(tree_list))
52+
stop("'tree_list' is required", call. = FALSE)
53+
54+
if (!is.data.frame(tree_list))
55+
stop("'tree_list' must be a data frame", call. = FALSE)
56+
57+
required_cols <- c("SUBP", "STATUSCD", "DIA", "HT", "ACTUALHT", "AZIMUTH",
58+
"DIST", "CRWIDTH")
59+
60+
if (!all(required_cols %in% colnames(tree_list)))
61+
stop("'tree_list' is missing required columns", call. = FALSE)
62+
63+
if (!all(unique(tree_list$SUBP) %in% c(1, 2, 3, 4)))
64+
stop("'tree_list$SUBP' contains invalid subplot numbers", call. = FALSE)
65+
66+
if (any(tree_list$AZIMUTH < 0) || any(tree_list$AZIMUTH > 360))
67+
stop("'tree_list$AZIMUTH' contains values out of range", call. = FALSE)
4468

4569
if (is.null(linear_unit))
4670
linear_unit <- "ft"
@@ -83,13 +107,13 @@ plot_crowns <- function(tree_list, subplot = NULL, microplot = FALSE,
83107
trees_in$dia_ft <- 0.0833333 * trees_in$DIA
84108
trees_in <- trees_in[order(trees_in$height), ]
85109

110+
pts <- vector(mode = "list", length = 2)
86111
if (subplot) {
87-
pts <- vector(mode = "list", length = 2)
88112
names(pts) <- c("x", "y")
89113
pts$x <- trees_in$DIST * sin(trees_in$AZIMUTH * (pi / 180))
90114
pts$y <- trees_in$DIST * cos(trees_in$AZIMUTH * (pi / 180))
91115
} else {
92-
pts <- .get_tree_list_xy(trees_in)
116+
pts[1:2] <- .get_tree_list_xy(trees_in)
93117
}
94118

95119
crowns <- lapply(seq_len(nrow(trees_in)), \(i) {
@@ -113,23 +137,23 @@ plot_crowns <- function(tree_list, subplot = NULL, microplot = FALSE,
113137
gdalraster::g_envelope())
114138
names(rct) <- c("xmin", "xmax", "ymin", "ymax")
115139

116-
xlab <- paste0("x (", linear_unit, ")")
117-
ylab <- paste0("y (", linear_unit, ")")
140+
xlab <- sprintf("x (%s)", linear_unit)
141+
ylab <- sprintf("y (%s)", linear_unit)
118142
gdalraster::plot_geom(fia_poly, xlab, ylab, main, border = "gray62",
119-
lwd = 3, bbox = rct)
143+
lwd = subp_border_lwd, bbox = rct)
120144

121145
for (i in seq_len(nrow(trees_in))) {
122-
# alternate green: #40c945
123-
gdalraster::plot_geom(crowns[[i]], col = "#328e13", border = NA,
146+
gdalraster::plot_geom(crowns[[i]], col = crown_col, border = NA,
124147
add = TRUE)
125148
if (subplot) {
126-
gdalraster::plot_geom(stems[[i]], col = "#b85e00", border = NA,
149+
gdalraster::plot_geom(stems[[i]], col = stem_col, border = NA,
127150
add = TRUE)
128151
}
129152
}
130153

131154
border_col <- grDevices::adjustcolor("gray62", alpha.f = 0.2)
132-
gdalraster::plot_geom(fia_poly, border = border_col, lwd = 3, add = TRUE)
155+
gdalraster::plot_geom(fia_poly, border = border_col, lwd = subp_border_lwd,
156+
add = TRUE)
133157

134158
invisible(tree_list)
135159
}

man/plot_crowns.Rd

Lines changed: 18 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)