1 Overview

Welcome! This bite-sized adventure turns open elevation data into a spin-able, zoom-able 3D model of the Grand Canyon. We’ll fetch a Digital Elevation Model (DEM) and render it as an interactive surface you can explore right in your browser.

  • Use your mouse/trackpad to rotate, zoom, and pan the 3D surface (try dragging while holding Shift!).
  • Elevations are in meters. The default view frames the main canyon corridor.
  • Curious to tweak it? Change the parameters at the top: bbox corners (xmin/xmax/ymin/ymax), zoom level z, and color scale.

Prefer to run the function in your own script? Download it here:

Download grand_canyon_3d.R

2 Data and Method

  • Elevation source: fetched on-the-fly via elevatr::get_elev_raster (typically backed by AWS Terrain Tiles). Availability and resolution may vary by location and zoom.
  • Processing: The DEM is optionally aggregated to keep the visualization responsive, then rendered as a plotly surface. A small bounding-box buffer helps avoid tile-edge NAs.

3 Requirements

Install required packages (shown as code only; not executed during knit):

install.packages(c("elevatr", "sf", "terra", "plotly", "progress"))

4 Parameters

  • Bounding box (WGS84 degrees): xmin, ymin, xmax, ymax
  • Zoom z (typical range 8–13; higher is finer and heavier)
  • bbox_buffer (degrees): expands the bbox slightly to dodge tile-edge gaps
  • max_cells: controls aggregation for performance
  • colors: plotly color scale (e.g., “Viridis”, “Cividis”, “Earth”)

5 Render the 3D Surface

The code below sources the helper function defined in grand_canyon_3d.R, then generates the plot using the parameters above. If a fetch fails (e.g., due to tile gaps), an informative message is shown instead of stopping the entire knit.

bbox <- c(xmin = params$xmin, ymin = params$ymin, xmax = params$xmax, ymax = params$ymax)

p <- tryCatch(
  grand_canyon_plotly(
    bbox = bbox,
    z = params$z,
    bbox_buffer = params$bbox_buffer,
    max_cells = params$max_cells,
    colors = params$colors,
    display = FALSE
  ),
  error = function(e) {
    message("3D plot failed: ", e$message)
    NULL
  }
)

if (!is.null(p)) {
  # Smooth, light plotly theme to match the page; increase height for a larger view
  p <- plotly::layout(p, template = "plotly_white", height = 720)
  p
}

6 Tips for Best Results

  • If the plot fails with a message about no valid values, try increasing bbox_buffer or changing z (e.g., 10 or 12).
  • For smoother interaction on lower-spec machines, lower z or reduce max_cells.
  • Larger extents and higher zooms produce bigger HTML files. If publishing to RPubs, keep the file size modest by reducing max_cells or z.

7 Appendix: Session Info

sessionInfo()
## R version 4.4.2 (2024-10-31)
## Platform: aarch64-apple-darwin20
## Running under: macOS 26.0.1
## 
## Matrix products: default
## BLAS:   /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRblas.0.dylib 
## LAPACK: /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.12.0
## 
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
## 
## time zone: America/Phoenix
## tzcode source: internal
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] progress_1.2.3 plotly_4.11.0  ggplot2_3.5.2  elevatr_0.99.1 terra_1.8-60  
## [6] sf_1.0-21     
## 
## loaded via a namespace (and not attached):
##  [1] tidyr_1.3.1        sass_0.4.10        generics_0.1.4     class_7.3-22      
##  [5] KernSmooth_2.23-24 lattice_0.22-6     hms_1.1.3          digest_0.6.37     
##  [9] magrittr_2.0.3     evaluate_1.0.5     grid_4.4.2         RColorBrewer_1.1-3
## [13] fastmap_1.2.0      jsonlite_2.0.0     e1071_1.7-16       DBI_1.2.3         
## [17] httr_1.4.7         purrr_1.1.0        crosstalk_1.2.2    viridisLite_0.4.2 
## [21] scales_1.4.0       slippymath_0.3.1   lazyeval_0.2.2     codetools_0.2-20  
## [25] jquerylib_0.1.4    cli_3.6.5          crayon_1.5.3       rlang_1.1.6       
## [29] units_0.8-7        withr_3.0.2        cachem_1.1.0       yaml_2.3.10       
## [33] raster_3.6-32      tools_4.4.2        dplyr_1.1.4        curl_7.0.0        
## [37] vctrs_0.6.5        R6_2.6.1           proxy_0.4-27       lifecycle_1.0.4   
## [41] classInt_0.4-11    htmlwidgets_1.6.4  pkgconfig_2.0.3    progressr_0.16.0  
## [45] pillar_1.11.0      bslib_0.9.0        gtable_0.3.6       glue_1.8.0        
## [49] data.table_1.17.8  Rcpp_1.1.0         xfun_0.53          tibble_3.3.0      
## [53] tidyselect_1.2.1   rstudioapi_0.17.1  knitr_1.50         farver_2.1.2      
## [57] htmltools_0.5.8.1  rmarkdown_2.29     compiler_4.4.2     prettyunits_1.2.0 
## [61] sp_2.2-0