## ----------------------------------------------------------------------------- #| label: Setup #| include: false library(here) source(here("R", ".setup.R")) ## ----------------------------------------------------------------------------- #| output: false library(logolink) library(dplyr) library(ggplot2) library(ggimage) library(ggtext) library(here) library(magick) library(magrittr) library(ragg) library(stringr) library(tidyr) ## ----------------------------------------------------------------------------- model_path <- find_netlogo_home() |> file.path( "models", "IABM Textbook", "chapter 4", "Wolf Sheep Simple 5.nlogox" ) ## ----------------------------------------------------------------------------- sheep_shape <- get_netlogo_shape("sheep") ## ----------------------------------------------------------------------------- wolf_shape <- get_netlogo_shape("wolf") ## ----------------------------------------------------------------------------- setup_file <- create_experiment( name = "Wolf Sheep Simple Model Analysis", repetitions = 1, sequential_run_order = TRUE, run_metrics_every_step = FALSE, setup = "setup", go = "go", time_limit = 500, run_metrics_condition = 'ticks mod 100 = 0', metrics = c( '[xcor] of sheep', '[ycor] of sheep', '[xcor] of wolves', '[ycor] of wolves', '[pxcor] of patches', '[pycor] of patches', '[pcolor] of patches' ), constants = list( "number-of-sheep" = 100, "number-of-wolves" = 15, "movement-cost" = 0.5, "grass-regrowth-rate" = 0.3, "energy-gain-from-grass" = 2, "energy-gain-from-sheep" = 5 ) ) ## ----------------------------------------------------------------------------- #| output: false results <- model_path |> run_experiment( setup_file = setup_file, output = c("table", "lists") ) #> ✔ Running model [2.1s] #> ✔ Gathering metadata [12ms] #> ✔ Processing table output [33ms] #> ✔ Processing lists output [6ms] ## ----------------------------------------------------------------------------- results |> extract2("lists") |> glimpse() #> Rows: 7,350 #> Columns: 16 #> $ run_number 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,… #> $ number_of_sheep 100, 100, 100, 100, 100, 100, 100, 100, 100,… #> $ number_of_wolves 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,… #> $ movement_cost 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,… #> $ grass_regrowth_rate 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3,… #> $ energy_gain_from_grass 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,… #> $ energy_gain_from_sheep 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,… #> $ step 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,… #> $ index "0", "1", "2", "3", "4", "5", "6", "7", "8",… #> $ pcolor_of_patches 56.35257, 55.37902, 55.10799, 56.12433,… #> $ pxcor_of_patches -12, 12, 7, -16, 6, -11, 11, 8, 5, -7, -13,… #> $ pycor_of_patches -6, 11, 10, 15, -14, 13, 13, 6, -9, 8, -5,… #> $ xcor_of_sheep -12.6365795, 16.9131184, -8.5579481,… #> $ xcor_of_wolves -17.368182, -11.239707, -13.813702, … #> $ ycor_of_sheep 17.44700318, 14.04946398, 12.60102781, … #> $ ycor_of_wolves 16.403987, -15.657477, -1.630277,… ## ----------------------------------------------------------------------------- plot_data <- results |> extract2("lists") |> mutate( across( .cols = matches("^pcolor_of_patches|^color_of_"), .fns = parse_netlogo_color ) ) ## ----------------------------------------------------------------------------- plot_netlogo_world <- function( data, run_number = 1, step = 0, step_label = TRUE ) { data <- data |> filter( run_number == .env$run_number, step == .env$step ) plot <- data |> ggplot( aes( x = pxcor_of_patches, y = pycor_of_patches, fill = pcolor_of_patches ) ) + geom_raster() + coord_fixed(expand = FALSE) + geom_image( data = data |> drop_na(xcor_of_sheep), mapping = aes( x = xcor_of_sheep, y = ycor_of_sheep, image = sheep_shape ), size = 0.04 ) + geom_image( data = data |> drop_na(xcor_of_wolves), mapping = aes( x = xcor_of_wolves, y = ycor_of_wolves, image = wolf_shape ), size = 0.055, color = parse_netlogo_color(31) ) + scale_fill_identity(na.value = parse_netlogo_color(7.5)) + theme_void() + theme(legend.position = "none") if (isTRUE(step_label)) { plot + labs(title = paste0("Step: **", step, "**")) + theme( plot.title.position = "plot", plot.title = element_markdown(size = 20, margin = margin(b = 10)), plot.background = element_rect(fill = "white", color = NA), plot.margin = margin(1.5, 1.5, 1.5, 1.5, "line") ) } else { plot } } ## ----------------------------------------------------------------------------- #| eval: false #| include: false # showtext_auto(FALSE) ## ----------------------------------------------------------------------------- plot_netlogo_world(plot_data) ## ----------------------------------------------------------------------------- #| eval: false #| include: false # ggsave( # filename = "vignette-wolf-sheep-model-plot-1.png", # plot = get_last_plot(), # device = agg_png, # path = here("man", "figures"), # width = 7, # height = 7.4, # units = "in", # dpi = 96 # ) ## ----------------------------------------------------------------------------- steps <- plot_data |> pull(step) |> unique() ## ----------------------------------------------------------------------------- steps #> [1] 0 100 200 300 400 500 ## ----------------------------------------------------------------------------- files <- character() cli_progress_bar("Generating frames", total = length(steps)) for (i in steps) { i_plot <- plot_netlogo_world(plot_data, step = i, step_label = TRUE) i_file <- tempfile(pattern = paste0("step-", i, "-"), fileext = ".png") ggsave( filename = i_file, plot = i_plot, device = agg_png, width = 7, height = 7.4, units = "in", dpi = 96 ) files <- append(files, i_file) cli_progress_update() } cli_progress_done() ## ----------------------------------------------------------------------------- animation <- files |> lapply(image_read) |> image_join() |> image_animate(fps = 1) ## ----------------------------------------------------------------------------- #| eval: false #| include: false # animation |> # image_write( # here( # "man", # "figures", # "vignette-wolf-sheep-model-animation-1.gif" # ) # ) ## ----------------------------------------------------------------------------- #| eval: false #| output: false # animation |> image_write("netlogo-world-animation.gif") ## ----------------------------------------------------------------------------- animation