.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/climate/plot_08_keeling_curve.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code or to run this example in your browser via JupyterLite. .. rst-class:: sphx-glr-example-title .. _sphx_glr_api_gallery_climate_plot_08_keeling_curve.py: Keeling's curve (1958) ====================== Charles David Keeling began continuous measurements of carbon dioxide at Mauna Loa in 1958. Within two years the record showed a seasonal cycle from the breathing of northern forests and a steady rise. Here the rise is synthetic: emissions grow by 2% a year and each pulse decays in a single reservoir with a 50-year time scale. For steady exponential growth, the fraction of emitted carbon left in the air tends to ``g tau / (1 + g tau)``, here one half. .. GENERATED FROM PYTHON SOURCE LINES 13-39 .. image-sg:: /api/gallery/climate/images/sphx_glr_plot_08_keeling_curve_001.png :alt: A synthetic Keeling curve, airborne fraction 0.50 :srcset: /api/gallery/climate/images/sphx_glr_plot_08_keeling_curve_001.png :class: sphx-glr-single-img .. code-block:: Python import matplotlib.pyplot as plt import numpy as np from earthsciencekit.climate import carbon_airborne_fraction, carbon_decay from earthsciencekit.units import convert growth, tau = 0.02, 50.0 # per year, years years = np.arange(1750, 2020, 1 / 12) dt = 1 / 12 emissions = 10e12 * np.exp(growth * (years - 2020)) # kg C per year age = years[:, None] - years[None, :] weight = carbon_decay(emissions[None, :] * dt, convert(tau, "year", "s"), convert(np.clip(age, 0, None), "year", "s")) excess = np.where(age >= 0, weight, 0).sum(axis=1) exact = 10e12 * (np.exp(growth * (years - 2020)) - np.exp(growth * (1750 - 2020) - (years - 1750) / tau)) / (growth + 1 / tau) np.testing.assert_allclose(excess[120:], exact[120:], rtol=0.02) fraction = carbon_airborne_fraction(excess[-1], emissions.sum() * dt) assert np.isclose(fraction, growth * tau / (1 + growth * tau), atol=0.02) ppm = 280 + excess / 2.12e12 + 3 * np.sin(2 * np.pi * (years - 0.3)) record = years >= 1958 fig, ax = plt.subplots() ax.plot(years[record], ppm[record], lw=0.8) ax.set(xlabel="year", ylabel="CO2 [ppm]", title=f"A synthetic Keeling curve, airborne fraction {fraction:.2f}") plt.show() .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.281 seconds) .. _sphx_glr_download_api_gallery_climate_plot_08_keeling_curve.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: lite-badge .. image:: images/jupyterlite_badge_logo.svg :target: ../../../lite/lab/index.html?path=api/gallery/climate/plot_08_keeling_curve.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_08_keeling_curve.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_08_keeling_curve.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_08_keeling_curve.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_