diff --git a/Dockerfile b/Dockerfile index 03e5279..9abf256 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,18 +2,25 @@ # https://hub.docker.com/_/python FROM python:3.11-slim +# Allow statements and log messages to immediately appear in the Knative logs +ENV PYTHONUNBUFFERED True + RUN apt-get update \ -&& apt-get install gcc -y \ -&& apt-get clean + && apt-get install --no-install-recommends -y gcc \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* -ENV APP_HOME /app -WORKDIR $APP_HOME +# Install pipenv +RUN python -m pip install --upgrade pip \ + && python -m pip install --no-cache-dir "pipenv>=2024.0,<2026.0" +# Set working directory +WORKDIR /app -COPY . ./ +# Copy Pipfile and Pipfile.lock +COPY Pipfile Pipfile.lock ./ -# Install production dependencies. -RUN pip install --upgrade pip -RUN pip install -r requirements.txt +# Install dependencies +RUN pipenv sync --deploy --system EXPOSE 8080 diff --git a/docs/contributing/contributing.md b/docs/contributing/contributing.md index 3018a69..103d52f 100644 --- a/docs/contributing/contributing.md +++ b/docs/contributing/contributing.md @@ -115,9 +115,7 @@ Before submitting a Pull Request, please make sure: - You have installed project dependencies: ```bash -npm install - -pipenv install -r requirements.txt +pipenv sync ``` From the root directory, run: diff --git a/pages/lib/extract_df.py b/pages/lib/extract_df.py index ded1c78..75b8e06 100644 --- a/pages/lib/extract_df.py +++ b/pages/lib/extract_df.py @@ -444,10 +444,8 @@ def create_df(lst, file_name): def convert_SI_to_IP(df: pd.DataFrame, name: str) -> None: """Convert SI to IP based on column name.""" if name not in df.columns: - print( - f"[convert_SI_to_IP] Column '{name}' not found in DataFrame. Skipping conversion." - ) return + match name: case ( Variables.DBT.col_name diff --git a/pages/lib/global_scheme.py b/pages/lib/global_scheme.py index 36fd2d0..8b93053 100644 --- a/pages/lib/global_scheme.py +++ b/pages/lib/global_scheme.py @@ -1,62 +1,56 @@ import plotly.io as pio - +import numpy as np from pages.lib.global_variables import Variables, VariableInfo -# Colors Dictionary -blue_red_yellow = ["#00b3ff", "#000082", "#ff0000", "#ffff00"] -dry_humid = ["#ffe600", "#00c8ff", "#0000ff"] -sun_colors = [ - "#293a59", - "#960c2c", - "#ff0000", - "#ff7b00", - "#fffc00", - "#ffff7b", - "#ffffff", -] -light_colors = ["#4d6daa", "#a0beed", "#f1e969", "#eb7d05", "#d81600"] -bright_colors = ["#730a8c", "#0d0db3", "#0f85be", "#0f85be", "#b11421", "#fdf130"] -wind_speed_color = [ - "#ffffff", - "#b2f2ff", - "#33ddff", - "#00aaff", - "#0055ff", - "#0000ff", - "#aa00ff", - "#ff00ff", - "#cc0000", - "#ffaa00", -] -wind_dir_color = ["#0072dd", "#00c420", "#eded00", "#be00d5", "#0072dd"] -cloud_colors = [ - "#7ec9f3", - "#e6eae9", - "#c2c2c2", -] -utci_categories_color = [ - # Let first 10% (0.1) of the values have color rgb(0, 0, 0) - [0, "#2B2977"], - [0.0555, "#2B2977"], - [0.0555, "#38429B"], - [0.0555 + 0.111 * 1, "#38429B"], - [0.0555 + 0.111 * 1, "#4253A4"], - [0.0555 + 0.111 * 2, "#4253A4"], - [0.0555 + 0.111 * 2, "#4B62AD"], - [0.0555 + 0.111 * 3, "#4B62AD"], - [0.0555 + 0.111 * 3, "#68B8E7"], - [0.0555 + 0.111 * 4, "#68B8E7"], - [0.0555 + 0.111 * 4, "#53B848"], - [0.0555 + 0.111 * 5, "#53B848"], - [0.0555 + 0.111 * 5, "#EE8522"], - [0.0555 + 0.111 * 6, "#EE8522"], - [0.0555 + 0.111 * 6, "#EA2C24"], - [0.0555 + 0.111 * 7, "#EA2C24"], - [0.0555 + 0.111 * 7, "#B12224"], - [0.0555 + 0.111 * 8, "#B12224"], - [0.0555 + 0.111 * 8, "#751613"], - [1.0, "#751613"], -] +WIND_ROSE_BINS = [-1, 0.5, 1.5, 3.3, 5.5, 7.9, 10.7, 13.8, 17.1, 20.7, np.inf] + + +def _stepped_colorscale_from_bins(bins, colors): + """ + Build a stepped colorscale from bin edges and colors. + + Args: + bins: sequence/list of N+1 bin edges (ascending). The last edge may be np.inf. + colors: sequence/list of N colors, one per interval. + + Returns: + List of (position, color) tuples for a Plotly colorscale with positions in [0, 1]. + """ + if len(bins) != len(colors) + 1: + raise ValueError( + f"Expected {len(colors) + 1} bin edges for {len(colors)} colors, " + f"got {len(bins)}" + ) + + if any(b2 < b1 for b1, b2 in zip(bins, bins[1:])): + raise ValueError("bins must be in non-decreasing order") + + finite_edges = [b for b in bins if np.isfinite(b)] + if not finite_edges: + raise ValueError("All bin edges are non-finite; cannot build colorscale.") + + vmin, vmax = finite_edges[0], finite_edges[-1] + span = (vmax - vmin) or 1.0 + + cs = [] + for i, c in enumerate(colors): + left_edge, right_edge = bins[i], bins[i + 1] + + left = 0.0 if not np.isfinite(left_edge) else (left_edge - vmin) / span + right = 1.0 if not np.isfinite(right_edge) else (right_edge - vmin) / span + + left = max(0.0, min(1.0, float(left))) + right = max(0.0, min(1.0, float(right))) + + cs.append((left, c)) + cs.append((right, c)) + + return cs + + +wind_speed_colorscale_rose = _stepped_colorscale_from_bins( + WIND_ROSE_BINS, Variables.WIND_SPEED.color +) # containers container_row_center_full = "container-row row-center" diff --git a/pages/lib/global_variables.py b/pages/lib/global_variables.py index baf12b8..b2a3a17 100644 --- a/pages/lib/global_variables.py +++ b/pages/lib/global_variables.py @@ -1,6 +1,54 @@ from dataclasses import dataclass from typing import Optional, List, Any +from enum import Enum from config import UnitSystem +from plotly.colors import sequential as pseq + + +class ColorPalettes(Enum): + # Palettes + BLUE_RED_YELLOW = ["#00b3ff", "#000082", "#ff0000", "#ffff00"] + DRY_HUMID = ["#ffe600", "#00c8ff", "#0000ff"] + SUN_COLORS = [ + "#293a59", + "#960c2c", + "#ff0000", + "#ff7b00", + "#fffc00", + "#ffff7b", + "#ffffff", + ] + LIGHT_COLORS = ["#4d6daa", "#a0beed", "#f1e969", "#eb7d05", "#d81600"] + SKY_COVER_TRI = ["#08306b", "#7ec9f3", "#e6eae9"] + + # Unit conversions + PA_TO_PSI = 0.000145038 + WHM2_TO_BTU_FT2 = 0.3169983306 + LUX_TO_FC = 0.0929 + + # UTCI category colorscale + UTCI_CATEGORIES_SCALE = [ + [0, "#2B2977"], + [0.0555, "#2B2977"], + [0.0555, "#38429B"], + [0.1665, "#38429B"], + [0.1665, "#4253A4"], + [0.2775, "#4253A4"], + [0.2775, "#4B62AD"], + [0.3885, "#4B62AD"], + [0.3885, "#68B8E7"], + [0.4995, "#68B8E7"], + [0.4995, "#53B848"], + [0.6105, "#53B848"], + [0.6105, "#EE8522"], + [0.7215, "#EE8522"], + [0.7215, "#EA2C24"], + [0.8325, "#EA2C24"], + [0.8325, "#B12224"], + [0.9435, "#B12224"], + [0.9435, "#751613"], + [1.0, "#751613"], + ] @dataclass @@ -101,7 +149,7 @@ class Variables: name="Dry bulb temperature", unit="°C", range=[-40, 50], - color=["#00b3ff", "#000082", "#ff0000", "#ffff00"], + color=ColorPalettes.BLUE_RED_YELLOW.value, IP=IP(unit="°F", range=[-40, 122]), ) DPT = VariableInfo( @@ -109,7 +157,7 @@ class Variables: name="Dew point temperature", unit="°C", range=[-50, 35], - color=["#00b3ff", "#000082", "#ff0000", "#ffff00"], + color=ColorPalettes.BLUE_RED_YELLOW.value, IP=IP(unit="°F", range=[-58, 95]), ) RH = VariableInfo( @@ -117,7 +165,7 @@ class Variables: name="Relative humidity", unit="%", range=[0, 100], - color=["#ffe600", "#00c8ff", "#0000ff"], + color=ColorPalettes.DRY_HUMID.value, ) P_ATM = VariableInfo( @@ -137,7 +185,13 @@ class Variables: "#cc0000", "#ffaa00", ], - IP=IP(unit="Psi", range=[95000 * 0.000145038, 105000 * 0.000145038]), + IP=IP( + unit="Psi", + range=[ + 95000 * ColorPalettes.PA_TO_PSI.value, + 105000 * ColorPalettes.PA_TO_PSI.value, + ], + ), ) # ==================== Radiation Related Variables ==================== @@ -146,80 +200,55 @@ class Variables: name="Extraterrestrial horizontal irradiation", unit="Wh/m2", range=[0, 1200], - color=[ - "#293a59", - "#960c2c", - "#ff0000", - "#ff7b00", - "#fffc00", - "#ffff7b", - "#ffffff", - ], - IP=IP(unit="Btu/ft2", range=[0, 1200 * 0.3169983306]), + color=ColorPalettes.SUN_COLORS.value, + IP=IP( + unit="Btu/ft2", + range=[0, 1200 * ColorPalettes.WHM2_TO_BTU_FT2.value], + ), ) HOR_IR_RAD = VariableInfo( col_name="hor_ir_rad", name="Horizontal infrared radiation", unit="Wh/m2", range=[0, 500], - color=[ - "#293a59", - "#960c2c", - "#ff0000", - "#ff7b00", - "#fffc00", - "#ffff7b", - "#ffffff", - ], - IP=IP(unit="Btu/ft2", range=[0, 500 * 0.3169983306]), + color=ColorPalettes.SUN_COLORS.value, + IP=IP( + unit="Btu/ft2", + range=[0, 500 * ColorPalettes.WHM2_TO_BTU_FT2.value], + ), ) GLOB_HOR_RAD = VariableInfo( col_name="glob_hor_rad", name="Global horizontal radiation", unit="Wh/m2", range=[0, 1200], - color=[ - "#293a59", - "#960c2c", - "#ff0000", - "#ff7b00", - "#fffc00", - "#ffff7b", - "#ffffff", - ], - IP=IP(unit="Btu/ft2", range=[0, 1200 * 0.3169983306]), + color=ColorPalettes.SUN_COLORS.value, + IP=IP( + unit="Btu/ft2", + range=[0, 1200 * ColorPalettes.WHM2_TO_BTU_FT2.value], + ), ) DIR_NOR_RAD = VariableInfo( col_name="dir_nor_rad", name="Direct normal radiation", unit="Wh/m2", range=[0, 1200], - color=[ - "#293a59", - "#960c2c", - "#ff0000", - "#ff7b00", - "#fffc00", - "#ffff7b", - "#ffffff", - ], - IP=IP(unit="Btu/ft2", range=[0, 1200 * 0.3169983306]), + color=ColorPalettes.SUN_COLORS.value, + IP=IP( + unit="Btu/ft2", + range=[0, 1200 * ColorPalettes.WHM2_TO_BTU_FT2.value], + ), ) DIF_HOR_RAD = VariableInfo( col_name="dif_hor_rad", name="Diffuse horizontal radiation", unit="Wh/m2", range=[0, 1200], - color=[ - "#293a59", - "#960c2c", - "#ff0000", - "#ff7b00", - "#fffc00", - "#ffff7b", - "#ffffff", - ], - IP=IP(unit="Btu/ft2", range=[0, 1200 * 0.3169983306]), + color=ColorPalettes.SUN_COLORS.value, + IP=IP( + unit="Btu/ft2", + range=[0, 1200 * ColorPalettes.WHM2_TO_BTU_FT2.value], + ), ) # ==================== Lighting Related Variables ==================== @@ -228,24 +257,24 @@ class Variables: name="Global horizontal illuminance", unit="lux", range=[0, 120000], - color=["#4d6daa", "#a0beed", "#f1e969", "#eb7d05", "#d81600"], - IP=IP(unit="fc", range=[0, 120000 * 0.0929]), + color=ColorPalettes.LIGHT_COLORS.value, + IP=IP(unit="fc", range=[0, 120000 * ColorPalettes.LUX_TO_FC.value]), ) DIR_NOR_ILL = VariableInfo( col_name="dir_nor_ill", name="Direct normal illuminance", unit="lux", range=[0, 120000], - color=["#4d6daa", "#a0beed", "#f1e969", "#eb7d05", "#d81600"], - IP=IP(unit="fc", range=[0, 120000 * 0.0929]), + color=ColorPalettes.LIGHT_COLORS.value, + IP=IP(unit="fc", range=[0, 120000 * ColorPalettes.LUX_TO_FC.value]), ) DIF_HOR_ILL = VariableInfo( col_name="dif_hor_ill", name="Diffuse horizontal illuminance", unit="lux", range=[0, 120000], - color=["#4d6daa", "#a0beed", "#f1e969", "#eb7d05", "#d81600"], - IP=IP(unit="fc", range=[0, 120000 * 0.0929]), + color=ColorPalettes.LIGHT_COLORS.value, + IP=IP(unit="fc", range=[0, 120000 * ColorPalettes.LUX_TO_FC.value]), ) ZLUMI = VariableInfo( @@ -263,7 +292,7 @@ class Variables: name="Wind direction", unit="°deg", range=[0, 360], - color=["#0072dd", "#00c420", "#eded00", "#be00d5", "#0072dd"], + color=list(pseq.Viridis), ) WIND_SPEED = VariableInfo( col_name="wind_speed", @@ -271,16 +300,16 @@ class Variables: unit="m/s", range=[0, 20], color=[ - "#D3D3D3", - "#b2f2ff", - "#33ddff", - "#00aaff", - "#0055ff", - "#0000ff", - "#aa00ff", - "#ff00ff", - "#cc0000", - "#ffaa00", + "#feffff", + "#dcf0fc", + "#c2defe", + "#b8cafd", + "#beb1f5", + "#d093df", + "#e272bb", + "#eb4f8b", + "#e52d51", + "#d0210e", ], IP=IP(unit="fpm", range=[0, 20 * 196.85039370078738]), ) @@ -290,33 +319,21 @@ class Variables: name="Total sky cover", unit="tenths", range=[0, 10], - color=[ - "#7ec9f3", - "#e6eae9", - "#c2c2c2", - ], + color=ColorPalettes.SKY_COVER_TRI.value, ) OPAQUE_SKY_COVER = VariableInfo( col_name="Oskycover", name="Opaque sky cover", unit="tenths", range=[0, 10], - color=[ - "#7ec9f3", - "#e6eae9", - "#c2c2c2", - ], + color=ColorPalettes.SKY_COVER_TRI.value, ) VIS = VariableInfo( col_name="Vis", name="Visibility", unit="km", range=[0, 100], - color=[ - "#7ec9f3", - "#e6eae9", - "#c2c2c2", - ], + color=ColorPalettes.SKY_COVER_TRI.value, IP=IP(unit="miles", range=[0, 100 * 0.6215]), ) @@ -326,90 +343,42 @@ class Variables: name="Apparent zenith", unit="°deg", range=[0, 180], - color=[ - "#293a59", - "#960c2c", - "#ff0000", - "#ff7b00", - "#fffc00", - "#ffff7b", - "#ffffff", - ], + color=ColorPalettes.SUN_COLORS.value, ) ZENITH = VariableInfo( col_name="zenith", name="Zenith", unit="°deg", range=[0, 180], - color=[ - "#293a59", - "#960c2c", - "#ff0000", - "#ff7b00", - "#fffc00", - "#ffff7b", - "#ffffff", - ], + color=ColorPalettes.SUN_COLORS.value, ) APPARENT_ELEVATION = VariableInfo( col_name="apparent_elevation", name="Apparent elevation", unit="°deg", range=[-90, 90], - color=[ - "#293a59", - "#960c2c", - "#ff0000", - "#ff7b00", - "#fffc00", - "#ffff7b", - "#ffffff", - ], + color=ColorPalettes.SUN_COLORS.value, ) ELEVATION = VariableInfo( col_name="elevation", name="Elevation", unit="°deg", range=[-90, 90], - color=[ - "#293a59", - "#960c2c", - "#ff0000", - "#ff7b00", - "#fffc00", - "#ffff7b", - "#ffffff", - ], + color=ColorPalettes.SUN_COLORS.value, ) AZIMUTH = VariableInfo( col_name="azimuth", name="Azimuth", unit="°deg", range=[0, 360], - color=[ - "#293a59", - "#960c2c", - "#ff0000", - "#ff7b00", - "#fffc00", - "#ffff7b", - "#ffffff", - ], + color=ColorPalettes.SUN_COLORS.value, ) EQUATION_OF_TIME = VariableInfo( col_name="equation_of_time", name="Equation of time", unit="°deg", range=[-20, 20], - color=[ - "#293a59", - "#960c2c", - "#ff0000", - "#ff7b00", - "#fffc00", - "#ffff7b", - "#ffffff", - ], + color=ColorPalettes.SUN_COLORS.value, ) # ==================== UTCI Comfort Related Variables ==================== @@ -418,7 +387,7 @@ class Variables: name="UTCI: Sun & Wind", unit="°C", range=[-70, 70], - color=["#00b3ff", "#000082", "#ff0000", "#ffff00"], + color=ColorPalettes.BLUE_RED_YELLOW.value, IP=IP(unit="°F", range=[-94, 158]), ) UTCI_NO_SUN_WIND = VariableInfo( @@ -426,7 +395,7 @@ class Variables: name="UTCI: no Sun & Wind", unit="°C", range=[-70, 70], - color=["#00b3ff", "#000082", "#ff0000", "#ffff00"], + color=ColorPalettes.BLUE_RED_YELLOW.value, IP=IP(unit="°F", range=[-94, 158]), ) UTCI_SUN_NO_WIND = VariableInfo( @@ -434,7 +403,7 @@ class Variables: name="UTCI: Sun & no Wind", unit="°C", range=[-70, 70], - color=["#00b3ff", "#000082", "#ff0000", "#ffff00"], + color=ColorPalettes.BLUE_RED_YELLOW.value, IP=IP(unit="°F", range=[-94, 158]), ) UTCI_NO_SUN_NO_WIND = VariableInfo( @@ -442,7 +411,7 @@ class Variables: name="UTCI: no Sun & no Wind", unit="°C", range=[-70, 70], - color=["#00b3ff", "#000082", "#ff0000", "#ffff00"], + color=ColorPalettes.BLUE_RED_YELLOW.value, IP=IP(unit="°F", range=[-94, 158]), ) @@ -451,112 +420,28 @@ class Variables: name="UTCI: Sun & Wind : categories", unit="Thermal stress", range=[-5, 4], - color=[ - [0, "#2B2977"], - [0.0555, "#2B2977"], - [0.0555, "#38429B"], - [0.1665, "#38429B"], - [0.1665, "#4253A4"], - [0.2775, "#4253A4"], - [0.2775, "#4B62AD"], - [0.3885, "#4B62AD"], - [0.3885, "#68B8E7"], - [0.4995, "#68B8E7"], - [0.4995, "#53B848"], - [0.6105, "#53B848"], - [0.6105, "#EE8522"], - [0.7215, "#EE8522"], - [0.7215, "#EA2C24"], - [0.8325, "#EA2C24"], - [0.8325, "#B12224"], - [0.9435, "#B12224"], - [0.9435, "#751613"], - [1.0, "#751613"], - ], + color=ColorPalettes.UTCI_CATEGORIES_SCALE.value, ) UTCI_NOSUN_WIND_CATEGORIES = VariableInfo( col_name="utci_noSun_Wind_categories", name="UTCI: no Sun & Wind : categories", unit="Thermal stress", range=[-5, 4], - color=[ - [0, "#2B2977"], - [0.0555, "#2B2977"], - [0.0555, "#38429B"], - [0.1665, "#38429B"], - [0.1665, "#4253A4"], - [0.2775, "#4253A4"], - [0.2775, "#4B62AD"], - [0.3885, "#4B62AD"], - [0.3885, "#68B8E7"], - [0.4995, "#68B8E7"], - [0.4995, "#53B848"], - [0.6105, "#53B848"], - [0.6105, "#EE8522"], - [0.7215, "#EE8522"], - [0.7215, "#EA2C24"], - [0.8325, "#EA2C24"], - [0.8325, "#B12224"], - [0.9435, "#B12224"], - [0.9435, "#751613"], - [1.0, "#751613"], - ], + color=ColorPalettes.UTCI_CATEGORIES_SCALE.value, ) UTCI_SUN_NOWIND_CATEGORIES = VariableInfo( col_name="utci_Sun_noWind_categories", name="UTCI: Sun & no Wind : categories", unit="Thermal stress", range=[-5, 4], - color=[ - [0, "#2B2977"], - [0.0555, "#2B2977"], - [0.0555, "#38429B"], - [0.1665, "#38429B"], - [0.1665, "#4253A4"], - [0.2775, "#4253A4"], - [0.2775, "#4B62AD"], - [0.3885, "#4B62AD"], - [0.3885, "#68B8E7"], - [0.4995, "#68B8E7"], - [0.4995, "#53B848"], - [0.6105, "#53B848"], - [0.6105, "#EE8522"], - [0.7215, "#EE8522"], - [0.7215, "#EA2C24"], - [0.8325, "#EA2C24"], - [0.8325, "#B12224"], - [0.9435, "#B12224"], - [0.9435, "#751613"], - [1.0, "#751613"], - ], + color=ColorPalettes.UTCI_CATEGORIES_SCALE.value, ) UTCI_NOSUN_NOWIND_CATEGORIES = VariableInfo( col_name="utci_noSun_noWind_categories", name="UTCI: no Sun & no Wind : categories", unit="Thermal stress", range=[-5, 4], - color=[ - [0, "#2B2977"], - [0.0555, "#2B2977"], - [0.0555, "#38429B"], - [0.1665, "#38429B"], - [0.1665, "#4253A4"], - [0.2775, "#4253A4"], - [0.2775, "#4B62AD"], - [0.3885, "#4B62AD"], - [0.3885, "#68B8E7"], - [0.4995, "#68B8E7"], - [0.4995, "#53B848"], - [0.6105, "#53B848"], - [0.6105, "#EE8522"], - [0.7215, "#EE8522"], - [0.7215, "#EA2C24"], - [0.8325, "#EA2C24"], - [0.8325, "#B12224"], - [0.9435, "#B12224"], - [0.9435, "#751613"], - [1.0, "#751613"], - ], + color=ColorPalettes.UTCI_CATEGORIES_SCALE.value, ) # ==================== Additional Meteorological Data ==================== @@ -565,7 +450,7 @@ class Variables: name="Vapor partial pressure", unit="Pa", range=[0, 5000], - color=["#ffe600", "#00c8ff", "#0000ff"], + color=ColorPalettes.DRY_HUMID.value, IP=IP(unit="Psi", range=[0, 5000 * 0.000145038]), ) P_SAT = VariableInfo( @@ -580,7 +465,7 @@ class Variables: name="Absolute humidity", unit="g water/kg dry air", range=[0, 0.03 * 1000], - color=["#ffe600", "#00c8ff", "#0000ff"], + color=ColorPalettes.DRY_HUMID.value, IP=IP(unit="lb water/klb dry air", range=[0, 0.03 * 1000]), ) T_WB = VariableInfo( @@ -588,7 +473,7 @@ class Variables: name="Wet bulb temperature", unit="°C", range=[-40, 50], - color=["#00b3ff", "#000082", "#ff0000", "#ffff00"], + color=ColorPalettes.BLUE_RED_YELLOW.value, IP=IP(unit="°F", range=[-40, 122]), ) T_DP = VariableInfo( @@ -596,7 +481,7 @@ class Variables: name="Dew point temperature", unit="°C", range=[-40, 50], - color=["#00b3ff", "#000082", "#ff0000", "#ffff00"], + color=ColorPalettes.BLUE_RED_YELLOW.value, IP=IP(unit="°F", range=[-40, 122]), ) EH = VariableInfo( @@ -604,7 +489,7 @@ class Variables: name="Enthalpy", unit="J/kg dry air", range=[0, 110000], - color=["#00b3ff", "#000082", "#ff0000", "#ffff00"], + color=ColorPalettes.BLUE_RED_YELLOW.value, IP=IP(unit="Btu/lb dry air", range=[0, 110000 * 0.000429923]), ) diff --git a/pages/lib/template_graphs.py b/pages/lib/template_graphs.py index 4dcc499..1fb189d 100644 --- a/pages/lib/template_graphs.py +++ b/pages/lib/template_graphs.py @@ -6,7 +6,7 @@ from config import UnitSystem from pages.lib.utils import get_max_min_value import dash_bootstrap_components as dbc -from .global_scheme import month_lst, template, tight_margins +from .global_scheme import month_lst, template, tight_margins, WIND_ROSE_BINS from pages.lib.global_variables import Variables, VariableInfo from .utils import code_timer, determine_month_and_hour_filter @@ -430,6 +430,12 @@ def heatmap_with_filter( ) ) + if var == Variables.WIND_SPEED.col_name: + spd_bins = list(WIND_ROSE_BINS) + if si_ip == UnitSystem.IP: + spd_bins = convert_bins(spd_bins) + fig.update_traces(zmin=0, zmax=spd_bins[-2]) + fig.update_xaxes(dtick="M1", tickformat="%b", ticklabelmode="period") fig.update_yaxes(title_text="Hour") @@ -492,6 +498,12 @@ def heatmap(df, var, global_local, si_ip): ) ) + if var == Variables.WIND_SPEED.col_name: + spd_bins = list(WIND_ROSE_BINS) + if si_ip == UnitSystem.IP: + spd_bins = convert_bins(spd_bins) + fig.update_traces(zmin=0, zmax=spd_bins[-2]) + fig.update_xaxes(dtick="M1", tickformat="%b", ticklabelmode="period") fig.update_yaxes(title_text="Hour") @@ -551,7 +563,7 @@ def wind_rose(df, title, month, hour, labels, si_ip): spd_colors = wind_speed_variable.get_color() spd_unit = wind_speed_variable.get_unit(si_ip) - spd_bins = [-1, 0.5, 1.5, 3.3, 5.5, 7.9, 10.7, 13.8, 17.1, 20.7, np.inf] + spd_bins = WIND_ROSE_BINS if si_ip == UnitSystem.IP: spd_bins = convert_bins(spd_bins) diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 14cdb68..0000000 --- a/requirements.txt +++ /dev/null @@ -1,59 +0,0 @@ -ansi2html==1.9.2 -black==25.1.0 -blinker==1.9.0 -bump2version==1.0.1 -cachelib==0.9.0 -certifi==2025.7.14 -charset-normalizer==3.4.2 -cleanpy==0.5.1 -click==8.2.1 -dash==3.2.0 -dash-bootstrap-components==1.2.0 -dash-core-components==2.0.0 -dash-extensions==1.0.7 -dash-html-components==2.0.0 -dash-iconify==0.1.2 -dash-mantine-components==2.2.1 -dash-table==5.0.0 -dataclass-wizard==0.22.3 -EditorConfig==0.17.1 -Flask==2.3.3 -Flask-Caching==2.0.2 -h5py==3.14.0 -idna==3.10 -importlib_metadata==8.7.0 -iniconfig==2.1.0 -itsdangerous==2.2.0 -Jinja2==3.1.6 -jsbeautifier==1.15.4 -llvmlite==0.44.0 -MarkupSafe==3.0.2 -more-itertools==9.1.0 -mypy_extensions==1.1.0 -narwhals==2.0.1 -nest-asyncio==1.6.0 -numba==0.61.2 -numpy==1.26.3 -packaging==25.0 -pandas==2.2.0 -pathspec==0.12.1 -platformdirs==4.3.8 -plotly==5.18.0 -pluggy==1.6.0 -pvlib==0.9.1 -Pygments==2.19.2 -pytest==8.4.1 -pythermalcomfort==2.9.1 -python-dateutil==2.9.0.post0 -pytz==2025.2 -requests==2.32.4 -retrying==1.4.1 -ruff==0.12.7 -scipy==1.12.0 -six==1.17.0 -tenacity==9.1.2 -typing_extensions==4.14.1 -tzdata==2025.2 -urllib3==2.5.0 -Werkzeug==3.0.6 -zipp==3.23.0