Commit
·
30f401b
1
Parent(s):
d3040d3
chore: added geojson polygon function and custom colorscale per indicator
Browse files
climateqa/engine/talk_to_data/drias/config.py
CHANGED
@@ -1,4 +1,7 @@
|
|
1 |
|
|
|
|
|
|
|
2 |
DRIAS_TABLES = [
|
3 |
"total_winter_precipitation",
|
4 |
"total_summer_precipitation",
|
@@ -74,6 +77,24 @@ DRIAS_PLOT_PARAMETERS = [
|
|
74 |
'year',
|
75 |
'location'
|
76 |
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
DRIAS_UI_TEXT = """
|
78 |
Hi, I'm **Talk to Drias**, designed to answer your questions using [**DRIAS - TRACC 2023**](https://www.drias-climat.fr/accompagnement/sections/401) data.
|
79 |
I'll answer by displaying a list of SQL queries, graphs and data most relevant to your question.
|
|
|
1 |
|
2 |
+
from climateqa.engine.talk_to_data.ui_config import PRECIPITATION_COLORSCALE, TEMPERATURE_COLORSCALE
|
3 |
+
|
4 |
+
|
5 |
DRIAS_TABLES = [
|
6 |
"total_winter_precipitation",
|
7 |
"total_summer_precipitation",
|
|
|
77 |
'year',
|
78 |
'location'
|
79 |
]
|
80 |
+
|
81 |
+
DRIAS_INDICATOR_TO_COLORSCALE = {
|
82 |
+
"total_winter_precipitation": PRECIPITATION_COLORSCALE,
|
83 |
+
"total_summer_precipitation": PRECIPITATION_COLORSCALE,
|
84 |
+
"total_annual_precipitation": PRECIPITATION_COLORSCALE,
|
85 |
+
"total_remarkable_daily_precipitation": PRECIPITATION_COLORSCALE,
|
86 |
+
"frequency_of_remarkable_daily_precipitation": PRECIPITATION_COLORSCALE,
|
87 |
+
"extreme_precipitation_intensity": PRECIPITATION_COLORSCALE,
|
88 |
+
"mean_winter_temperature":TEMPERATURE_COLORSCALE,
|
89 |
+
"mean_summer_temperature":TEMPERATURE_COLORSCALE,
|
90 |
+
"mean_annual_temperature":TEMPERATURE_COLORSCALE,
|
91 |
+
"number_tropical_nights": TEMPERATURE_COLORSCALE,
|
92 |
+
"maximum_summer_temperature":TEMPERATURE_COLORSCALE,
|
93 |
+
"number_of_days_with_tx_above_30": TEMPERATURE_COLORSCALE,
|
94 |
+
"number_of_days_with_tx_above_35": TEMPERATURE_COLORSCALE,
|
95 |
+
"number_of_days_with_dry_ground": TEMPERATURE_COLORSCALE
|
96 |
+
}
|
97 |
+
|
98 |
DRIAS_UI_TEXT = """
|
99 |
Hi, I'm **Talk to Drias**, designed to answer your questions using [**DRIAS - TRACC 2023**](https://www.drias-climat.fr/accompagnement/sections/401) data.
|
100 |
I'll answer by displaying a list of SQL queries, graphs and data most relevant to your question.
|
climateqa/engine/talk_to_data/drias/plots.py
CHANGED
@@ -10,8 +10,29 @@ from climateqa.engine.talk_to_data.drias.queries import (
|
|
10 |
indicator_for_given_year_query,
|
11 |
indicator_per_year_at_location_query,
|
12 |
)
|
13 |
-
from climateqa.engine.talk_to_data.drias.config import DRIAS_INDICATOR_TO_UNIT
|
14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
|
16 |
def plot_indicator_evolution_at_location(params: dict) -> Callable[..., Figure]:
|
17 |
"""Generates a function to plot indicator evolution over time at a location.
|
@@ -359,50 +380,19 @@ def plot_map_of_france_of_indicator_for_given_year(
|
|
359 |
longitudes = df_model["longitude"].astype(float).tolist()
|
360 |
model_label = f"Model : {df['model'].unique()[0]}"
|
361 |
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
for idx, (lat, lon, val) in enumerate(zip(latitudes, longitudes, indicators)):
|
366 |
-
delta_lon = side_km / (111 * cos(radians(lat)))
|
367 |
-
half_lat = delta_lat / 2
|
368 |
-
half_lon = delta_lon / 2
|
369 |
-
features.append(geojson.Feature(
|
370 |
-
geometry=geojson.Polygon([[
|
371 |
-
[lon - half_lon, lat - half_lat],
|
372 |
-
[lon + half_lon, lat - half_lat],
|
373 |
-
[lon + half_lon, lat + half_lat],
|
374 |
-
[lon - half_lon, lat + half_lat],
|
375 |
-
[lon - half_lon, lat - half_lat]
|
376 |
-
]]),
|
377 |
-
properties={"value": val},
|
378 |
-
id=str(idx)
|
379 |
-
))
|
380 |
-
|
381 |
-
geojson_data = geojson.FeatureCollection(features)
|
382 |
-
|
383 |
-
custom_colorscale = [
|
384 |
-
[0.0, "rgb(5, 48, 97)"],
|
385 |
-
[0.10, "rgb(33, 102, 172)"],
|
386 |
-
[0.20, "rgb(67, 147, 195)"],
|
387 |
-
[0.30, "rgb(146, 197, 222)"],
|
388 |
-
[0.40, "rgb(209, 229, 240)"],
|
389 |
-
[0.50, "rgb(247, 247, 247)"],
|
390 |
-
[0.60, "rgb(253, 219, 199)"],
|
391 |
-
[0.75, "rgb(244, 165, 130)"],
|
392 |
-
[0.85, "rgb(214, 96, 77)"],
|
393 |
-
[0.90, "rgb(178, 24, 43)"],
|
394 |
-
[1.0, "rgb(103, 0, 31)"]
|
395 |
-
]
|
396 |
|
397 |
fig = go.Figure(go.Choroplethmapbox(
|
398 |
geojson=geojson_data,
|
399 |
locations=[str(i) for i in range(len(indicators))],
|
400 |
featureidkey="id",
|
401 |
z=indicators,
|
402 |
-
colorscale=
|
403 |
zmin=min(indicators),
|
404 |
zmax=max(indicators),
|
405 |
-
marker_opacity=0.
|
406 |
marker_line_width=0,
|
407 |
colorbar_title=f"{indicator_label} ({unit})",
|
408 |
text=[f"{indicator_label}: {value:.2f} {unit}" for value in indicators], # Add hover text showing the indicator value
|
|
|
10 |
indicator_for_given_year_query,
|
11 |
indicator_per_year_at_location_query,
|
12 |
)
|
13 |
+
from climateqa.engine.talk_to_data.drias.config import DRIAS_INDICATOR_TO_COLORSCALE, DRIAS_INDICATOR_TO_UNIT
|
14 |
+
|
15 |
+
def generate_geojson_polygons(latitudes: list[float], longitudes: list[float], indicators: list[float]) -> geojson.FeatureCollection:
|
16 |
+
side_km = 8
|
17 |
+
delta_lat = side_km / 111
|
18 |
+
features = []
|
19 |
+
for idx, (lat, lon, val) in enumerate(zip(latitudes, longitudes, indicators)):
|
20 |
+
delta_lon = side_km / (111 * cos(radians(lat)))
|
21 |
+
half_lat = delta_lat / 2
|
22 |
+
half_lon = delta_lon / 2
|
23 |
+
features.append(geojson.Feature(
|
24 |
+
geometry=geojson.Polygon([[
|
25 |
+
[lon - half_lon, lat - half_lat],
|
26 |
+
[lon + half_lon, lat - half_lat],
|
27 |
+
[lon + half_lon, lat + half_lat],
|
28 |
+
[lon - half_lon, lat + half_lat],
|
29 |
+
[lon - half_lon, lat - half_lat]
|
30 |
+
]]),
|
31 |
+
properties={"value": val},
|
32 |
+
id=str(idx)
|
33 |
+
))
|
34 |
+
|
35 |
+
return geojson.FeatureCollection(features)
|
36 |
|
37 |
def plot_indicator_evolution_at_location(params: dict) -> Callable[..., Figure]:
|
38 |
"""Generates a function to plot indicator evolution over time at a location.
|
|
|
380 |
longitudes = df_model["longitude"].astype(float).tolist()
|
381 |
model_label = f"Model : {df['model'].unique()[0]}"
|
382 |
|
383 |
+
|
384 |
+
|
385 |
+
geojson_data = generate_geojson_polygons(latitudes, longitudes, indicators)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
386 |
|
387 |
fig = go.Figure(go.Choroplethmapbox(
|
388 |
geojson=geojson_data,
|
389 |
locations=[str(i) for i in range(len(indicators))],
|
390 |
featureidkey="id",
|
391 |
z=indicators,
|
392 |
+
colorscale=DRIAS_INDICATOR_TO_COLORSCALE[indicator],
|
393 |
zmin=min(indicators),
|
394 |
zmax=max(indicators),
|
395 |
+
marker_opacity=0.6,
|
396 |
marker_line_width=0,
|
397 |
colorbar_title=f"{indicator_label} ({unit})",
|
398 |
text=[f"{indicator_label}: {value:.2f} {unit}" for value in indicators], # Add hover text showing the indicator value
|
climateqa/engine/talk_to_data/ipcc/config.py
CHANGED
@@ -1,3 +1,6 @@
|
|
|
|
|
|
|
|
1 |
IPCC_DATASET_URL = "hf://datasets/ekimetrics/ipcc-atlas"
|
2 |
IPCC_TABLES = [
|
3 |
"mean_temperature",
|
@@ -55,6 +58,11 @@ MACRO_COUNTRIES = ['JP',
|
|
55 |
'RU'
|
56 |
]
|
57 |
|
|
|
|
|
|
|
|
|
|
|
58 |
IPCC_UI_TEXT = """
|
59 |
Hi, I'm **Talk to IPCC**, designed to answer your questions using [**IPCC - ATLAS**](https://interactive-atlas.ipcc.ch/regional-information#eyJ0eXBlIjoiQVRMQVMiLCJjb21tb25zIjp7ImxhdCI6OTc3MiwibG5nIjo0MDA2OTIsInpvb20iOjQsInByb2oiOiJFUFNHOjU0MDMwIiwibW9kZSI6ImNvbXBsZXRlX2F0bGFzIn0sInByaW1hcnkiOnsic2NlbmFyaW8iOiJzc3A1ODUiLCJwZXJpb2QiOiIyIiwic2Vhc29uIjoieWVhciIsImRhdGFzZXQiOiJDTUlQNiIsInZhcmlhYmxlIjoidGFzIiwidmFsdWVUeXBlIjoiQU5PTUFMWSIsImhhdGNoaW5nIjoiU0lNUExFIiwicmVnaW9uU2V0IjoiYXI2IiwiYmFzZWxpbmUiOiJwcmVJbmR1c3RyaWFsIiwicmVnaW9uc1NlbGVjdGVkIjpbXX0sInBsb3QiOnsiYWN0aXZlVGFiIjoicGx1bWUiLCJtYXNrIjoibm9uZSIsInNjYXR0ZXJZTWFnIjpudWxsLCJzY2F0dGVyWVZhciI6bnVsbCwic2hvd2luZyI6ZmFsc2V9fQ==) data.
|
60 |
I'll answer by displaying a list of SQL queries, graphs and data most relevant to your question.
|
|
|
1 |
+
from climateqa.engine.talk_to_data.ui_config import PRECIPITATION_COLORSCALE, TEMPERATURE_COLORSCALE
|
2 |
+
|
3 |
+
|
4 |
IPCC_DATASET_URL = "hf://datasets/ekimetrics/ipcc-atlas"
|
5 |
IPCC_TABLES = [
|
6 |
"mean_temperature",
|
|
|
58 |
'RU'
|
59 |
]
|
60 |
|
61 |
+
IPCC_INDICATOR_TO_COLORSCALE = {
|
62 |
+
"mean_temperature": TEMPERATURE_COLORSCALE,
|
63 |
+
"total_precipitation": PRECIPITATION_COLORSCALE
|
64 |
+
}
|
65 |
+
|
66 |
IPCC_UI_TEXT = """
|
67 |
Hi, I'm **Talk to IPCC**, designed to answer your questions using [**IPCC - ATLAS**](https://interactive-atlas.ipcc.ch/regional-information#eyJ0eXBlIjoiQVRMQVMiLCJjb21tb25zIjp7ImxhdCI6OTc3MiwibG5nIjo0MDA2OTIsInpvb20iOjQsInByb2oiOiJFUFNHOjU0MDMwIiwibW9kZSI6ImNvbXBsZXRlX2F0bGFzIn0sInByaW1hcnkiOnsic2NlbmFyaW8iOiJzc3A1ODUiLCJwZXJpb2QiOiIyIiwic2Vhc29uIjoieWVhciIsImRhdGFzZXQiOiJDTUlQNiIsInZhcmlhYmxlIjoidGFzIiwidmFsdWVUeXBlIjoiQU5PTUFMWSIsImhhdGNoaW5nIjoiU0lNUExFIiwicmVnaW9uU2V0IjoiYXI2IiwiYmFzZWxpbmUiOiJwcmVJbmR1c3RyaWFsIiwicmVnaW9uc1NlbGVjdGVkIjpbXX0sInBsb3QiOnsiYWN0aXZlVGFiIjoicGx1bWUiLCJtYXNrIjoibm9uZSIsInNjYXR0ZXJZTWFnIjpudWxsLCJzY2F0dGVyWVZhciI6bnVsbCwic2hvd2luZyI6ZmFsc2V9fQ==) data.
|
68 |
I'll answer by displaying a list of SQL queries, graphs and data most relevant to your question.
|
climateqa/engine/talk_to_data/ipcc/plots.py
CHANGED
@@ -4,10 +4,29 @@ import plotly.graph_objects as go
|
|
4 |
import pandas as pd
|
5 |
import geojson
|
6 |
|
7 |
-
from climateqa.engine.talk_to_data.ipcc.config import IPCC_INDICATOR_TO_UNIT, IPCC_SCENARIO
|
8 |
from climateqa.engine.talk_to_data.ipcc.queries import indicator_for_given_year_query, indicator_per_year_at_location_query
|
9 |
from climateqa.engine.talk_to_data.objects.plot import Plot
|
10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
def plot_indicator_evolution_at_location_historical_and_projections(
|
12 |
params: dict,
|
13 |
) -> Callable[[pd.DataFrame], Figure]:
|
@@ -100,57 +119,31 @@ def plot_choropleth_map_of_country_indicator_for_specific_year(
|
|
100 |
showing the indicator's spatial distribution as a choropleth map for the specified year.
|
101 |
"""
|
102 |
indicator = params["indicator_column"]
|
103 |
-
year = params.get('year'
|
|
|
|
|
104 |
country_name = params['country_name']
|
105 |
location = params['location']
|
106 |
indicator_label = " ".join(word.capitalize() for word in indicator.split("_"))
|
107 |
unit = IPCC_INDICATOR_TO_UNIT.get(indicator, "")
|
108 |
|
109 |
def plot_data(df: pd.DataFrame) -> Figure:
|
110 |
-
custom_colorscale = [
|
111 |
-
[0.0, "rgb(5, 48, 97)"],
|
112 |
-
[0.10, "rgb(33, 102, 172)"],
|
113 |
-
[0.20, "rgb(67, 147, 195)"],
|
114 |
-
[0.30, "rgb(146, 197, 222)"],
|
115 |
-
[0.40, "rgb(209, 229, 240)"],
|
116 |
-
[0.50, "rgb(247, 247, 247)"],
|
117 |
-
[0.60, "rgb(253, 219, 199)"],
|
118 |
-
[0.75, "rgb(244, 165, 130)"],
|
119 |
-
[0.85, "rgb(214, 96, 77)"],
|
120 |
-
[0.90, "rgb(178, 24, 43)"],
|
121 |
-
[1.0, "rgb(103, 0, 31)"]
|
122 |
-
]
|
123 |
|
124 |
indicators = df[indicator].astype(float).tolist()
|
125 |
latitudes = df["latitude"].astype(float).tolist()
|
126 |
longitudes = df["longitude"].astype(float).tolist()
|
127 |
|
128 |
-
|
129 |
-
geojson.Feature(
|
130 |
-
geometry=geojson.Polygon([[
|
131 |
-
[lon - 0.5, lat - 0.5],
|
132 |
-
[lon + 0.5, lat - 0.5],
|
133 |
-
[lon + 0.5, lat + 0.5],
|
134 |
-
[lon - 0.5, lat + 0.5],
|
135 |
-
[lon - 0.5, lat - 0.5]
|
136 |
-
]]),
|
137 |
-
properties={"value": val},
|
138 |
-
id=str(idx)
|
139 |
-
)
|
140 |
-
for idx, (lat, lon, val) in enumerate(zip(latitudes, longitudes, indicators))
|
141 |
-
]
|
142 |
-
|
143 |
-
geojson_data = geojson.FeatureCollection(features)
|
144 |
|
145 |
fig = go.Figure(go.Choroplethmapbox(
|
146 |
geojson=geojson_data,
|
147 |
locations=[str(i) for i in range(len(indicators))],
|
148 |
featureidkey="id",
|
149 |
z=indicators,
|
150 |
-
colorscale=
|
151 |
zmin=min(indicators),
|
152 |
zmax=max(indicators),
|
153 |
-
marker_opacity=0.
|
154 |
marker_line_width=0,
|
155 |
colorbar_title=f"{indicator_label} ({unit})",
|
156 |
text=[f"{indicator_label}: {value:.2f} {unit}" for value in indicators], # Add hover text showing the indicator value
|
|
|
4 |
import pandas as pd
|
5 |
import geojson
|
6 |
|
7 |
+
from climateqa.engine.talk_to_data.ipcc.config import IPCC_INDICATOR_TO_COLORSCALE, IPCC_INDICATOR_TO_UNIT, IPCC_SCENARIO
|
8 |
from climateqa.engine.talk_to_data.ipcc.queries import indicator_for_given_year_query, indicator_per_year_at_location_query
|
9 |
from climateqa.engine.talk_to_data.objects.plot import Plot
|
10 |
|
11 |
+
def generate_geojson_polygons(latitudes: list[float], longitudes: list[float], indicators: list[float]) -> geojson.FeatureCollection:
|
12 |
+
features = [
|
13 |
+
geojson.Feature(
|
14 |
+
geometry=geojson.Polygon([[
|
15 |
+
[lon - 0.5, lat - 0.5],
|
16 |
+
[lon + 0.5, lat - 0.5],
|
17 |
+
[lon + 0.5, lat + 0.5],
|
18 |
+
[lon - 0.5, lat + 0.5],
|
19 |
+
[lon - 0.5, lat - 0.5]
|
20 |
+
]]),
|
21 |
+
properties={"value": val},
|
22 |
+
id=str(idx)
|
23 |
+
)
|
24 |
+
for idx, (lat, lon, val) in enumerate(zip(latitudes, longitudes, indicators))
|
25 |
+
]
|
26 |
+
|
27 |
+
geojson_data = geojson.FeatureCollection(features)
|
28 |
+
return geojson_data
|
29 |
+
|
30 |
def plot_indicator_evolution_at_location_historical_and_projections(
|
31 |
params: dict,
|
32 |
) -> Callable[[pd.DataFrame], Figure]:
|
|
|
119 |
showing the indicator's spatial distribution as a choropleth map for the specified year.
|
120 |
"""
|
121 |
indicator = params["indicator_column"]
|
122 |
+
year = params.get('year')
|
123 |
+
if year is None:
|
124 |
+
year = 2050
|
125 |
country_name = params['country_name']
|
126 |
location = params['location']
|
127 |
indicator_label = " ".join(word.capitalize() for word in indicator.split("_"))
|
128 |
unit = IPCC_INDICATOR_TO_UNIT.get(indicator, "")
|
129 |
|
130 |
def plot_data(df: pd.DataFrame) -> Figure:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
|
132 |
indicators = df[indicator].astype(float).tolist()
|
133 |
latitudes = df["latitude"].astype(float).tolist()
|
134 |
longitudes = df["longitude"].astype(float).tolist()
|
135 |
|
136 |
+
geojson_data = generate_geojson_polygons(latitudes, longitudes, indicators)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
137 |
|
138 |
fig = go.Figure(go.Choroplethmapbox(
|
139 |
geojson=geojson_data,
|
140 |
locations=[str(i) for i in range(len(indicators))],
|
141 |
featureidkey="id",
|
142 |
z=indicators,
|
143 |
+
colorscale=IPCC_INDICATOR_TO_COLORSCALE[indicator],
|
144 |
zmin=min(indicators),
|
145 |
zmax=max(indicators),
|
146 |
+
marker_opacity=0.6,
|
147 |
marker_line_width=0,
|
148 |
colorbar_title=f"{indicator_label} ({unit})",
|
149 |
text=[f"{indicator_label}: {value:.2f} {unit}" for value in indicators], # Add hover text showing the indicator value
|
climateqa/engine/talk_to_data/ui_config.py
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
TEMPERATURE_COLORSCALE = [
|
2 |
+
[0.0, "rgb(5, 48, 97)"],
|
3 |
+
[0.10, "rgb(33, 102, 172)"],
|
4 |
+
[0.20, "rgb(67, 147, 195)"],
|
5 |
+
[0.30, "rgb(146, 197, 222)"],
|
6 |
+
[0.40, "rgb(209, 229, 240)"],
|
7 |
+
[0.50, "rgb(247, 247, 247)"],
|
8 |
+
[0.60, "rgb(253, 219, 199)"],
|
9 |
+
[0.75, "rgb(244, 165, 130)"],
|
10 |
+
[0.85, "rgb(214, 96, 77)"],
|
11 |
+
[0.90, "rgb(178, 24, 43)"],
|
12 |
+
[1.0, "rgb(103, 0, 31)"]
|
13 |
+
]
|
14 |
+
|
15 |
+
PRECIPITATION_COLORSCALE = [
|
16 |
+
[0.0, "rgb(84, 48, 5)"],
|
17 |
+
[0.10, "rgb(140, 81, 10)"],
|
18 |
+
[0.20, "rgb(191, 129, 45)"],
|
19 |
+
[0.30, "rgb(223, 194, 125)"],
|
20 |
+
[0.40, "rgb(246, 232, 195)"],
|
21 |
+
[0.50, "rgb(245, 245, 245)"],
|
22 |
+
[0.60, "rgb(199, 234, 229)"],
|
23 |
+
[0.75, "rgb(128, 205, 193)"],
|
24 |
+
[0.85, "rgb(53, 151, 143)"],
|
25 |
+
[0.90, "rgb(1, 102, 94)"],
|
26 |
+
[1.0, "rgb(0, 60, 48)"]
|
27 |
+
]
|