# set the working directory for the code chunks to the project directory rather than # the directory in which the Rmd document is housed. # Don't print any messages, warnings, or code. knitr::opts_knit$set(root.dir = rprojroot::find_rstudio_root_file()) knitr::opts_chunk$set( echo = FALSE, message = FALSE, warning = FALSE, out.width= "90%", fig.align='center', dpi = 300, results = 'hide' ) xfun::pkg_attach(c("tidyverse", "rgl", "magick", "cowplot", "patchwork")) theme_set(theme_cowplot()) # start clock start_time <- Sys.time()
# test_dates <- params$test_dates test_dates <- "2021-01-15"
# construct file paths based on date drydown_paths <- paste0("analysis/data/raw_data/cleat_mark_testing/", test_dates, "/", test_dates, "_drydown_data.csv") test_time_water_content_data <- purrr::map( .x = drydown_paths, .f = readr::read_csv, na = "-", col_types = cols(cylinder_ID = col_character(), tin_tare_set = col_character()) ) %>% purrr::map(.f = ~dplyr::filter(., .data$time_type == "test_time")) # write a function that computes the water content for all the samples # on a given day (i.e. in a given drydown data file)....it should # perform a separate lookup for the tin tares based on the unique date # value found in the file itself. cleat_mark_water_contents <- function(path){ # read drydown data files w_data <- readr::read_csv(path, na= "-") %>% dplyr::filter(time_type == "test_time") # join to correct tin tare set tin_tare_date <- unique(as.character(w_data$tin_tare_set)) w_data <- w_data %>% dplyr::left_join(asi468::tin_tares[[tin_tare_date]])%>% soiltestr::add_w() %>% dplyr::select(.data$soil_ID, .data$date, .data$cylinder_ID, .data$water_content, .data$comments) return(w_data) } # apply the function to all the paths to drydown files listed above (which # in turn was constructed from the `test_dates` parameter in the YAML, # this way everything is linked to the date of data collection water_content_values <- purrr::map(.x =drydown_paths, .f = cleat_mark_water_contents) %>% purrr::reduce(rbind)
daily_directories <- paste0("analysis/data/derived_data/cleat_mark_testing/", test_dates, "/") mesh_file_paths <- purrr::map(.x = daily_directories, .f = ~list.files(path = paste0(., "/processed_meshes"), pattern = "[.]ply$", full.names = T)) %>% purrr::reduce(.x = ., .f = c) # read mesh files into current R session and enframe them in a tibble meshes <- soilmesh::read_meshfiles(mesh_file_paths) %>% dplyr::arrange(cylinder_ID) %>% dplyr::left_join(water_content_values)
# compute the volume and surface area metrics and join with water contents # meshes <- meshes %>% # dplyr::mutate(vol_above = purrr::map_dbl(mesh_object, soilmesh::vol_above), # vol_below = purrr::map_dbl(mesh_object, soilmesh::vol_below), # vol_total = vol_above + vol_below, # surf_area_cm2 = (0.1*0.1)*purrr::map_dbl(mesh_object, Rvcg::vcgArea), # rfi = surf_area_cm2 / (7*7*pi)) %>% # dplyr::left_join(water_content_values)
# eventually I will probably want to # map color to date and facet by metric # for now use color to distinguish the soils # construct paths to data files metrics_file_paths <- paste0(daily_directories, "/", test_dates, "_mesh_metrics.csv") metrics_plotting_data <- purrr::map(metrics_file_paths, readr::read_csv, col_types = readr::cols(date = readr::col_date()), na = c("NA", "-")) %>% purrr::reduce(rbind) %>% tidyr::pivot_longer(cols= c(vol_above:dne), names_to = "metric", values_to = "value") %>% dplyr::filter(metric != "surf_area_cm2") %>% dplyr::left_join(water_content_values) # set more readable facet labels by writing a labeller function # metric_facet_labs <- tibble::tibble(metric = c(rfi= "RFI", surf_area_cm2 = "Surface~area(cm^2)", vol_above = "Vol.~above~datum(cm^3)", vol_below = "Vol.~above~datum(cm^3)", vol_below = "Total~vol.~(cm^3)")) metric_facet_labs <- as_labeller(c(rfi= "RFI", surf_area_cm2 = "Surface~area~(cm^2)", vol_above = "Volume~above~(cm^3)", vol_below = "Volume~above~(cm^3)", vol_total = "Total~volume~(cm^3)", dne = "DNE"), default = label_parsed) metrics_plots <- ggplot(metrics_plotting_data, aes(water_content, value, fill = soil_ID))+ geom_point(size = 2.5, shape =21, alpha= 2/3, stroke =0.25)+ theme_bw()+ scale_x_continuous(labels = scales::label_percent(accuracy = 1, suffix = ""))+ labs(x= bquote("Water content, % g g"^-1), y= "Metric value")+ #guides(fill = guide_legend(title = "Soil ID", title.hjust = 0.5))+ colorblindr::scale_fill_OkabeIto()+ theme(strip.text.y = element_text(angle = 0, hjust = 0.5, vjust = 0.5), strip.background = element_rect(fill = 'grey95'), legend.position = 'none', panel.grid.minor = element_blank())+ facet_grid(metric~soil_ID, scales = 'free_y', labeller = labeller(metric = metric_facet_labs)) print(metrics_plots)
drydown_plots <- purrr::map(drydown_paths, soilmesh::drydown_analysis) %>% purrr::map(pluck, 3) patchwork::wrap_plots(drydown_plots, ncol = 1)
# read snapshots into R session with magick # construct file paths to read images into R session # then read images for each row and add a new column containing th the text with which to annotate the image . Add the text. meshes_w_images <- metrics_plotting_data %>% tidyr::pivot_wider(names_from = 'metric', values_from = 'value') %>% dplyr::left_join(meshes) %>% mutate( image_path = paste0( "analysis/data/derived_data/cleat_mark_testing/", date, "/mesh_snapshots/", experiment_name, "_", soil_ID, "_", date, "_cyl", cylinder_ID, "_4x3.png" ), image = purrr::map(image_path, magick::image_read) ) %>% mutate( image_text = paste0( "w = ", 100 * round(water_content, 3), " | RFI = ", 100 * round(rfi - 1, 2), " | DNE = ", round(dne, 0), " | Vol. = ", round(vol_total, 1) ) ) %>% dplyr::arrange(.data$soil_ID, .data$date, dplyr::desc(.data$water_content)) # can't figure out how to do this with piping so just create the vector externally and tack it onto the tibble using the $. It has to be coerced to a list because a magick object apparently cant be treated as a regular vector magick_vector <- image_join(meshes_w_images$image) meshes_w_images$annotated_image <- as.list(image_annotate(magick_vector, text = meshes_w_images$image_text, size = 64)) # create new tibble of image montages, one per soil # montages <- meshes_w_images %>% # group_by(date, soil_ID) %>% # nest() %>% # mutate(by_soil_magick_vector = map(data, ~image_join(.$annotated_image)), # montage = map(by_soil_magick_vector, image_montage)) # # image_ggplot(montages$montage[[1]]) # The montage approach doesn't seem to be working as well as I had hoped. Instead let's try iterating over the individual images and putting them into a ggplot environment - then I can use patchwork to piece them together into a 1x3 patchwork object, creating one plot of 3 images per soil. meshes_w_images$ggplotimage <- map(meshes_w_images$annotated_image, image_ggplot) nested_ggplot_images <- meshes_w_images %>% group_by(date, soil_ID) %>% nest() %>% mutate(patchwork_title = paste0(soil_ID, ",", " tested ", strftime(date, format = "%b %e")), patchwork_of_images = map(data, ~patchwork::wrap_plots(.$ggplotimage, nrow = 1))) %>% arrange(soil_ID, date) # again I can't quite figure out how to do this inside a tibble using mutate # but I can do it externally with paired lists. # write a function to add the title to the patchwork add_soil_id <- function(patchwork_object, title){ patchwork_object+ patchwork::plot_annotation(title = title) } # construct list of arguments to pass to pmap patchwork_args <- nested_ggplot_images %>% ungroup() %>% rename(title = patchwork_title, patchwork_object = patchwork_of_images) %>% select(patchwork_object, title) # iterate over the arguments in parallel: the patchwork object and the title to add patchworks <- pmap(patchwork_args, add_soil_id) # If I wrap the titled patchworks into a single patchwork, the prior annotations are lost. However they can just be printed in succession to show all of them print(patchworks) # patchworks[[1]] # patchworks[[2]] # patchworks[[3]] # patchworks[[4]] end_time <- Sys.time() report_runtime <- round(as.numeric(end_time - start_time), 2)
Total run time was r report_runtime
seconds.
# which R packages and versions? sessioninfo::package_info() #if ("devtools" %in% installed.packages()) { # devtools::session_info() #}
# what commit is this file at? if ("git2r" %in% installed.packages() & git2r::in_repository(path = ".")){ git2r::repository(here::here()) }
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.