-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy path01-Atmospheric-Carbon-Dioxide.qmd
244 lines (206 loc) · 11.2 KB
/
01-Atmospheric-Carbon-Dioxide.qmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
---
title: "Atmospheric_Carbon_Dioxide"
author: "[email protected]"
format:
docx:
reference-doc: SAFE-Reference-Doc.docx
---
## Atmospheric Concentration of Carbon Dioxide at Mauna Loa
```{r}
#| include: false
### Load libraries
library(tidyverse)
library(lubridate)
library(here)
# remotes::install_github("nmfs-fish-tools/nmfspalette")
library(nmfspalette)
library(plotly)
library(reticulate)
# reticulate::install_miniconda()
# reticulate::conda_install('r-reticulate', 'python-kaleido')
# reticulate::py_install("packaging")
# reticulate::conda_install('r-reticulate', 'plotly', channel = 'plotly')
reticulate::use_miniconda('r-reticulate')
```
```{r}
#| include: false
# Set report year (RptYr), to make things easier
RptYr <- 2023
# Set path to variable: Atmospheric_CO2
# This is where the data are and where the plots will go
Dir <- here("Atmospheric_CO2")
```
```{r}
#| include: false
### Load data
# Note that the number of lines to skip changes each year, which is frustrating.
# Monthly CO2 concentration
atm_co2 <- read_csv(file = paste(Dir, '/co2_mm_mlo_', RptYr, '.csv', sep = ""), skip = 40)
# Annual Growth Rates
ann_gr <- read_csv(file = paste(Dir, '/co2_gr_mlo_', RptYr, '.csv', sep = ""), skip = 45)
# Annual concentrations, so that we're not providing a potentially different value
ann_co2 <- read_csv(file = paste(Dir, '/co2_annmean_mlo_', RptYr, '.csv', sep = ""), skip = 43)
```
```{r}
#| echo: false
# Note that the above needs to be 'echo' and not 'include' so that the error checks print.
# Pull out the ANNUAL values we need for the report
ann_mean_idx <- which(ann_co2$year == RptYr)
ann_mean <- ann_co2$mean[ann_mean_idx]
max_ann_mean <- max(ann_co2$mean)
if (ann_mean != max_ann_mean) {
print('The highest annual value was prior to the report year.')
}
# Pull out the MONTHLY values we need for the report & plots
yr_of_int <- which(atm_co2$year == RptYr)
prev_yrs <- which(atm_co2$year < RptYr)
all_yrs <- which(atm_co2$year <= RptYr)
monthly_max_RptYr <- max(atm_co2$average[yr_of_int])
monthly_max_PrevYrs <- max(atm_co2$average[prev_yrs])
if (monthly_max_PrevYrs > monthly_max_RptYr) {
print('The highest monthly value was prior to the report year.')
}
# Confirm current text hasn't changed for some reason
pass_350 <- which(ann_co2$mean >= 350)
pass_400 <- which(ann_co2$mean >= 400)
if (ann_co2$year[pass_350[1]] != 1988) {
print('Reevaluate the year that annual mean CO2 passed 350 ppm.')
}
if (ann_co2$year[pass_400[1]] != 2015) {
print('Reevaluate the year that annual mean CO2 passed 400 ppm.')
}
```
```{r}
#| include: false
# ### Create growth rate plot for reference
seasonadj <- nmfspalette::nmfs_cols("supdkgray") # seasonally adj
pdf(paste(Dir, '/AtmosphericCO2growth_ts_', RptYr, '.pdf', sep = ""), width = 5, height = 3.5)
plot(ann_gr$year, ann_gr$`ann inc`, type = "l", lwd = 2, col = seasonadj,
xlim = c(min(ann_gr$year), RptYr), ylim = c(0, 3.5),
xlab = "Year", ylab = "Parts per Million (ppm)",
xaxt = "n", yaxt = "n", xaxs = "i", yaxs = "i")
axis((1), at = seq(1960, 2020, 5), tck = 0.025)
axis((2), at = seq(0, 3.5, 0.5), tck = 0.025, las = 1)
axis((3), at = seq(1960, 2020, 5), tck = 0.025, labels = FALSE)
axis((4), at = seq(0, 3.5, 0.5), tck = 0.025, labels = FALSE)
dev.off()
```
```{r}
#| include: false
# Write csv for portal
# Renaming 'mean' to 'ppm'
# Note that output csvs go in their own folder
AtmosphericCO2 <- ann_co2 %>% select(year, mean)
AtmosphericCO2 <- rename(AtmosphericCO2, ppm = mean)
write_csv(AtmosphericCO2, file = paste(here(), '/PelagicClimate_', RptYr, '/AtmosphericCO2_', RptYr, '.csv', sep = ""))
```
```{r}
#| include: false
# Write csv for dashboard
# Note that dashboard output has its own folder
# Thanks to Emily Conklin for this chunk of code!
CO2_dashboard <- atm_co2 %>%
mutate(Date_Time = date_decimal(`decimal date`) %>%
format('%d-%b-%Y %H:%M') %>%
toupper) %>%
mutate(ID = "CO2") %>%
select(Date_Time, Year = year, Month = month, Value = average, Anom = deseasonalized, ID) %>%
mutate(Value_lm = NA, Anom_lm = NA, Units = "ppm")
write_csv(CO2_dashboard, file = here("Indicator_Dashboard", "Data",
paste('CO2_Dashboard_Data_', RptYr, '.csv', sep = "")))
```
```{r}
#| include: false
# Borrowing code from the dashboard for this chunk
# so that figures look the same across products
indicator_data <- CO2_dashboard |>
filter(Year <= RptYr)
# Create color palette for easy reference
oceans <- nmfs_palette("oceans")(3) # 1 = report_year, 3 = previous years
crustacean <- nmfs_palette("crustacean")(4) # 1 = linear trend
coral <- nmfs_palette("coral")(3) # 3 = annual average for Rpt Yr
ann_grey <- "#D0D0D0" # annual means; in NMFS branding guide but not in package
waves <- nmfs_palette("waves")(3) # annual means; in NMFS branding guide but not in package
seagrass <- nmfs_palette("seagrass")(3)
pal <- c(oceans[3], coral[2], waves[2], coral[3], crustacean[2])
# Formatting
plot_title_font <- list(size = 14)
plot_height <- 350 #in pixels
# Calculate annual means
ann_vals <- indicator_data |>
group_by(Year) |>
summarise(Value = mean(Value, na.rm = TRUE))
# Identify the current year, to overlay on plot
given_yr <- indicator_data |>
filter(Year == RptYr)
given_yr_ann <- bind_cols(rep(ann_vals$Value[dim(ann_vals)[1]]),
given_yr$Date_Time)
given_yr_ann <- rename(given_yr_ann, Value = ...1)
given_yr_ann <- rename(given_yr_ann, Date_Time = ...2)
p1 <- plot_ly(indicator_data, x = dmy_hm(indicator_data$Date_Time), y = ~Value,
type = "scatter", mode = "lines", line = list(color = pal[1]),
height = plot_height, name = "Monthly average") |>
add_trace(indicator_data, x = dmy_hm(indicator_data$Date_Time), y = ~Value_lm,
type = "scatter", mode = "lines", line = list(color = pal[5]),
name = "Long-term Trend") |>
add_trace(ann_vals, x = ymd_hm(paste(ann_vals$Year, '0601 00:00', sep = "")), y = ann_vals$Value,
type = "scatter", mode = "lines", line = list(color = pal[3]),
name = "Annual average") |>
add_trace(given_yr, x = dmy_hm(given_yr$Date_Time), y = given_yr$Value,
type = "scatter", mode = "lines", line = list(color = pal[2]),
name = paste("Monthly average,", RptYr)) |>
add_trace(given_yr_ann, x = dmy_hm(given_yr_ann$Date_Time), y = given_yr_ann$Value,
type = "scatter", mode = "lines", line = list(color = pal[4]),
name = paste("Annual average,", RptYr))
#apply same layout parameters for all plots
#custom x axis (min, every decade, report year)
all_years <- unique(indicator_data$Year)
first_date <- as.character(parse_date_time(indicator_data$Date_Time[1], orders = "d-b-Y H:M"))
date_axis <- c(first_date,
all_years[which(all_years %% 10 == 0)],
RptYr)
p1 <- p1 |> layout(title = list(text = "Indicator Time Series", x = 0.01, font = plot_title_font), #add title
xaxis = list(type = "date", tickformat = "%Y", tickmode = "array", tickvals = date_axis, tickangle = 90),
#xaxis = list(tick0 = min(indicator_data$Date_Time), dtick = "M24"),
yaxis = list(title = indicator_data$Units[1], hoverformat = '.3f', range = list(300, 430), tickvals = list(300, 320, 340, 360, 380, 400, 420, 430)), #add units and round values in hover display; not sure of a better way to set axis limits and ticks...
paper_bgcolor = 'transparent', plot_bgcolor = 'transparent', #transparent background
hovermode = "x unified", #show data for all traces simultaneously
hoverlabel = list(namelength = -1)) #don't cutoff hoverinfo due to length
#return plot - oddly works in R but results in an error when rendering
save_image(p1, paste(Dir, '/AtmosphericCO2_ts_', RptYr, '.pdf', sep = ""))
# NOTE - added below in the library import chunk at the top
# Handy reference, in case this doesn't work in the future
# from: https://stackoverflow.com/questions/64028289/export-plot-from-plotly-into-pdf
# install.packages('reticulate')
# reticulate::install_miniconda()
# reticulate::conda_install('r-reticulate', 'python-kaleido')
# reticulate::conda_install('r-reticulate', 'plotly', channel = 'plotly')
# reticulate::use_miniconda('r-reticulate')
# To export:
#
# library(plotly)
# kaleido(FINAL_plot, "FINAL_plot.pdf")
```
Rationale: Atmospheric carbon dioxide is a measure of what human activity has already done to affect the climate system through greenhouse gas emissions. It provides quantitative information in a simplified, standardized format that decision makers can easily understand. This indicator demonstrates that the concentration (and, in turn, warming influence) of greenhouse gases in the atmosphere has increased substantially over the last several decades.
\
Status: Atmospheric CO~2~ is increasing exponentially. This means that atmospheric CO~2~ is increasing more quickly over time. In `r RptYr`, the annual mean concentration of CO~2~ was `r ann_mean` ppm. This is the highest annual value recorded. This year also saw the highest monthly value, which was `r monthly_max_RptYr` ppm. In 1959, the first year full of the time series, the atmospheric concentration of CO~2~ was 316 ppm. The annual mean passed 350 ppm in 1988, and 400 ppm in 2015.
\
Description: Monthly mean atmospheric carbon dioxide (CO~2~) at Mauna Loa Observatory, Hawaiʻi in parts per million (ppm) from March 1958 to present. The observed increase in monthly average carbon dioxide concentration is primarily due to CO~2~ emissions from fossil fuel burning. Carbon dioxide remains in the atmosphere for a very long time, and emissions from any location mix throughout the atmosphere in approximately one year. The annual variations at Mauna Loa, Hawaiʻi are due to the seasonal imbalance between the photosynthesis and respiration of terrestrial plants. During the summer growing season, photosynthesis exceeds respiration, and CO~2~ is removed from the atmosphere. In the winter (outside the growing season), respiration exceeds photosynthesis, and CO~2~ is returned to the atmosphere. The seasonal cycle is strongest in the northern hemisphere because of its larger land mass.
\
Timeframe: Annual, monthly.
\
Region/Location: Mauna Loa, Hawaiʻi, but representative of global atmospheric carbon dioxide concentration. Note that due to the eruption of the Mauna Loa Volcano, measurements from Mauna Loa Observatory were suspended as of 29 November 2022. Observations from December 2022 to 4 July 2023 are from a site at the Maunakea Observatories, approximately 21 miles north of the Mauna Loa Observatory. Mauna Loa observations resumed in July 2023.
\
Measurement Platform: *In-situ* station.
\
Data available at: <https://gml.noaa.gov/ccgg/trends/data.html>.
\
Sourced from: Keeling et al. (1976), Thoning et al. (1989), and NOAA (2024a).
\
Graphics produced in part using Stawitz (2023).
## Additional Information
The following .csv files were downloaded from <https://gml.noaa.gov/ccgg/trends/data.html>:
- Mauna Loa CO2 monthly mean data (co2_mm_mlo.csv)
- Mauna Loa CO2 annual mean data (co2_annmean_mlo.csv)
- Mauna Loa CO2 annual mean growth rates (co2_gr_mlo.csv)
These files were manually appended with the report year (i.e., `r RptYr`). Information from these data was used to lend detail and context to the indicator status.