Plotly — Température dans les stations Châtelet et Franklin D. Roosevelt (deuxième version)

Voici une deuxième version de la visualisation avec Plotly des températures relevées dans les stations Châtelet et Franklin D. Roosevelt. Cette fois les données traitées sont en JSON et elle sont récupérées via l’API REST Opendatasoft Explore API.

Dans un billet de septembre 2022 j'avais montré comment visualiser les températures relevées en juillet-août 2022 dans les stations Châtelet (ligne 1) et Franklin D. Roosevelt (ligne 4) avec Pandas et Plotly. Les fichiers de données au format CSV étaient récupérées à la main sur le site Open Data RATP. Mais il est possible et plus simple d'obtenir les données aux formats CSV ou JSON via l’API REST Opendatasoft Explore API.

Voici par exemple la requête GET pour récupérer les données de qualité de l'air mesurée dans la station Châtelet entre le 1er juillet et le 31 août 2023 :

https://data.ratp.fr/api/explore/v2.1/catalog/datasets/qualite-de-lair-mesuree-dans-la-station-chatelet/exports/json?&limit=-1&timezone=UTC&use_labels=false&epsg=4326&where=dateheure>=date'2023-07-01'%20AND%20dateheure<=date'2023-08-31'

Code source

import json
import pandas as pd
import plotly.express as px
from urllib.request import urlopen


def url_to_df(url, station_name, col_temp):
    response = urlopen(url)
    data = json.loads(response.read())

    df = pd.DataFrame(data)
    df.insert(1, "station", station_name)
    df = df.rename(columns={col_temp: "temp", "dateheure": "dtime"})
    df["temp"] = df["temp"].str.replace("ND", "NaN")
    df["temp"] = df["temp"].str.replace(",", ".").astype(float)

    return df


url_chatelet = "https://data.ratp.fr/api/explore/v2.1/catalog/datasets/qualite-de-lair-mesuree-dans-la-station-chatelet/exports/json?&limit=-1&timezone=UTC&use_labels=false&epsg=4326&where=dateheure>=date'2023-07-01'%20AND%20dateheure<=date'2023-08-31'"
url_roosevelt = "https://data.ratp.fr/api/explore/v2.1/catalog/datasets/qualite-de-lair-mesuree-dans-la-station-franklin-d-roosevelt/exports/json?&limit=-1&timezone=UTC&use_labels=false&epsg=4326&where=dateheure>=date'2023-07-01'%20AND%20dateheure<=date'2023-08-31'"

# dataframe pour Châtelet
df_chatelet = url_to_df(url_chatelet, "Châtelet", "tcha4")

# dataframe pour Nation
df_roosevelt = url_to_df(url_roosevelt, "Franklin D. Roosevelt", "tfra1")

# concaténation des dataframes
df = pd.concat([df_chatelet, df_roosevelt])
del [df_chatelet, df_roosevelt]

# création du diagramme
url = "https://data.ratp.fr/"
title = f"<b>Température juillet-août 2023</b><br>Source:<a href='{url}'>{url}</a>"

fig = px.line(
    df,
    x="dtime",
    y="temp",
    color="station",
    markers=False,
    title=title,
    labels={
        "dtime": "<b>Date</b>",
        "temp": "<b>Température °C</b>",
        "station": "<b>Stations</b>",
    },
)

# centrage du titre, suppression du quadrillage et placement de la légende en haut à droite
fig.update_layout(
    title_x=0.5,
    plot_bgcolor="#fff",
    xaxis=dict(showgrid=False, linecolor="#000"),
    yaxis=dict(showgrid=False, linecolor="#000"),
    legend=dict(yanchor="top", y=0.99, xanchor="right", x=0.99, bgcolor="#efefef"),
)

# ajout d'annotations pour indiquer les températures min et max
min_value = df["temp"].min()
min_days = df[df["temp"] == min_value]["dtime"].values
max_value = df["temp"].max()
max_days = df[df["temp"] == max_value]["dtime"].values

for day in max_days:
    fig.add_annotation(x=day, y=max_value, text=f"<b>Max : {max_value} °C</b>")

for day in min_days:
    fig.add_annotation(x=day, y=min_value, text=f"<b>Min : {min_value} °C</b>")

# affichage et sauvegarde
fig.show()
fig.write_html("plotly-ratp2.html")

Diagramme généré