• Home
  • Team
  • Science
  • Publications
  • Visual Stories
    • CH4
    • Clouds
  • News

What is going on with methane?

Human activities have significantly altered the Earth’s carbon cycle and energy budget through the release of anthropogenic greenhouse gases (GHG), particularly carbon dioxide (CO2) and methane (CH4). While we have a good understanding of anthropogenic sources of CO2 at national to continental scales, uncertainties surrounding CH4 are an order of magnitude higher, as sources range from agriculture and waste management to fossil fuel production and use (Turner, Frankenberg, and Kort 2019; Saunois et al. 2017). The recent acceleration in the methane growth rate creates an urgency to act, yet we do not even understand the relative contribu- tions of natural climate feedbacks (Zhang et al. 2023) and anthropogenic sources (Jackson et al. 2020).

CH4 data from NOAA

Ground based in-situ data provide the most accurate information on the recent rise in global methane. Here you can observe the global rise, stagnation and recent acceleration of the global methane abundances, obtained directly from NOAA’s Monthly CH4 concentration data, globally averaged per month (black) and a 12 months running mean. Stagnation, renewed increase and acceleration periods are indicated in blue, yellow, and red, respectively.

//fileUrl = 'https://corsproxy.io/?' + encodeURIComponent('https://gml.noaa.gov/webdata/ccgg/trends/ch4/ch4_mm_gl.csv');
fileUrl = 'https://corsproxy.io/?url=https://gml.noaa.gov/webdata/ccgg/trends/ch4/ch4_mm_gl.csv'
//fileUrl = `/data/subset_data.csv`;
fileUrl = "https://corsproxy.io/?url=https://gml.noaa.gov/webdata/ccgg/trends/ch4/ch4_mm_gl.csv"
csvText = d3.text(fileUrl)
processedData = {
  const lines = csvText.split('\n').filter(line => line.trim().length > 0 && !line.startsWith('#'));
  return d3.csvParse(lines.join('\n'),d3.autoType);
}
processedData2 = processedData.map(d => ({
  ...d,
  Date: new Date(`${d.year}-${d.month}-01`) // Parsing year and month into a Date
}));
start = new Date(1980, 0)
end   = new Date(2024,0)
start = 1980-01-01
end = 2024-01-01
viewof slider = rangeSlider({
  min: 0,
  max: d3.timeDay.count(start, end),
  step: 1,
  format: d => formatDate(d3.timeDay.offset(start, d)),
  title: 'Pick a date range',
})
RuntimeError: rangeSlider is not defined
OJS Runtime Error (line 55, column 17)

rangeSlider is not defined

RuntimeError: rangeSlider is not defined
OJS Runtime Error (line 55, column 17)

rangeSlider is not defined

startDate = d3.timeDay.offset(start, slider[0])
stopDate  = d3.timeDay.offset(start, slider[1])
RuntimeError: rangeSlider is not defined
OJS Runtime Error

rangeSlider is not defined

RuntimeError: rangeSlider is not defined
OJS Runtime Error

rangeSlider is not defined

filtered = processedData2.filter(function(s2) {
  return s2.Date >= startDate && s2.Date <= stopDate;
})
RuntimeError: rangeSlider is not defined
OJS Runtime Error

rangeSlider is not defined

import { rangeSlider as rangeSlider } from '@mootari/range-slider'
formatDate = d3.timeFormat("%Y-%m-%d")
yMin = d3.min(filtered, d => d.average); // Get the minimum value of the 'average' field
yMax = d3.max(filtered, d => d.average);
RuntimeError: rangeSlider is not defined
OJS Runtime Error

rangeSlider is not defined

RuntimeError: rangeSlider is not defined
OJS Runtime Error

rangeSlider is not defined

stagnationDate = new Date("2005-01-01") 
increaseDate   = new Date("2010-01-01") 
accelerationDate = new Date("2015-01-01") 
topMargin= 1750
stagnationDate = 2005-01-01
increaseDate = 2010-01-01
accelerationDate = 2015-01-01
topMargin = 1750
function adjustTextPosition(plotDomain, fixedDate, defaultPosition) {
  if (fixedDate < plotDomain[0] || fixedDate > plotDomain[1]) {
    // Adjust the position to be within the domain
    // For example, set it to the start or end of the domain
    return plotDomain[0]; // or plotDomain[1]
  }
  return defaultPosition;
}
adjustTextPosition = ƒ(plotDomain, fixedDate, defaultPosition)
Plot.plot({
    width,
  y: {
    grid: true,
    label: "CH₄ (ppb)",
    domain: [yMin, yMax] // Set the y-axis domain
  },
  x: {
    grid: true,
    label: "time",
    domain: [d3.min(filtered, d => d.Date), d3.max(filtered, d => d.Date)] // Set the y-axis domain
  },
  color: { legend: true },
  style: { fontSize: "12px",},
  marks: [
    Plot.rectY([{}], { 
      x1: new Date("2000-01-01"), // lower x bound of your overlay
      x2: new Date("2007-01-01"), // upper x bound of your overlay
      y1: yMin,
      y2: yMax,
      fill: "blue", // color of the overlay
      fillOpacity: 0.1
    }),
    Plot.rectY([{}], { 
      x1: new Date("2007-01-01"), // lower x bound of your overlay
      x2: new Date("2015-01-01"), // upper x bound of your overlay
      y1: yMin,
      y2: yMax,
      fill: "yellow", // color of the overlay
      fillOpacity: 0.1
    }),
    Plot.rectY([{}], { 
      x1: new Date("2015-01-01"), // lower x bound of your overlay
      x2: new Date("2024-01-01"), // upper x bound of your overlay
      y1: yMin,
      y2: yMax,
      fill: "red", // color of the overlay
      fillOpacity: 0.1
    }),
    Plot.line(filtered, { 
      x: "Date", 
      y: "average",
      title: (d) =>
        `${formatDate(d.Date)} \n CH₄: ${d.average} +/- ${d.average_unc} ppb`, // \n makes a new line
    }),
    Plot.lineY(filtered, Plot.windowY({k: 12, reduce: "mean"}, {x: "Date", y: "average", stroke: "red"})),
    Plot.text([{}], {
      x: stagnationDate,
      y: 1820,
      textAnchor: "middle",
      dy: "-0.5em", // Adjust vertical position
      fontWeight: "bold",
      text: "Stagnation Period"
    })
  ]
})
RuntimeError: rangeSlider is not defined
OJS Runtime Error

rangeSlider is not defined

import {Plot} from "@mkfreeman/plot-tooltip"

References

Jackson, R B, M Saunois, P Bousquet, J G Canadell, B Poulter, A R Stavert, P Bergamaschi, Y Niwa, A Segers, and A Tsuruta. 2020. “Increasing Anthropogenic Methane Emissions Arise Equally from Agricultural and Fossil Fuel Sources.” Environmental Research Letters 15 (7): 071002. https://doi.org/10.1088/1748-9326/ab9ed2.
Saunois, Marielle, Philippe Bousquet, Ben Poulter, Anna Peregon, Philippe Ciais, Josep G Canadell, Edward J Dlugokencky, et al. 2017. “Variability and Quasi-Decadal Changes in the Methane Budget over the Period 2000–2012.” Atmospheric Chemistry and Physics 17 (18): 11135–61. https://doi.org/10.5194/essd-2016-25-rc2.
Turner, Alexander J, Christian Frankenberg, and Eric A Kort. 2019. “Interpreting Contemporary Trends in Atmospheric Methane.” Proceedings of the National Academy of Sciences 116 (8): 2805–13. https://doi.org/10.1073/pnas.1814297116.
Zhang, Zhen, Benjamin Poulter, Andrew F. Feldman, Qing Ying, Philippe Ciais, Shushi Peng, and Xin Li. 2023. “Recent Intensification of Wetland Methane Feedback.” Nature Climate Change 13 (5): 430–33. https://doi.org/10.1038/s41558-023-01629-0.
Source Code
---
comments: false
page-layout: full
bibliography: publications/cfranken2024_doi.bib
format:
  html:
    margin-top: 0em
    margin-bottom: 0em
    minimal: true
    smooth-scroll: true
    fig-responsive: true
    toc: false
    echo: false
    keep-hidden: true
    code-tools: true
---

## What is going on with methane?

Human activities have significantly altered the Earth’s carbon cycle and energy budget through the release of anthropogenic greenhouse gases (GHG), particularly carbon dioxide (CO<sub>2</sub>) and methane (CH<sub>4</sub>). While we have a good understanding of anthropogenic sources of CO2 at national to continental scales, uncertainties surrounding CH4 are an order of magnitude higher, as sources range from agriculture and waste management to fossil fuel production and use [@turner2019interpreting; @saunois2017variability]. The recent acceleration in the methane growth rate creates an urgency to act, yet we do not even understand the relative contribu- tions of natural climate feedbacks [@Zhang_2023] and anthropogenic sources [@Jackson_2020].

## CH<sub>4</sub> data from NOAA

Ground based in-situ data provide the most accurate information on the recent rise in global methane. Here you can observe the global rise, stagnation and recent acceleration of the global methane abundances, obtained directly from NOAA's Monthly [CH<sub>4</sub> concentration data](https://gml.noaa.gov/ccgg/trends_ch4/), globally averaged per month (black) and a 12 months running mean. Stagnation, renewed increase and acceleration periods are indicated in blue, yellow, and red, respectively.

```{ojs}
//fileUrl = 'https://corsproxy.io/?' + encodeURIComponent('https://gml.noaa.gov/webdata/ccgg/trends/ch4/ch4_mm_gl.csv');
fileUrl = 'https://corsproxy.io/?url=https://gml.noaa.gov/webdata/ccgg/trends/ch4/ch4_mm_gl.csv'
//fileUrl = `/data/subset_data.csv`;
```

```{ojs}
csvText = d3.text(fileUrl)
```

```{ojs}
processedData = {
  const lines = csvText.split('\n').filter(line => line.trim().length > 0 && !line.startsWith('#'));
  return d3.csvParse(lines.join('\n'),d3.autoType);
}
```

```{ojs}
processedData2 = processedData.map(d => ({
  ...d,
  Date: new Date(`${d.year}-${d.month}-01`) // Parsing year and month into a Date
}));
```

```{ojs}
start = new Date(1980, 0)
end   = new Date(2024,0)
```

```{ojs}
viewof slider = rangeSlider({
  min: 0,
  max: d3.timeDay.count(start, end),
  step: 1,
  format: d => formatDate(d3.timeDay.offset(start, d)),
  title: 'Pick a date range',
})
```

```{ojs}
startDate = d3.timeDay.offset(start, slider[0])
stopDate  = d3.timeDay.offset(start, slider[1]) 
```

```{ojs}
filtered = processedData2.filter(function(s2) {
  return s2.Date >= startDate && s2.Date <= stopDate;
})
```

```{ojs}
import { rangeSlider as rangeSlider } from '@mootari/range-slider'
```

```{ojs}
formatDate = d3.timeFormat("%Y-%m-%d")
```

```{ojs}
// Assuming 'filtered' is your dataset
yMin = d3.min(filtered, d => d.average); // Get the minimum value of the 'average' field
yMax = d3.max(filtered, d => d.average);
```

```{ojs}
stagnationDate = new Date("2005-01-01") 
increaseDate   = new Date("2010-01-01") 
accelerationDate = new Date("2015-01-01") 
topMargin= 1750
```

```{ojs}
function adjustTextPosition(plotDomain, fixedDate, defaultPosition) {
  if (fixedDate < plotDomain[0] || fixedDate > plotDomain[1]) {
    // Adjust the position to be within the domain
    // For example, set it to the start or end of the domain
    return plotDomain[0]; // or plotDomain[1]
  }
  return defaultPosition;
}
```

```{ojs}
Plot.plot({
    width,
  y: {
    grid: true,
    label: "CH₄ (ppb)",
    domain: [yMin, yMax] // Set the y-axis domain
  },
  x: {
    grid: true,
    label: "time",
    domain: [d3.min(filtered, d => d.Date), d3.max(filtered, d => d.Date)] // Set the y-axis domain
  },
  color: { legend: true },
  style: { fontSize: "12px",},
  marks: [
    Plot.rectY([{}], { 
      x1: new Date("2000-01-01"), // lower x bound of your overlay
      x2: new Date("2007-01-01"), // upper x bound of your overlay
      y1: yMin,
      y2: yMax,
      fill: "blue", // color of the overlay
      fillOpacity: 0.1
    }),
    Plot.rectY([{}], { 
      x1: new Date("2007-01-01"), // lower x bound of your overlay
      x2: new Date("2015-01-01"), // upper x bound of your overlay
      y1: yMin,
      y2: yMax,
      fill: "yellow", // color of the overlay
      fillOpacity: 0.1
    }),
    Plot.rectY([{}], { 
      x1: new Date("2015-01-01"), // lower x bound of your overlay
      x2: new Date("2024-01-01"), // upper x bound of your overlay
      y1: yMin,
      y2: yMax,
      fill: "red", // color of the overlay
      fillOpacity: 0.1
    }),
    Plot.line(filtered, { 
      x: "Date", 
      y: "average",
      title: (d) =>
        `${formatDate(d.Date)} \n CH₄: ${d.average} +/- ${d.average_unc} ppb`, // \n makes a new line
    }),
    Plot.lineY(filtered, Plot.windowY({k: 12, reduce: "mean"}, {x: "Date", y: "average", stroke: "red"})),
    Plot.text([{}], {
      x: stagnationDate,
      y: 1820,
      textAnchor: "middle",
      dy: "-0.5em", // Adjust vertical position
      fontWeight: "bold",
      text: "Stagnation Period"
    })
  ]
})
```

```{ojs}
import {Plot} from "@mkfreeman/plot-tooltip"
```

Caltech      Carnegie      Harvard

 
  • Google Scholar