codextrophic-energy-budget.py
trophic-energy-budget.py
"""Plot a production budget with explicitly assumed 10% transfer efficiency.
Tested with Python 3.14.4, NumPy 2.3.5 and Matplotlib 3.10.7.
Write an opaque white same-basename PNG to the working directory.
"""
from pathlib import Path
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
def main():
efficiency = 0.10
production = 1000 * efficiency ** np.arange(3)
not_transferred = production[:-1] - production[1:]
np.testing.assert_allclose(production, [1000, 100, 10])
np.testing.assert_allclose(not_transferred, [900, 90])
fig, ax = plt.subplots(figsize=(8.8, 4.9))
fig.set_facecolor("white")
ax.set_facecolor("white")
fig.subplots_adjust(left=0.24, right=0.95, top=0.76, bottom=0.29)
y = np.array([2, 1, 0])
ax.barh(y, production, height=0.48,
color=["#5c8b48", "#367fa3", "#9d6298"], zorder=3)
for pos, value in zip(y, production):
ax.text(value + 14, pos, f"{value:g}", va="center",
fontsize=13, weight="bold", color="#243642")
ax.set_yticks(y, ["Level 1\nPrimary producers",
"Level 2\nPrimary consumers", "Level 3\nSecondary consumers"])
ax.set_xlim(0, 1100)
ax.set_ylim(-0.6, 2.6)
ax.set_xticks(np.arange(0, 1001, 200))
ax.set_xlabel("Net production (kJ per m² per day) • one linear scale", fontsize=11)
ax.tick_params(axis="both", labelsize=11)
ax.grid(axis="x", color="#dce3e8", linewidth=0.8, zorder=0)
ax.spines[["top", "right", "left"]].set_visible(False)
ax.tick_params(axis="y", length=0)
fig.text(0.5, 0.94, "An assumed trophic energy budget", ha="center",
fontsize=16, weight="bold", color="#243642")
fig.text(0.5, 0.87, "10% transfer at EACH step is assumed, not a universal law",
ha="center", fontsize=11.5, color="#243642")
fig.text(0.5, 0.16, "1000 × 0.10 = 100 100 × 0.10 = 10", ha="center",
fontsize=12, color="#243642")
fig.text(0.5, 0.095, "Production not transferred along this chain: 900, then 90",
ha="center", fontsize=11, color="#243642")
fig.text(0.5, 0.04, "Includes other material routes and heat; these differences are not heat alone",
ha="center", fontsize=10, color="#243642")
fig.savefig(Path(__file__).with_suffix(".png").name, dpi=130,
facecolor="white", transparent=False)
plt.close(fig)
print(f"Production: {production.tolist()}; not transferred: {not_transferred.tolist()}")
if __name__ == "__main__":
main()