.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/climate/plot_15_gregory_forcing_feedback_regression.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_15_gregory_forcing_feedback_regression.py: Gregory's forcing-feedback regression (2004) ============================================ Jonathan Gregory and colleagues proposed a way to read forcing and feedback from a single run in which CO2 is quadrupled abruptly. Each year the net top-of-atmosphere imbalance ``N = F - lambda T`` is plotted against the warming. The intercept is the forcing, the slope is minus the feedback, and the line crosses zero at the equilibrium warming, without running to equilibrium. Here the run is a one-box model with seeded annual noise added to the imbalance. .. GENERATED FROM PYTHON SOURCE LINES 13-39 .. image-sg:: /api/gallery/climate/images/sphx_glr_plot_15_gregory_forcing_feedback_regression_001.png :alt: Abrupt 4×CO2: 3.4 K per doubling :srcset: /api/gallery/climate/images/sphx_glr_plot_15_gregory_forcing_feedback_regression_001.png :class: sphx-glr-single-img .. code-block:: Python import matplotlib.pyplot as plt import numpy as np from earthsciencekit.climate import equilibrium_warming, gregory_regression, simulate_one_box from earthsciencekit.units import convert forcing, restoring, capacity = 7.4, 1.1, 3e8 years = np.arange(0, 151) warming = simulate_one_box(forcing, restoring, capacity, convert(years, "year", "s")).values[:, 0] imbalance = forcing - restoring * warming np.testing.assert_allclose(gregory_regression(warming, imbalance), [forcing, restoring]) noisy = imbalance + np.random.default_rng(2004).normal(0, 0.4, years.size) fitted_forcing, fitted_restoring = gregory_regression(warming[1:], noisy[1:]) assert np.isclose(fitted_forcing, forcing, rtol=0.1) and np.isclose(fitted_restoring, restoring, rtol=0.1) sensitivity = equilibrium_warming(fitted_forcing / 2, fitted_restoring) line = np.linspace(0, fitted_forcing / fitted_restoring, 2) fig, ax = plt.subplots() ax.scatter(warming[1:], noisy[1:], c=years[1:], s=10, cmap="viridis", label="annual means") ax.plot(line, fitted_forcing - fitted_restoring * line, "k", label=f"fit: F = {fitted_forcing:.1f} W/m², λ = {fitted_restoring:.2f}") ax.axhline(0, color="0.5", lw=0.8) ax.set(xlabel="warming [K]", ylabel="TOA imbalance [W/m²]", title=f"Abrupt 4×CO2: {sensitivity:.1f} K per doubling") ax.legend() plt.show() .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.090 seconds) .. _sphx_glr_download_api_gallery_climate_plot_15_gregory_forcing_feedback_regression.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_15_gregory_forcing_feedback_regression.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_15_gregory_forcing_feedback_regression.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_15_gregory_forcing_feedback_regression.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_15_gregory_forcing_feedback_regression.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_