Spaces:
Runtime error
Runtime error
| import solara | |
| import pandas as pd | |
| import numpy as np | |
| import xarray as xr | |
| import geopandas as gpd | |
| import asyncio | |
| import plotly.express as px | |
| from scipy.stats import linregress | |
| from constants import ( | |
| DEFAULT_DATASET, | |
| DEFAULT_VARIABLE, | |
| DEFAULT_TYPE, | |
| DEFAULT_TIMESCALE, | |
| DEFAULT_MAP_STYLE, | |
| DEFAULT_OPACITY, | |
| DEFAULT_PLOTTED_LINE_COLOR, | |
| DEFAULT_TREND_LINE_COLOR, | |
| DEFAULT_SPATIAL_MEAN_COLOR, | |
| COLOR_SCALES, | |
| MAP_STYLES, | |
| PLOTLY_COLORS, | |
| SHAPEFILE_PATH, | |
| REGION_COLUMN, | |
| ) | |
| from Datasets import DATASETS | |
| from utils import ( | |
| get_plotly_theme, | |
| load_dataset, | |
| create_heatmap, | |
| create_timeseries_plot, | |
| get_region_bounds, | |
| filter_region_data, | |
| calculate_spatial_mean, | |
| calculate_selected_spatial_mean, | |
| create_selected_timeseries_plot, | |
| get_available_years, | |
| ) | |
| tab_index = solara.reactive(0) | |
| right_tab_index = solara.reactive(0) | |
| def Layout(children=[]): | |
| return solara.AppLayout(children=children, sidebar_open=False) | |
| def PlottingControls(show_spatial_mean, set_show_spatial_mean, show_trend_line, set_show_trend_line, show_point_data=None, set_show_point_data=None): | |
| with solara.Row(): | |
| solara.Checkbox( | |
| label="Show Spatial Mean", | |
| value=show_spatial_mean, | |
| on_value=set_show_spatial_mean | |
| ) | |
| solara.Checkbox( | |
| label="Show Trend Line", | |
| value=show_trend_line, | |
| on_value=set_show_trend_line | |
| ) | |
| if show_point_data is not None and set_show_point_data is not None: | |
| solara.Checkbox( | |
| label="Show Point Data", | |
| value=show_point_data, | |
| on_value=set_show_point_data | |
| ) | |
| def Page(): | |
| dataset_id, set_dataset_id = solara.use_state(DEFAULT_DATASET) | |
| selected_variable, set_selected_variable = solara.use_state(DEFAULT_VARIABLE) | |
| selected_type, set_selected_type = solara.use_state(DEFAULT_TYPE) | |
| selected_timescale, set_selected_timescale = solara.use_state(DEFAULT_TIMESCALE) | |
| selected_scenario, set_selected_scenario = solara.use_state(None) # Reactive state for scenario | |
| data, set_data = solara.use_state(None) | |
| heatmap, set_heatmap = solara.use_state(None) | |
| timeseries, set_timeseries = solara.use_state(None) | |
| selected_timeseries, set_selected_timeseries = solara.use_state(None) | |
| region_timeseries, set_region_timeseries = solara.use_state(None) | |
| value_column, set_value_column = solara.use_state(None) | |
| color_scale, set_color_scale = solara.use_state(None) | |
| map_style, set_map_style = solara.use_state(DEFAULT_MAP_STYLE) | |
| opacity, set_opacity = solara.use_state(DEFAULT_OPACITY) | |
| variables, set_variables = solara.use_state([]) | |
| latitude, set_latitude = solara.use_state(0.0) | |
| longitude, set_longitude = solara.use_state(0.0) | |
| use_regions, set_use_regions = solara.use_state(False) | |
| region, set_region = solara.use_state("India") | |
| regions, set_regions = solara.use_state(["India"]) | |
| geodataframe, set_geodataframe = solara.use_state(None) | |
| region_bounds, set_region_bounds = solara.use_state(None) | |
| show_spatial_mean, set_show_spatial_mean = solara.use_state(True) | |
| show_region_spatial_mean, set_show_region_spatial_mean = solara.use_state(True) | |
| show_region_trend_line, set_show_region_trend_line = solara.use_state(True) | |
| show_selected_trend_line, set_show_selected_trend_line = solara.use_state(True) | |
| spatial_mean_data, set_spatial_mean_data = solara.use_state({"overall_mean": None, "timeseries": pd.DataFrame()}) | |
| selected_spatial_mean_data, set_selected_spatial_mean_data = solara.use_state({"overall_mean": None, "timeseries": pd.DataFrame()}) | |
| available_years, set_available_years = solara.use_state([]) | |
| from_year, set_from_year = solara.use_state(None) | |
| to_year, set_to_year = solara.use_state(None) | |
| use_timeframe, set_use_timeframe = solara.use_state(False) | |
| selected_coords, set_selected_coords = solara.use_state([]) | |
| show_stats_for_nerds, set_show_stats_for_nerds = solara.use_state(False) | |
| loading_data, set_loading_data = solara.use_state(False) | |
| loading_spatial_mean, set_loading_spatial_mean = solara.use_state(False) | |
| show_trend_line, set_show_trend_line = solara.use_state(True) | |
| plotted_line_color, set_plotted_line_color = solara.use_state(DEFAULT_PLOTTED_LINE_COLOR) | |
| trend_line_color, set_trend_line_color = solara.use_state(DEFAULT_TREND_LINE_COLOR) | |
| spatial_mean_color, set_spatial_mean_color = solara.use_state(DEFAULT_SPATIAL_MEAN_COLOR) | |
| def get_available_types(): | |
| return sorted(set(d["type"] for d in DATASETS if d["variable"] == selected_variable)) | |
| def get_available_timescales(): | |
| return sorted(set(d["timescale"] for d in DATASETS if d["variable"] == selected_variable and d["type"] == selected_type)) | |
| def get_available_scenarios(): | |
| scenarios = sorted(set(d["scenario"] for d in DATASETS if d["variable"] == selected_variable and d["type"] == selected_type and d["timescale"] == selected_timescale and "scenario" in d)) | |
| return scenarios if scenarios else [] | |
| def update_dataset_id(): | |
| matching_datasets = [ | |
| d["id"] for d in DATASETS | |
| if d["variable"] == selected_variable | |
| and d["type"] == selected_type | |
| and d["timescale"] == selected_timescale | |
| and (d.get("scenario") == selected_scenario if selected_type == "Projected" else True) | |
| ] | |
| if matching_datasets: | |
| set_dataset_id(matching_datasets[0]) | |
| else: | |
| set_dataset_id(None) | |
| set_loading_data(False) | |
| solara.Info("No dataset available for the selected combination.") | |
| def reset_scenario(): | |
| available_scenarios = get_available_scenarios() | |
| if selected_type != "Projected": | |
| set_selected_scenario(None) | |
| elif available_scenarios: | |
| set_selected_scenario(available_scenarios[0]) | |
| else: | |
| set_selected_scenario(None) | |
| solara.use_effect(update_dataset_id, dependencies=[selected_variable, selected_type, selected_timescale, selected_scenario]) | |
| solara.use_effect(reset_scenario, dependencies=[selected_type, selected_variable, selected_timescale]) | |
| def load_shapefile(): | |
| try: | |
| gdf = gpd.read_file(SHAPEFILE_PATH) | |
| set_regions(["India"] + sorted(gdf[REGION_COLUMN].unique().tolist())) | |
| set_geodataframe(gdf) | |
| except Exception as e: | |
| print(f"Error loading shapefile: {e}") | |
| solara.use_effect(load_shapefile, dependencies=[]) | |
| def update_region_bounds(): | |
| if geodataframe is not None and region != "India" and use_regions: | |
| try: | |
| set_region_bounds(get_region_bounds(geodataframe, region)) | |
| set_loading_spatial_mean(True) | |
| set_spatial_mean_data({"overall_mean": None, "timeseries": pd.DataFrame()}) | |
| except Exception as e: | |
| print(f"Error getting region bounds: {e}") | |
| set_region_bounds(None) | |
| set_spatial_mean_data({"overall_mean": None, "timeseries": pd.DataFrame()}) | |
| set_loading_spatial_mean(False) | |
| else: | |
| set_region_bounds(None) | |
| set_spatial_mean_data({"overall_mean": None, "timeseries": pd.DataFrame()}) | |
| set_loading_spatial_mean(False) | |
| solara.use_effect(update_region_bounds, dependencies=[region, use_regions, geodataframe]) | |
| def load_available_years(): | |
| if dataset_id: | |
| dataset = next(d for d in DATASETS if d["id"] == dataset_id) | |
| years = get_available_years(dataset) | |
| set_available_years(years) | |
| if years: | |
| set_from_year(years[0]) | |
| set_to_year(years[-1]) | |
| else: | |
| set_from_year(None) | |
| set_to_year(None) | |
| solara.use_effect(load_available_years, dependencies=[dataset_id]) | |
| async def async_compute_spatial_mean(): | |
| if not show_region_spatial_mean: | |
| set_spatial_mean_data({"overall_mean": None, "timeseries": pd.DataFrame()}) | |
| set_loading_spatial_mean(False) | |
| return | |
| await asyncio.sleep(0.1) | |
| if dataset_id: | |
| dataset = next(d for d in DATASETS if d["id"] == dataset_id) | |
| mean_data = calculate_spatial_mean(dataset, geodataframe, region, from_year, to_year, use_timeframe) | |
| set_spatial_mean_data(mean_data) | |
| set_loading_spatial_mean(False) | |
| def compute_spatial_mean(): | |
| asyncio.create_task(async_compute_spatial_mean()) | |
| solara.use_effect(compute_spatial_mean, | |
| dependencies=[dataset_id, region, use_regions, geodataframe, | |
| show_region_spatial_mean, from_year, to_year, use_timeframe]) | |
| def compute_region_timeseries(): | |
| if not show_region_spatial_mean or not dataset_id: | |
| set_region_timeseries(None) | |
| return | |
| dataset = next(d for d in DATASETS if d["id"] == dataset_id) | |
| if spatial_mean_data["timeseries"].empty: | |
| set_region_timeseries(None) | |
| return | |
| try: | |
| dataset_nc = xr.open_dataset(dataset["timeseries_path"], decode_timedelta=False) | |
| variable = list(dataset_nc.data_vars)[0] | |
| dataset_nc.close() | |
| except Exception as e: | |
| print(f"Error accessing dataset variable: {e}") | |
| set_region_timeseries(None) | |
| return | |
| if variable not in spatial_mean_data["timeseries"].columns: | |
| print(f"Variable {variable} not found in spatial mean data. Recomputing spatial mean.") | |
| set_region_timeseries(None) | |
| return | |
| fig = px.line( | |
| spatial_mean_data["timeseries"], | |
| x="year", | |
| y=variable, | |
| title=f"Spatial Mean {dataset['name']} for {region}, {from_year}-{to_year}" if use_timeframe else f"Spatial Mean {dataset['name']} for {region}", | |
| labels={"year": "Year", variable: dataset["name"]}, | |
| color_discrete_sequence=[plotted_line_color] | |
| ) | |
| fig.data[0].name = f"{region} Spatial Mean" | |
| if show_region_trend_line and len(spatial_mean_data["timeseries"]) > 2: | |
| x_series = spatial_mean_data["timeseries"]["year"] | |
| y_series = spatial_mean_data["timeseries"][variable] | |
| valid_indices = y_series.notna() | |
| x_valid = x_series[valid_indices].values | |
| y_valid = y_series[valid_indices].values | |
| if len(x_valid) > 2: | |
| y_numeric = y_valid | |
| if pd.api.types.is_timedelta64_dtype(y_numeric.dtype): | |
| y_numeric = y_numeric / np.timedelta64(1, 'D') | |
| x_norm = x_valid - x_valid.mean() | |
| coeffs = np.polyfit(x_norm, y_numeric, deg=2) | |
| poly = np.poly1d(coeffs) | |
| trend_line = poly(x_norm) | |
| midpoint_idx = len(x_valid) // 2 | |
| slope = 2 * coeffs[0] * x_norm[midpoint_idx] + coeffs[1] | |
| _, _, r_value, p_value, _ = linregress(x_valid, y_numeric) | |
| trend = "Increasing" if p_value < 0.05 and slope > 0 else "Decreasing" if p_value < 0.05 and slope < 0 else "No Significant Trend" | |
| fig.add_scatter( | |
| x=x_valid, | |
| y=trend_line, | |
| mode="lines", | |
| name=f"{region} Trend", | |
| line=dict(color=trend_line_color, dash="dash") | |
| ) | |
| fig.add_annotation( | |
| x=x_valid.max(), | |
| y=y_valid.min(), | |
| text=f"Slope: {slope:.4f}<br>p-value: {p_value:.4f}<br>Trend: {trend}", | |
| showarrow=False, | |
| xanchor="right", | |
| yanchor="top", | |
| bgcolor="white" if not solara.lab.theme.dark_effective else "#333333", | |
| bordercolor="black", | |
| borderpad=4, | |
| opacity=0.8, | |
| font=dict(size=12, color="black" if not solara.lab.theme.dark_effective else "white") | |
| ) | |
| fig.update_layout( | |
| xaxis_title="Year", | |
| yaxis_title=dataset["name"], | |
| height=550, | |
| width=650, | |
| showlegend=True, | |
| legend=dict( | |
| x=0.99, | |
| y=0.99, | |
| xanchor="right", | |
| yanchor="top", | |
| bgcolor="rgba(0, 0, 0, 0)" | |
| ), | |
| template=get_plotly_theme() | |
| ) | |
| set_region_timeseries(fig) | |
| solara.use_effect(compute_region_timeseries, | |
| dependencies=[dataset_id, region, use_regions, spatial_mean_data, | |
| show_region_trend_line, plotted_line_color, trend_line_color, | |
| from_year, to_year, use_timeframe, selected_variable]) | |
| def compute_selected_spatial_mean(): | |
| if not selected_coords: | |
| set_selected_spatial_mean_data({"overall_mean": None, "timeseries": pd.DataFrame()}) | |
| set_selected_timeseries(None) | |
| return | |
| if dataset_id: | |
| dataset = next(d for d in DATASETS if d["id"] == dataset_id) | |
| mean_data = calculate_selected_spatial_mean(dataset, selected_coords, from_year, to_year, use_timeframe) | |
| set_selected_spatial_mean_data(mean_data) | |
| set_selected_timeseries(create_selected_timeseries_plot( | |
| dataset["timeseries_path"], | |
| dataset["name"], | |
| selected_coords, | |
| plotted_line_color, | |
| mean_data, | |
| from_year, | |
| to_year, | |
| use_timeframe, | |
| show_selected_trend_line, | |
| trend_line_color, | |
| spatial_mean_color | |
| )) | |
| solara.use_effect(compute_selected_spatial_mean, | |
| dependencies=[dataset_id, selected_coords, from_year, to_year, use_timeframe, | |
| plotted_line_color, show_selected_trend_line, trend_line_color, spatial_mean_color]) | |
| def handle_map_click(click_data): | |
| if click_data and "points" in click_data and "point_indexes" in click_data["points"]: | |
| idx = click_data["points"]["point_indexes"][0] | |
| row = data.iloc[idx] | |
| set_latitude(float(row["lat"])) | |
| set_longitude(float(row["lon"])) | |
| def handle_map_selection(selection_data): | |
| if selection_data and "points" in selection_data and "point_indexes" in selection_data["points"]: | |
| selected_indices = selection_data["points"]["point_indexes"] | |
| coords = [(float(data.iloc[idx]["lat"]), float(data.iloc[idx]["lon"])) for idx in selected_indices] | |
| set_selected_coords(coords) | |
| else: | |
| set_selected_coords([]) | |
| def generate_timeseries(): | |
| if dataset_id and latitude and longitude: | |
| dataset = next(d for d in DATASETS if d["id"] == dataset_id) | |
| set_timeseries(create_timeseries_plot( | |
| dataset["timeseries_path"], | |
| dataset["name"], | |
| latitude, | |
| longitude, | |
| plotted_line_color, | |
| spatial_mean_data=spatial_mean_data, | |
| show_spatial_mean=show_spatial_mean, | |
| from_year=from_year, | |
| to_year=to_year, | |
| use_timeframe=use_timeframe, | |
| region=region, | |
| show_trend_line=show_trend_line, | |
| trend_line_color=trend_line_color, | |
| spatial_mean_color=spatial_mean_color | |
| )) | |
| solara.use_effect(generate_timeseries, [ | |
| dataset_id, latitude, longitude, plotted_line_color, spatial_mean_data, | |
| show_spatial_mean, from_year, to_year, use_timeframe, region, | |
| show_trend_line, trend_line_color, spatial_mean_color | |
| ]) | |
| async def async_load_and_visualize(): | |
| set_loading_data(True) | |
| if dataset_id: | |
| dataset = next(d for d in DATASETS if d["id"] == dataset_id) | |
| print(f"Loading dataset: {dataset['id']} - {dataset['name']}") | |
| loaded_data, float_vars, grid_size = load_dataset(dataset) | |
| set_variables([var for var in float_vars if var not in ["lat", "lon", "latitude", "longitude"]]) | |
| new_value_column = float_vars[0] if float_vars else None | |
| set_value_column(new_value_column) | |
| if use_regions and geodataframe is not None: | |
| loaded_data = filter_region_data(loaded_data, geodataframe, region) | |
| if not new_value_column: | |
| set_loading_data(False) | |
| return | |
| filtered_data = loaded_data[loaded_data[new_value_column].notnull()][["lat", "lon", new_value_column]] | |
| set_heatmap(create_heatmap(filtered_data, dataset["name"], new_value_column, | |
| grid_size, color_scale, map_style, opacity)) | |
| set_data(filtered_data) | |
| set_selected_coords([]) | |
| set_loading_data(False) | |
| def load_and_visualize(): | |
| asyncio.create_task(async_load_and_visualize()) | |
| solara.use_effect(load_and_visualize, | |
| dependencies=[dataset_id, color_scale, map_style, | |
| opacity, region, use_regions]) | |
| def update_color_scale(): | |
| if dataset_id: | |
| dataset = next(d for d in DATASETS if d["id"] == dataset_id) | |
| set_color_scale(dataset["color_scale"]) | |
| solara.use_effect(update_color_scale, dependencies=[dataset_id]) | |
| def sync_map_style_with_theme(): | |
| if map_style not in ["carto-darkmatter", "carto-positron"]: | |
| return | |
| new_map_style = "carto-darkmatter" if solara.lab.theme.dark_effective else "carto-positron" | |
| set_map_style(new_map_style) | |
| solara.use_effect(sync_map_style_with_theme, dependencies=[solara.lab.theme.dark_effective]) | |
| with solara.AppLayout(sidebar_open=True): | |
| with solara.AppBar(): | |
| solara.Image("data/logo/TERI Logo Seal.png", width="80px", classes=["mx-2"]) | |
| solara.AppBarTitle("TERI Climate Tools - Climate Data Explorer") | |
| solara.lab.ThemeToggle() | |
| with solara.Sidebar(): | |
| with solara.Card("Controls", margin=0, elevation=0): | |
| with solara.Column(): | |
| solara.Details( | |
| summary="Dataset Settings", | |
| children=[ | |
| solara.Select( | |
| label="Variable", | |
| value=selected_variable, | |
| values=["Tmin", "Tmax", "Precipitation", "Climate Extremes"], | |
| dense=True, | |
| on_value=lambda value: [set_selected_variable(value), set_loading_data(True)] | |
| ), | |
| solara.Select( | |
| label="Dataset Type", | |
| value=selected_type, | |
| values=get_available_types(), | |
| dense=True, | |
| on_value=lambda value: [set_selected_type(value), set_loading_data(True)], | |
| disabled=not selected_variable | |
| ), | |
| solara.Select( | |
| label="Time Scale", | |
| value=selected_timescale, | |
| values=get_available_timescales(), | |
| dense=True, | |
| on_value=lambda value: [set_selected_timescale(value), set_loading_data(True)], | |
| disabled=not selected_variable or not selected_type | |
| ), | |
| solara.Select( | |
| label="Scenario", | |
| value=selected_scenario, | |
| values=get_available_scenarios(), | |
| dense=True, | |
| on_value=lambda value: [set_selected_scenario(value), set_loading_data(True)], | |
| disabled=not get_available_scenarios() | |
| ) if selected_type == "Projected" else solara.Markdown("**No scenarios available**" if selected_type == "Projected" else ""), | |
| solara.Select( | |
| label="Value", | |
| value=value_column, | |
| values=variables, | |
| on_value=set_value_column, | |
| disabled=not variables | |
| ) | |
| ], | |
| expand=False | |
| ) | |
| solara.Details( | |
| summary="Visualization Settings", | |
| children=[ | |
| solara.Select( | |
| label="Color Scale", | |
| value=color_scale, | |
| values=COLOR_SCALES, | |
| on_value=lambda value: [set_color_scale(value), set_loading_data(True)] | |
| ), | |
| solara.Select( | |
| label="Map Style", | |
| value=map_style, | |
| values=MAP_STYLES, | |
| on_value=lambda value: [set_map_style(value), set_loading_data(True)] | |
| ), | |
| solara.SliderFloat( | |
| label="Opacity", | |
| value=opacity, | |
| min=0.1, max=1.0, step=0.1, | |
| on_value=lambda value: [set_opacity(value), set_loading_data(True)] | |
| ), | |
| solara.Details( | |
| summary="Line Plot Settings", | |
| children=[ | |
| solara.Select( | |
| label="Plotted Line Color", | |
| value=plotted_line_color, | |
| values=PLOTLY_COLORS, | |
| on_value=set_plotted_line_color | |
| ), | |
| solara.Select( | |
| label="Trend Line Color", | |
| value=trend_line_color, | |
| values=PLOTLY_COLORS, | |
| on_value=set_trend_line_color | |
| ), | |
| solara.Select( | |
| label="Spatial Mean Color", | |
| value=spatial_mean_color, | |
| values=PLOTLY_COLORS, | |
| on_value=set_spatial_mean_color | |
| ) | |
| ], | |
| expand=False | |
| ) | |
| ], | |
| expand=False | |
| ) | |
| solara.Details( | |
| summary="Time Series Settings", | |
| children=[ | |
| solara.Checkbox( | |
| label="Use Specific Time Frame", | |
| value=use_timeframe, | |
| on_value=set_use_timeframe | |
| ), | |
| solara.Select( | |
| label="From Year", | |
| value=from_year, | |
| values=available_years, | |
| on_value=set_from_year, | |
| disabled=not available_years or not use_timeframe | |
| ), | |
| solara.Select( | |
| label="To Year", | |
| value=to_year, | |
| values=[y for y in available_years if y >= (from_year or available_years[0])], | |
| on_value=set_to_year, | |
| disabled=not available_years or not use_timeframe | |
| ) | |
| ], | |
| expand=False | |
| ) | |
| with solara.VBox(classes=["h-full", "w-full"]): | |
| if loading_data: | |
| solara.SpinnerSolara(size="100px") | |
| elif heatmap: | |
| with solara.Columns(widths=[2, 1], gutters=True, gutters_dense=True): | |
| with solara.Column(): | |
| solara.FigurePlotly(heatmap, on_click=handle_map_click, on_selection=handle_map_selection) | |
| with solara.Column(): | |
| with solara.lab.Tabs(value=right_tab_index): | |
| with solara.lab.Tab("Point Based Analysis"): | |
| solara.Details( | |
| summary="Coordinates", | |
| children=[ | |
| solara.InputFloat(label="Latitude", value=latitude, on_value=set_latitude), | |
| solara.InputFloat(label="Longitude", value=longitude, on_value=set_longitude), | |
| solara.Button(label="Generate Plot", color="primary", | |
| text=True, on_click=generate_timeseries) | |
| ], | |
| expand=False | |
| ) | |
| if timeseries: | |
| solara.FigurePlotly(timeseries) | |
| if dataset_id: | |
| dataset = next(d for d in DATASETS if d["id"] == dataset_id) | |
| variable = list(xr.open_dataset(dataset["timeseries_path"], decode_timedelta=False).data_vars)[0] | |
| dataset_xr = xr.open_dataset(dataset["timeseries_path"], decode_timedelta=False) | |
| lat_idx = np.abs((dataset_xr.get("lat", dataset_xr.get("latitude")).values - latitude)).argmin() | |
| lon_idx = np.abs((dataset_xr.get("lon", dataset_xr.get("longitude")).values - longitude)).argmin() | |
| timeseries_data = dataset_xr[variable].isel(lat=lat_idx, lon=lon_idx).to_dataframe().reset_index() | |
| dataset_xr.close() | |
| if use_timeframe and from_year is not None and to_year is not None: | |
| timeseries_data = timeseries_data[(timeseries_data["year"] >= from_year) & (timeseries_data["year"] <= to_year)] | |
| timeseries_data = timeseries_data[["year", variable]].rename(columns={variable: dataset["name"]}) | |
| show_timeseries_data, set_show_timeseries_data = solara.use_state(False) | |
| PlottingControls(show_spatial_mean, set_show_spatial_mean, show_trend_line, set_show_trend_line, show_timeseries_data, set_show_timeseries_data) | |
| if show_timeseries_data: | |
| solara.Markdown("### Point Data") | |
| display_df = timeseries_data.copy() | |
| if pd.api.types.is_numeric_dtype(display_df[dataset["name"]]): | |
| display_df[dataset["name"]] = display_df[dataset["name"]].map('{:.2f}'.format) | |
| solara.DataFrame(display_df, items_per_page=10) | |
| csv_data = timeseries_data.to_csv(index=False) | |
| solara.FileDownload( | |
| data=csv_data, | |
| filename=f"timeseries_lat_{latitude:.2f}_lon_{longitude:.2f}.csv", | |
| label="Download Point Data as CSV" | |
| ) | |
| else: | |
| solara.Info(label="Click a map point to generate a plot.") | |
| with solara.lab.Tab("Region Based Analysis"): | |
| solara.Details( | |
| summary="State Based Analysis", | |
| children=[ | |
| child for child in [ | |
| solara.Select( | |
| label="Region", | |
| value=region, | |
| values=regions, | |
| on_value=lambda value: [set_region(value), set_use_regions(value != "India"), set_loading_data(True), set_loading_spatial_mean(True)] | |
| ), | |
| solara.Row(children=[ | |
| solara.Checkbox( | |
| label="Show Region Spatial Mean", | |
| value=show_region_spatial_mean, | |
| on_value=set_show_region_spatial_mean | |
| ), | |
| solara.Checkbox( | |
| label="Show Trend Line", | |
| value=show_region_trend_line, | |
| on_value=set_show_region_trend_line | |
| ) | |
| ]), | |
| solara.Markdown("### Spatial Mean Value") if show_region_spatial_mean else None, | |
| solara.SpinnerSolara(size="64px") if show_region_spatial_mean and loading_spatial_mean else None, | |
| solara.Markdown( | |
| f"**Spatial Mean for {region} ({from_year}-{to_year}):** {spatial_mean_data['overall_mean'].days:.2f} days" | |
| if use_timeframe and from_year and to_year | |
| else f"**Spatial Mean for {region} (All Years):** {spatial_mean_data['overall_mean'].days:.2f} days" | |
| ) if show_region_spatial_mean and isinstance(spatial_mean_data['overall_mean'], pd.Timedelta) and not loading_spatial_mean else solara.Markdown( | |
| f"**Spatial Mean for {region} ({from_year}-{to_year}):** {spatial_mean_data['overall_mean']:.2f}" | |
| if use_timeframe and from_year and to_year | |
| else f"**Spatial Mean for {region} (All Years):** {spatial_mean_data['overall_mean']:.2f}" | |
| ) if show_region_spatial_mean and spatial_mean_data['overall_mean'] is not None and not loading_spatial_mean else None, | |
| solara.Markdown("**Spatial Mean calculation not available**") if show_region_spatial_mean and not loading_spatial_mean and spatial_mean_data['overall_mean'] is None else None, | |
| solara.Markdown("### Region Spatial Mean Timeseries") if show_region_spatial_mean else None, | |
| solara.FigurePlotly(region_timeseries) if show_region_spatial_mean and region_timeseries else None, | |
| solara.Info("Please wait we are calculating the Spatial Mean and Plotting the Plots") if show_region_spatial_mean and not region_timeseries else None | |
| ] if child is not None | |
| ], | |
| expand=False | |
| ) | |
| if selected_coords: | |
| solara.Markdown( | |
| f"**Spatial Mean of Selected Points{' (' + str(from_year) + '-' + str(to_year) + ')' if use_timeframe and from_year and to_year else ''}:** {selected_spatial_mean_data['overall_mean']:.2f}" | |
| if selected_spatial_mean_data["overall_mean"] is not None | |
| else "**No spatial mean available**" | |
| ) | |
| if selected_timeseries: | |
| solara.FigurePlotly(selected_timeseries) | |
| selected_data = selected_spatial_mean_data.get("timeseries", pd.DataFrame()) | |
| if not selected_data.empty: | |
| if dataset_id: | |
| dataset = next(d for d in DATASETS if d["id"] == dataset_id) | |
| selected_data_display = selected_data[["year", list(xr.open_dataset(dataset["timeseries_path"], decode_timedelta=False).data_vars)[0]]] | |
| selected_data_display = selected_data_display.rename(columns={list(xr.open_dataset(dataset["timeseries_path"], decode_timedelta=False).data_vars)[0]: dataset["name"]}) | |
| show_selected_data, set_show_selected_data = solara.use_state(False) | |
| with solara.Row(): | |
| solara.Checkbox( | |
| label="Show Trend Line", | |
| value=show_selected_trend_line, | |
| on_value=set_show_selected_trend_line | |
| ) | |
| solara.Checkbox( | |
| label="Show Region Data", | |
| value=show_selected_data, | |
| on_value=set_show_selected_data | |
| ) | |
| solara.Checkbox( | |
| label="Stats for Nerds", | |
| value=show_stats_for_nerds, | |
| on_value=set_show_stats_for_nerds | |
| ) | |
| if show_selected_data: | |
| solara.Markdown("### Region Data") | |
| display_df = selected_data_display.copy() | |
| if pd.api.types.is_numeric_dtype(display_df[dataset["name"]]): | |
| display_df[dataset["name"]] = display_df[dataset["name"]].map('{:.2f}'.format) | |
| solara.DataFrame(display_df, items_per_page=10) | |
| csv_data = selected_data_display.to_csv(index=False) | |
| solara.FileDownload( | |
| data=csv_data, | |
| filename="selected_points_spatial_mean.csv", | |
| label="Download Region Data as CSV" | |
| ) | |
| else: | |
| solara.Info(label="No data available for selected region.") | |
| else: | |
| solara.Info("Select points on the heatmap to generate a region.") | |
| if show_stats_for_nerds and selected_coords: | |
| coords_df = pd.DataFrame(selected_coords, columns=["Latitude", "Longitude"]) | |
| solara.Markdown(f"**Total Points Selected**: {len(selected_coords)}") | |
| solara.DataFrame(coords_df, items_per_page=5) | |
| coords_csv_data = coords_df.to_csv(index=False) | |
| solara.FileDownload( | |
| data=coords_csv_data, | |
| filename="selected_coordinates.csv", | |
| label="Download Selected Coordinates as CSV" | |
| ) | |
| elif show_stats_for_nerds: | |
| solara.Info("Select points to view coordinates.") | |
| else: | |
| solara.Info(label="Select points on the heatmap to view spatial mean and time series.") |