Épreuve pratique · 2026 · Sujet 16

Bac NSI pratique 2026 sujet 16 : Warming stripes, anomalies et régression linéaire

Les warming stripes représentent les écarts annuels de température par des bandes de même hauteur. Les données du fichier datas.csv couvrent 1851 à 2025 et utilisent la moyenne 1901-2000 comme référence : un écart 1,01 en 2020 signifie 1,01°C au-dessus de cette moyenne. On recherche une année, on corrige une moyenne puis on étudie une extrapolation linéaire. Les résultats ci-dessous sont ceux du fichier pédagogique fourni, sans les confondre avec une mise à jour extérieure de la série.

Dans ce sujet

Un corrigé pédagogique pour comprendre et justifier vos réponses. Les conseils de rédaction ne constituent pas un barème officiel détaillé.

Application

Warming stripes, anomalies et régression linéaire

Les warming stripes représentent les écarts annuels de température par des bandes de même hauteur. Les données du fichier datas.csv couvrent 1851 à 2025 et utilisent la moyenne 1901-2000 comme référence : un écart 1,01 en 2020 signifie 1,01°C au-dessus de cette moyenne. On recherche une année, on corrige une moyenne puis on étudie une extrapolation linéaire. Les résultats ci-dessous sont ceux du fichier pédagogique fourni, sans les confondre avec une mise à jour extérieure de la série.

1851 : -0.15°C1852 : -0.05°C1853 : -0.03°C1854 : -0.09°C1855 : -0.02°C1856 : -0.03°C1857 : -0.15°C1858 : -0.17°C1859 : -0.16°C1860 : -0.03°C1861 : -0.25°C1862 : -0.25°C1863 : -0.31°C1864 : -0.21°C1865 : -0.15°C1866 : -0.09°C1867 : -0.11°C1868 : -0.2°C1869 : -0.1°C1870 : -0.08°C1871 : -0.18°C1872 : -0.15°C1873 : -0.19°C1874 : -0.2°C1875 : -0.22°C1876 : -0.23°C1877 : -0.23°C1878 : 0.14°C1879 : 0.11°C1880 : -0.16°C1881 : -0.16°C1882 : -0.08°C1883 : -0.18°C1884 : -0.19°C1885 : -0.31°C1886 : -0.27°C1887 : -0.3°C1888 : -0.29°C1889 : -0.08°C1890 : -0.07°C1891 : -0.32°C1892 : -0.21°C1893 : -0.28°C1894 : -0.32°C1895 : -0.3°C1896 : -0.19°C1897 : -0.1°C1898 : -0.1°C1899 : -0.26°C1900 : -0.15°C1901 : -0.05°C1902 : -0.1°C1903 : -0.22°C1904 : -0.39°C1905 : -0.4°C1906 : -0.25°C1907 : -0.16°C1908 : -0.36°C1909 : -0.43°C1910 : -0.4°C1911 : -0.39°C1912 : -0.38°C1913 : -0.34°C1914 : -0.29°C1915 : -0.15°C1916 : -0.09°C1917 : -0.34°C1918 : -0.43°C1919 : -0.27°C1920 : -0.24°C1921 : -0.23°C1922 : -0.18°C1923 : -0.25°C1924 : -0.24°C1925 : -0.25°C1926 : -0.16°C1927 : -0.11°C1928 : -0.16°C1929 : -0.18°C1930 : -0.32°C1931 : -0.09°C1932 : -0.04°C1933 : -0.15°C1934 : -0.25°C1935 : -0.11°C1936 : -0.15°C1937 : -0.09°C1938 : 0°C1939 : 0°C1940 : 0.03°C1941 : 0.15°C1942 : 0.24°C1943 : 0.06°C1944 : 0.1°C1945 : 0.23°C1946 : 0.15°C1947 : -0.05°C1948 : 0°C1949 : -0.06°C1950 : -0.09°C1951 : -0.14°C1952 : 0.01°C1953 : 0.04°C1954 : 0.08°C1955 : -0.07°C1956 : -0.14°C1957 : -0.16°C1958 : 0.09°C1959 : 0.07°C1960 : 0.07°C1961 : 0.01°C1962 : 0.07°C1963 : 0.05°C1964 : 0.07°C1965 : -0.17°C1966 : -0.08°C1967 : -0.02°C1968 : 0°C1969 : -0.04°C1970 : 0.12°C1971 : 0.04°C1972 : -0.07°C1973 : 0.1°C1974 : 0.17°C1975 : -0.04°C1976 : 0.01°C1977 : -0.03°C1978 : 0.2°C1979 : 0.11°C1980 : 0.22°C1981 : 0.32°C1982 : 0.32°C1983 : 0.21°C1984 : 0.33°C1985 : 0.19°C1986 : 0.16°C1987 : 0.23°C1988 : 0.36°C1989 : 0.37°C1990 : 0.31°C1991 : 0.45°C1992 : 0.42°C1993 : 0.23°C1994 : 0.26°C1995 : 0.35°C1996 : 0.46°C1997 : 0.35°C1998 : 0.52°C1999 : 0.62°C2000 : 0.4°C2001 : 0.42°C2002 : 0.57°C2003 : 0.62°C2004 : 0.62°C2005 : 0.57°C2006 : 0.68°C2007 : 0.68°C2008 : 0.59°C2009 : 0.58°C2010 : 0.68°C2011 : 0.72°C2012 : 0.61°C2013 : 0.67°C2014 : 0.69°C2015 : 0.76°C2016 : 0.95°C2017 : 1.02°C2018 : 0.92°C2019 : 0.88°C2020 : 1.01°C2021 : 0.99°C2022 : 0.88°C2023 : 0.9°C2024 : 1.22°C2025 : 1.29°C18512025
Reconstruction à partir des 175 valeurs de datas.csv. Référence : moyenne 1901-2000. Bleu : écart négatif ; blanc : zéro ; rouge : écart positif. L’intensité représente la valeur absolue.

Le dossier comporte le sujet et les fichiers listés dans les téléchargements. Les codes de départ sont reproduits ci-dessous. Travaillez sur une copie. Les appels professeur signalés dans les questions servent à présenter votre démarche ; vous pouvez aussi demander de l’aide en cas de difficulté.

Code fourni : warming_stripes.py
import csv
import matplotlib.pyplot as plt

############ Question 1  ############


def charger(nom_fichier):
    """
    Lit un fichier CSV (contenant les colonnes 'Year' et 'Anomaly') 
    et renvoie une liste de dictionnaires correctement typés.
    """
    donnees = []
    with open(nom_fichier, mode='r', encoding='utf-8') as f:
        lecteur = csv.DictReader(f)
        for ligne in lecteur:
            annee = int(ligne["Year"])
            ecart = float(ligne["Anomaly"])
            donnees.append({"année": annee, "écart": ecart})
    return donnees


# Chargement global des données
datas_temperature = charger("datas.csv")

#############################################################################
# Question 1 : Recherche de l'écart                                         #
#############################################################################

# Écrire la fonction ecart_temperature et ses tests ici

#############################################################################
# Question 2 : Dernière année négative                                      #
#############################################################################


def derniere_annee_ecart_negatif(datas):
    annee = max([element["année"] for element in datas])
    ecart = ecart_temperature(datas, annee)
    while ecart >= 0:
        annee = annee - 1
        ecart = ecart_temperature(datas, annee)
    return annee


#############################################################################
# Question 3 : Analyse et correction de bug                                 #
#############################################################################

def moyenne_ecarts(annee_debut, annee_fin, datas):
    """
    Renvoie la moyenne des écarts de température pour la période comprise 
    entre annee_debut et annee_fin (incluses).
    """
    somme = 0
    compteur = 0
    for dico in datas:
        if annee_debut <= dico["année"] and dico["année"] <= annee_fin:
            somme = somme - dico["écart"]
            compteur += 1
    return somme / compteur


def prevision(datas, annee, n):
    """
    Renvoie l'écart de température attendu calculé par régression linéaire 
    sur les n dernières années.
    """
    longueur = len(datas)
    annee_debut = datas[longueur-n]["année"]
    annee_fin = datas[longueur-1]["année"]

    moy_annees = (annee_debut + annee_fin) / 2
    moy_temperatures = moyenne_ecarts(annee_debut, annee_fin, datas)

    numerateur = 0
    denominateur = 0
    for i in range(1, n+1):
        ecart_annee = datas[longueur-i]["année"] - moy_annees
        ecart_temp = datas[longueur-i]["écart"] - moy_temperatures
        numerateur += ecart_annee * ecart_temp
        denominateur += ecart_annee ** 2

    a = numerateur / denominateur
    b = moy_temperatures - a * moy_annees

    return a * annee + b

# print("Prévision pour 2040 :", prevision(datas_temperature, 2040, 20))


#############################################################################
# Question 4 : Dataviz (Warming Stripes)                                    #
#############################################################################

def graphique(datas):
    """
    Représente visuellement les warming stripes.
    """
    fig, ax = plt.subplots(figsize=(10, 2))

    # Création d'une palette de couleurs basée sur l'amplitude thermique
    cmap = plt.get_cmap("seismic")
    temperatures = [dico["écart"] for dico in datas]
    max_val = max(max(temperatures), -min(temperatures))
    norm = plt.Normalize(-max_val, max_val)

    # A COMPLETER
    # Création des listes annees et ordonnees 
    # pour les abscisses et ordonnées

    # Génération du graphique
    ax.bar(annees, ordonnees, width=1.0, color=cmap(norm(temperatures)))
    ax.set_title("Warming Stripes mondiales - Base 1901-2000")
    plt.yticks([], [])  # Masque l'axe Y car seule la couleur compte
    ax.set_xlabel("Année")

    plt.tight_layout()
    plt.show()

# graphique(datas_temperature)

Question 1

#

Écrire ecart_temperature(datas, annee) qui renvoie l’écart de l’année, ou None si elle est absente. Rédiger des assertions, y compris pour une année hors du jeu de données.

Indice

Ne conclure à l’absence qu’après le parcours complet.

Comprendre la correction
def ecart_temperature(datas, annee):
    for donnee in datas:
        if donnee['année'] == annee:
            return donnee['écart']
    return None
assert ecart_temperature(datas_temperature,2020) == 1.01
assert ecart_temperature(datas_temperature,2025) == 1.29
assert ecart_temperature(datas_temperature,1800) is None
assert ecart_temperature([],2020) is None

Le return None doit être placé après toute la boucle : une première année différente ne prouve pas que l’année recherchée est absente. Le code retourne directement le float chargé depuis le CSV. Un écart 0 est une valeur mesurée, différente de None.

Voir la question dans le sujet PDF, p. 3 (nouvel onglet)

Question 2

#

Utiliser derniere_annee_ecart_negatif pour trouver la dernière année où la température était inférieure à la référence.

Comprendre la correction
print(derniere_annee_ecart_negatif(datas_temperature))

Avec les données fournies, la réponse est 1977. La fonction part de 2025 et recule tant que l’écart est positif ou nul. L’année recherchée a donc un écart strictement négatif. La fonction suppose une série continue d’années et l’existence d’au moins une valeur négative : sans ces hypothèses, la recherche pourrait rencontrer None ou dépasser les données. Pour ce fichier, elles sont vérifiées.

Voir la question dans le sujet PDF, p. 3 (nouvel onglet)

Question 3

#

L’appel prevision(datas_temperature,2040,20) paraît absurde. Identifier l’erreur dans moyenne_ecarts, la corriger et donner la nouvelle prévision.

PythonReplacer le centre de la droite de régressionÉcrivez votre solution et mettez-la à l’épreuve

Corrigez moyenne_ecarts(annee_debut, annee_fin, datas). Additionnez les écarts des années comprises entre les deux bornes incluses, puis divisez par leur effectif. Les dictionnaires portent les clés année et écart. Une assertion doit refuser un intervalle sans donnée. Le calcul de la régression reste fourni dans le sujet ; ici nous isolons la moyenne qui le faussait.

def moyenne_ecarts(annee_debut, annee_fin, datas):
    # À vous de jouer
    pass

Les cas de test proposés :

  • Moyenne positive facile à vérifier : Le signe de l’accumulation doit conserver celui d’une série positive.
  • Deux bornes incluses : Les valeurs hors période ne participent ni à la somme ni au dénominateur.
  • Écarts négatifs et positifs : Une moyenne peut rester négative ; il ne faut pas prendre de valeur absolue.
  • Une année : Une seule observation conserve sa valeur.
  • Aucune année retenue : La précondition protège la division par zéro.
Indice

Comparer une somme manuelle sur deux valeurs au résultat de moyenne_ecarts.

Comprendre la correction

L’accumulateur soustrait chaque écart au lieu de l’ajouter. Il calcule l’opposé de la moyenne :−0,836 au lieu de 0,836 sur 2006-2025. La droite est alors décalée, même si une partie du calcul de pente semble fonctionner. Corriger le signe et vérifier la moyenne séparément avant de relancer la prévision.

def moyenne_ecarts(annee_debut, annee_fin, datas):
    somme = 0
    compteur = 0
    for dico in datas:
        if annee_debut <= dico['année'] <= annee_fin:
            somme += dico['écart']
            compteur += 1
    assert compteur > 0, 'Aucune année dans cet intervalle'
    return somme / compteur
assert moyenne_ecarts(1,2,[{'année':1,'écart':1.0},
                          {'année':2,'écart':3.0}]) == 2.0
print(prevision(datas_temperature,2040,20))

L’extrapolation corrigée vaut environ 1.56657894736842°C par rapport à la moyenne 1901-2000, soit 1,57°C. Le résultat est une extrapolation de la droite ajustée aux 20 dernières années du fichier, pas une prévision physique complète. La période et la référence doivent accompagner le chiffre. La fonction fournie suppose aussi des années successives et ordonnées ; son calcul du centre des années par les deux bornes utilise cette régularité.

Une sortie plausible ne suffit pas à valider une formule. Pour la moyenne, utilisez d’abord deux nombres dont le calcul mental est immédiat, puis la période réelle. Pour la régression, indiquez les années utilisées et vérifiez que la droite passe au centre du nuage : à l’année moyenne de l’intervalle, la valeur ajustée doit être la moyenne des écarts. Cette propriété relie directement moyenne_ecarts au résultat final et aide à comprendre pourquoi son signe erroné déplace toute la droite. Changer la fenêtre dans l’atelier montre ensuite une sensibilité du modèle, qui est distincte d’un bug de calcul.

Lire une anomalie de températureUn atelier pour expérimenter

Choisissez une réponse puis confrontez votre intuition à l’explication. Vous pouvez modifier vos choix.

Lire les réponses et leurs explications
  1. Un écart 1,01°C signifie…

    1,01°C au-dessus de la moyenne de référence.. La référence est la moyenne 1901-2000 du fichier.

  2. Quelle erreur fait somme=somme-ecart ?

    Elle calcule l’opposé de la somme.. À partir de 0, toutes les valeurs sont soustraites.

Appuyez votre explication sur les valeurs et les conditions exactes du programme.

Voir la question dans le sujet PDF, p. 3 (nouvel onglet)

Question 4

#

Dans graphique(datas), compléter les listes annees et ordonnees. Les bandes doivent toutes avoir la hauteur 1 ; les couleurs sont déjà calculées.

Comprendre la correction
annees = [dico['année'] for dico in datas]
ordonnees = [1 for _ in datas]

Ces deux listes doivent garder la même longueur et le même ordre que temperatures. L’information de température est codée par la couleur, pas par la hauteur. Utiliser les écarts comme ordonnées produirait un autre graphique et ferait disparaître les bandes d’écart nul. Après insertion à l’endroit indiqué, appeler graphique(datas_temperature).

Voir la question dans le sujet PDF, p. 3 (nouvel onglet)
Changer la fenêtre de la droite ajustéeUn atelier pour expérimenter

L’atelier utilise les données réelles du sujet. Faites varier le nombre d’années d’ajustement et l’année extrapolée. Observez la pente et le résultat, tout en gardant la même référence climatique.

Lire le résultat de l’expérience initiale

Extrapolation pour2040 : 1.567°C par rapport à la référence.

Une droite ajustée aux dernières observations prolonge une tendance. Ce modèle scolaire ne constitue pas une projection climatique complète.

Année observéeÉcart (°C)
20060.68
20070.68
20080.59
20090.58
20100.68
20110.72
20120.61
20130.67
20140.69
20150.76
20160.95
20171.02
20180.92
20190.88
20201.01
20210.99
20220.88
20230.9
20241.22
20251.29

Une extrapolation dépend de la fenêtre choisie et de ses hypothèses ; l’unité et la référence restent essentielles.

Revoir les notions de cet exercice

Du sujet à la méthode

Votre prochaine séance de révision

  • Vérifier les fonctions intermédiaires avant d’interpréter un résultat final.
  • Une visualisation doit faire correspondre explicitement valeurs et couleurs.

Retrouver ces notions dans d’autres sujets

Toutes les annales de NSI · Le guide pour préparer le bac NSI 2027

Énoncé : sujet 26_BCG_NSI_16 (PDF). Corrigé et explications pédagogiques proposés par Sofien.