diff --git a/h2/app.r b/h2/app.r index bdf9f00..e4de19e 100644 --- a/h2/app.r +++ b/h2/app.r @@ -23,7 +23,6 @@ ui <- fluidPage(theme = shinythemes::shinytheme("readable"), column(4, div( br(), br(), - actionButton(inputId = "launch_scenario", label = "Explore Hector", style = "background: #4174C3; color: white; @@ -36,11 +35,14 @@ ui <- fluidPage(theme = shinythemes::shinytheme("readable"), tabPanel(title = "Guides"), tabPanel(title = "Run Hector", fluidRow( - run_ui("run_1"), - #download_ui("download_1"), - ) - ), - tabPanel(title = p(icon("chart-pie","fa-2x"), "Carbon Tracking", value="outputTab")), + run_ui("run_1"), + ) + ), + tabPanel(title = "Carbon Tracking", + fluidRow( + tracking_ui("tracking_1") + ) + ), tabPanel(title = "About") ), hr(), @@ -49,12 +51,14 @@ ui <- fluidPage(theme = shinythemes::shinytheme("readable"), server <- function(input, output, session) { r6 <- HectorInputs$new() # r6 class + r6_tracking <- HectorInputs$new() # separate r6 class for carbon tracking observeEvent(input$launch_scenario, updateTabsetPanel(session, "nav", selected = "Run Hector"), ignoreInit = TRUE) run_server("run_1", r6 = r6) summary_server("summary_1", r6 = r6) graph_server("graph_1", r6 = r6) download_server("download_1", r6 = r6) + tracking_server("tracking_1") } # Run the application diff --git a/h2/components/modules/mod_tracking.R b/h2/components/modules/mod_tracking.R new file mode 100644 index 0000000..3a7c37d --- /dev/null +++ b/h2/components/modules/mod_tracking.R @@ -0,0 +1,215 @@ +tracking_ui <- function(id) { + ns <- NS(id) + fluidRow( + sidebarPanel( + chooseSliderSkin(skin = "Flat", color = "#375a7f"), + prettyRadioButtons(ns("ssp_path"), label="Select SSP:", + choices = list("SSP 1-1.9"="input/hector_ssp119.ini", + "SSP 1-2.6"="input/hector_ssp126.ini", + "SSP 2-4.5"="input/hector_ssp245.ini", + "SSP 3-7.0"="input/hector_ssp370.ini", + "SSP 4-3.4"="input/hector_ssp434.ini", + "SSP 4-6.0"="input/hector_ssp460.ini", + "SSP 5-3.4OS"="input/hector_ssp534-over.ini", + "SSP 5-8.5"="input/hector_ssp585.ini"), + selected = "input/hector_ssp245.ini", inline=TRUE, + shape = "square", width = "80%"), + bsPopover(ns("ssp_path"), title="",content="Select a Shared Socioeconomic Pathway to plot.", + placement = "top", trigger = "hover", options = NULL), + + sliderInput(ns("start"), label="Select year to begin tracking:", + min = 1750, max = 2200, value = 1900, sep="",step=5), + + selectInput(ns("pool"), label="Select pool to view:", + choices = list("High latitude ocean"="HL Ocean", + "Low latitude ocean"="LL Ocean", + "Intermediate ocean"="Intermediate Ocean", + "Deep ocean"="Deep Ocean", + "Atmosphere"="Atmosphere", + "Vegetation"="Vegetation", + "Detritus"="Detritus", + "Soil"="Soil"), + selected="Atmosphere"), + + prettyRadioButtons(ns("ff"), label="Toggle fossil fuels:", + choices = list("On"=1,"Off"=2)), + bsPopover(ns("ff"), title="",content="Select whether you want fossil fuels to be included (On), or only non-anthropogenic sources of carbon (Off).", + placement = "top", trigger = "hover", options = NULL), + prettyRadioButtons(ns("view"), label="View:", + choices = list("Carbon Amount"=1, + "Carbon Fraction"=2), + selected = 1), + bsPopover(ns("view"), title="",content="Select whether you want to view the total amounts of carbon in each pool (Carbon Amount), or the fraction each pool has of the total amount in the system (Carbon Fraction).", + placement = "top", trigger = "hover", options = NULL), + actionButton(ns("generate"),"Generate"), + downloadButton(ns("download"),"Download Plots"), + ), + mainPanel( + withSpinner(plotOutput(ns("fig"))), + imageOutput(ns("gif")), + ) + ) +} + +tracking_server <- function(id) { + moduleServer(id, function(input, output, session) { + + observe({ + # Run Hector w/ carbon tracking + ini_file <- reactive({system.file(input$ssp_path,package="hector")}) + core <- newcore(ini_file()) + tunits <- getunits(TRACKING_DATE()) + setvar(core, NA, TRACKING_DATE(), input$start, tunits) + reset(core, core$reset_date) + print("Running Hector...") + run(core, runtodate = 2300) + print("Gathering data...") + df <- get_tracking_data(core) + + # clean up pool names + df[df=="atmos_co2"] <- "Atmosphere" + df[df=="deep"] <- "Deep Ocean" + df[df=="detritus_c"] <- "Detritus" + df[df=="earth_c"] <- "Fossil Fuels" + df[df=="HL"] <- "HL Ocean" + df[df=="intermediate"] <- "Intermediate Ocean" + df[df=="LL"] <- "LL Ocean" + df[df=="soil_c"] <- "Soil" + df[df=="veg_c"] <- "Vegetation" + + ## filter df to just selected pool + selectedPool <- reactive({input$pool}) + df <- filter(df,pool_name==selectedPool()) + # filter out fossil fuels if selected + if (input$ff == 2) { + df <- subset(df, source_name!="Fossil Fuels") + } + # filter out permafrost rows (for now -- they're empty) + df <- subset(df, source_name!="permafrost_c") + df <- subset(df, source_name!="thawedp_c") + + # fill in any missing pools + df <- df[order(df$source_name),] # sort by source, then year, so sources are always in same order each year + df <- df[order(df$year),] + + + # rank column for moving bar plot + df <- df %>% + group_by(year) %>% + mutate(rank = rank(-source_fraction), + frac_rel = source_fraction/source_fraction[rank==1], + source_amt = source_fraction*pool_value, + amt_lbl = paste0(format(round(source_amt,2), nsmall=2), " Pg C"), + frac_lbl = paste0(format(round(source_fraction,2),nsmall=2))) %>% + group_by(source_name) %>% + ungroup() + + # Carbon amount + if (input$view == 1) { + area_plot <- + ggplot(df, aes(x=year,y=source_amt,fill=source_name)) + + geom_area(stat="identity") + + scale_fill_viridis_d(name="Source") + + scale_color_viridis_d() + + ggtitle(paste0(selectedPool(), " Carbon Amount by Source")) + + xlab("") + + ylab("Carbon Pool (Pg C)") + + theme(plot.title = element_text(size=20,face="bold"), + legend.title=element_text(size=16), + legend.position="bottom", + legend.text=element_text(size=12), + axis.title.y=element_text(size=14), + axis.text=element_text(size=10), + plot.margin = margin(1,1,1,1,"cm")) + + # save as file + ggsave("outfile_area.jpeg",plot=area_plot,device="jpeg", + dpi=72,width=800,height=500,units="px") + + } + + # Carbon fraction + if (input$view == 2) { + + print("Generating plot...") + area_plot <- + ggplot(df, aes(x=year,y=source_fraction,fill=source_name)) + + geom_area(stat="identity") + + scale_fill_viridis_d() + + scale_color_viridis_d() + + ggtitle(paste0(selectedPool(), " Carbon Fraction by Source")) + + xlab("") + + ylab("Carbon Pool (Fraction)") + + theme(plot.title = element_text(size=20,face="bold"), + legend.title=element_text(size=16), + legend.position="bottom", + legend.text=element_text(size=12), + axis.title.y=element_text(size=14), + axis.text=element_text(size=10), + plot.margin = margin(1,1,1,1,"cm")) + + # save as file + ggsave("outfile_area.jpeg",plot=area_plot,device="jpeg", + width=800,height=500,units="px") + + } + + output$fig <- renderPlot(area_plot) + + output$gif <- renderImage({ + + # Make animation + p <- ggplot(df,aes(fill=source_name,color=source_name, + x=reorder(source_name,source_amt), + y=source_amt)) + + geom_bar(stat="identity") + + geom_text(aes(y=0, label = paste(source_name, " ")), + vjust = 0.2, hjust = 1, size = 6) + + geom_text(aes(y = source_amt, label = paste(" ",amt_lbl), hjust=0), + size = 6) + + coord_flip(clip = "off", expand = FALSE) + + theme_void() + + theme(plot.title = element_text(size=20,face="bold"), + plot.subtitle = element_text(size=18), + legend.position="none", + panel.grid.major.x = element_line(linewidth=.1,color="snow2"), + panel.grid.minor.x = element_line(linewidth=.1,color="snow2"), + plot.margin = margin(1,6,1,6,"cm")) + + ylab("Carbon (Pg)") + + xlab("") + + scale_fill_viridis_d() + + scale_color_viridis_d() + + + # gganimate + transition_time(year) + + ease_aes('linear') + + # Animate + anim <- p + transition_states(year,transition_length=4, + state_length=2,wrap=FALSE) + + view_follow(fixed_x = TRUE) + + labs(title=paste0(selectedPool()," Carbon Sources"), + subtitle="Year: {closest_state}") + + anim_save("outfile_bar.gif", animate(anim, height = 500, width = 800, + end_pause=30)) + list(src = 'outfile_bar.gif', + contentType = 'image/gif' + # width = 800, + # height = 500, + # alt = "An animation tracking the sources of carbon in a chosen pool" + )}, deleteFile = FALSE) + + }) %>% + bindEvent(input$generate) + + # Download plots + output$download <- downloadHandler( + filename="myplots.zip", + content=function(file){ + zip(file,files=c('outfile_area.jpeg','outfile_bar.gif')) + } + ) + + }) +} \ No newline at end of file diff --git a/h2/global.r b/h2/global.r index b8cb551..beaeef6 100644 --- a/h2/global.r +++ b/h2/global.r @@ -5,16 +5,21 @@ library(dplyr) library(ggplot2) library(shinycssloaders) library(plotly) -library(shinyalert) # don't need if we have shinyWidgets? library(DT) library(shinyWidgets) +library(gganimate) +library(tidyverse) +library(shinyBS) +library(zip) +library(svglite) -#setwd("~/GitHub/hectorui/h2") +setwd("~/GitHub/hectorui/h2") source("./components/modules/mod_graph.r") source("./components/modules/mod_run.r") source("./components/modules/mod_summary.r") source("./components/modules/mod_download.r") +source("./components/modules/mod_tracking.r") source("./components/functions/func_graph_plots.R") theme_set(theme_minimal()) @@ -37,13 +42,11 @@ HectorInputs <- R6Class( package = "hector")) { self$ini_file <- ini_file self$time <- time - # self$time[2] <- time self$output <- list() self$no_save <- NULL self$run_name <- 1 self$inputs <- list() self$selected_var <- "CO2_concentration" - #stopifnot(time[2] > time[1]) #gotta have the start year before the end year } ) ) @@ -154,3 +157,4 @@ units <- list("CO2_concentration" = "DegC", "heatflux_interior" = "W/m2", "heatflux" = "W/m2" ) +