{ "cells": [ { "cell_type": "code", "execution_count": null, "id": "d9bba75b", "metadata": {}, "outputs": [], "source": [ "# Préparation commune des TP Python\n", "# Le notebook utilise uniquement les ressources fournies dans le dossier codes/.\n", "from pathlib import Path\n", "import importlib.util\n", "import subprocess\n", "import sys\n", "\n", "REQUIRED_PACKAGES = {'numpy': 'numpy', 'pandas': 'pandas', 'matplotlib': 'matplotlib'}\n", "missing = [package for module, package in REQUIRED_PACKAGES.items()\n", " if importlib.util.find_spec(module) is None]\n", "if missing:\n", " print(\"Installation des paquets manquants :\", \", \".join(missing))\n", " subprocess.check_call([sys.executable, \"-m\", \"pip\", \"install\", *missing])\n", "\n", "WORKDIR = Path.cwd().resolve()\n", "CODES_DIR = WORKDIR.parent if WORKDIR.name == \"correction\" else WORKDIR\n", "TOOLBOX_DIR = CODES_DIR / \"toolbox\"\n", "DATA_DIR = CODES_DIR / \"data\"\n", "if not CODES_DIR.is_dir():\n", " raise FileNotFoundError(\"Exécutez le notebook depuis le dossier codes/.\" )\n", "if TOOLBOX_DIR.is_dir():\n", " sys.path.insert(0, str(TOOLBOX_DIR))\n", "\n", "DATA_FILE = DATA_DIR / \"temperature_historique.csv\"\n", "if not DATA_FILE.is_file():\n", " raise FileNotFoundError(\n", " f\"Donnée du cours introuvable : {DATA_FILE}. \"\n", " \"Téléchargez le dossier codes complet, avec data/.\"\n", " )\n", "\n", "print(\"Environnement prêt :\", CODES_DIR)\n" ] }, { "cell_type": "markdown", "id": "e6141848", "metadata": {}, "source": [ "# TP1 — Données climatiques historiques et tendances\n", "\n", "**Date de la séance :** mercredi 2 septembre 2026, 08:30–10:30\n", "\n", "**Objectifs**\n", "- Manipuler une série temporelle de température globale\n", "- Estimer une tendance de réchauffement climatique\n", "- Distinguer variabilité naturelle et tendance de long terme\n", "- Projeter la date de dépassement de seuils de réchauffement (+1,5°C, +2°C)\n", "\n", "**Prérequis** : numpy, pandas, matplotlib (bases de manipulation de tableaux et de graphiques)." ] }, { "cell_type": "code", "execution_count": null, "id": "482f7e93", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import pandas as pd\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "markdown", "id": "3a8be03a", "metadata": {}, "source": [ "## Partie 1 — Chargement des données" ] }, { "cell_type": "code", "execution_count": null, "id": "dff44741", "metadata": {}, "outputs": [], "source": [ "df = pd.read_csv(DATA_DIR / \"temperature_historique.csv\")\n", "print(df.shape)\n", "df.head()" ] }, { "cell_type": "markdown", "id": "01f729c9", "metadata": {}, "source": [ "**Question 1.** Tracez l'anomalie de température de 1880 à 2023." ] }, { "cell_type": "code", "execution_count": null, "id": "131e9fa4", "metadata": {}, "outputs": [], "source": [ "# Expected output: courbe bruitée croissante de -0.2°C (1880) à environ +1.1°C (2023)\n", "plt.figure(figsize=(9, 5))\n", "plt.plot(df['year'], df['T_anomaly'], color='tab:blue')\n", "plt.xlabel('Année')\n", "plt.ylabel('Anomalie de température (°C)')\n", "plt.title('Anomalie de température globale 1880-2023')\n", "plt.grid(True)\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "74df7f1a", "metadata": {}, "source": [ "## Partie 2 — Tendance linéaire" ] }, { "cell_type": "markdown", "id": "1f518eb4", "metadata": {}, "source": [ "**Question 2.** Calculez la tendance linéaire avec `np.polyfit`. Ajoutez la droite de tendance au graphique." ] }, { "cell_type": "code", "execution_count": null, "id": "93273963", "metadata": {}, "outputs": [], "source": [ "# Expected output: pente positive d'environ 0.007-0.008 °C/an (~0.7-0.8°C/siècle)\n", "coeffs = np.polyfit(df['year'], df['T_anomaly'], 1)\n", "trend = np.polyval(coeffs, df['year'])\n", "print(f\"Pente estimée : {coeffs[0]:.5f} °C/an (soit {coeffs[0]*100:.2f} °C/siècle)\")\n", "\n", "plt.figure(figsize=(9, 5))\n", "plt.plot(df['year'], df['T_anomaly'], color='tab:blue', label='Anomalie observée')\n", "plt.plot(df['year'], trend, color='tab:red', linewidth=2, label='Tendance linéaire')\n", "plt.xlabel('Année')\n", "plt.ylabel('Anomalie de température (°C)')\n", "plt.title('Anomalie de température et tendance linéaire')\n", "plt.legend()\n", "plt.grid(True)\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "85b810c2", "metadata": {}, "source": [ "## Partie 3 — Variabilité naturelle et tendance longue" ] }, { "cell_type": "markdown", "id": "34fe1d9b", "metadata": {}, "source": [ "**Question 3.** Calculez une moyenne mobile sur 10 ans. Tracez l'anomalie, la tendance et la moyenne mobile." ] }, { "cell_type": "code", "execution_count": null, "id": "1b069cab", "metadata": {}, "outputs": [], "source": [ "# Expected output: la moyenne mobile lisse le bruit annuel et suit la tendance de long terme\n", "window = 10\n", "df['rolling'] = df['T_anomaly'].rolling(window, center=True).mean()\n", "\n", "plt.figure(figsize=(9, 5))\n", "plt.plot(df['year'], df['T_anomaly'], color='tab:blue', alpha=0.4, label='Anomalie observée')\n", "plt.plot(df['year'], trend, color='tab:red', linewidth=2, label='Tendance linéaire')\n", "plt.plot(df['year'], df['rolling'], color='tab:green', linewidth=2, label=f'Moyenne mobile {window} ans')\n", "plt.xlabel('Année')\n", "plt.ylabel('Anomalie de température (°C)')\n", "plt.title('Anomalie, tendance et variabilité naturelle')\n", "plt.legend()\n", "plt.grid(True)\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "04a97869", "metadata": {}, "source": [ "## Partie 4 — Moyennes décennales" ] }, { "cell_type": "markdown", "id": "441eb1db", "metadata": {}, "source": [ "**Question 4.** Calculez la température moyenne par décennie (1880-1889, 1890-1899, ..., 2010-2019). Tracez un graphique en barres." ] }, { "cell_type": "code", "execution_count": null, "id": "64f0b705", "metadata": {}, "outputs": [], "source": [ "# Expected output: barres croissantes par décennie, de ~-0.15°C (1880s) à ~+0.9°C (2010s)\n", "df['decade'] = (df['year'] // 10) * 10\n", "dec_avg = df[df['decade'] < 2020].groupby('decade')['T_anomaly'].mean()\n", "\n", "plt.figure(figsize=(9, 5))\n", "dec_avg.plot(kind='bar', color='tab:orange')\n", "plt.xlabel('Décennie')\n", "plt.ylabel('Anomalie moyenne (°C)')\n", "plt.title('Anomalie de température moyenne par décennie')\n", "plt.grid(True, axis='y')\n", "plt.tight_layout()\n", "plt.show()\n", "dec_avg" ] }, { "cell_type": "markdown", "id": "21118722", "metadata": {}, "source": [ "## Partie 5 — Projection" ] }, { "cell_type": "markdown", "id": "007076a3", "metadata": {}, "source": [ "**Question 5.** En prolongeant la tendance linéaire, en quelle année atteint-on +1,5°C ? +2°C ?" ] }, { "cell_type": "code", "execution_count": null, "id": "d6272d73", "metadata": {}, "outputs": [], "source": [ "# Expected output: années de dépassement obtenues par extrapolation linéaire (résultat purement illustratif,\n", "# une vraie projection climatique nécessite un modèle physique, cf. TP2)\n", "year_15 = (1.5 - coeffs[1]) / coeffs[0]\n", "year_20 = (2.0 - coeffs[1]) / coeffs[0]\n", "print(f\"Seuil de +1.5°C atteint (extrapolation linéaire) vers l'année {year_15:.0f}\")\n", "print(f\"Seuil de +2.0°C atteint (extrapolation linéaire) vers l'année {year_20:.0f}\")" ] }, { "cell_type": "markdown", "id": "1861b166", "metadata": {}, "source": [ "## Interprétation\n", "\n", "**Répondez en quelques phrases :**\n", "1. Quelle est la vitesse de réchauffement observée depuis 1880 ?\n", "2. Est-ce que la tendance s'accélère ou reste-t-elle constante ?\n", "3. Quelle est la différence entre variabilité naturelle et tendance climatique ?\n", "4. Que représente l'anomalie de température par rapport à la météo quotidienne ?" ] }, { "cell_type": "markdown", "id": "e92db192", "metadata": {}, "source": [ "### Éléments de réponse\n", "\n", "1. La tendance linéaire estimée sur 1880-2023 correspond à environ 0,7-0,8°C de réchauffement par siècle.\n", "2. Les données synthétiques utilisées ici suivent une tendance linéaire par construction ; sur les données réelles, le réchauffement observé s'est nettement accéléré depuis les années 1970-1980 (la tendance récente est supérieure à la tendance sur tout le XXe siècle).\n", "3. La variabilité naturelle correspond aux fluctuations d'une année sur l'autre (cycles océaniques comme El Niño/La Niña, éruptions volcaniques, variabilité interne du système climatique) ; la tendance climatique est le signal de fond, robuste sur plusieurs décennies, attribuable au forçage radiatif anthropique.\n", "4. L'anomalie de température est un écart par rapport à une période de référence (moyenne climatologique), et non une température absolue journalière : elle filtre les effets saisonniers et géographiques pour isoler le signal de changement climatique global." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "name": "python", "version": "3.10" } }, "nbformat": 4, "nbformat_minor": 5 }