Skip to content

chore(a11y): update color schemes for color-blind assessment #110#256

Merged
FedericoTartarini merged 9 commits intoCenterForTheBuiltEnvironment:developmentfrom
LeoLuosifen:fwan
Oct 27, 2025
Merged

chore(a11y): update color schemes for color-blind assessment #110#256
FedericoTartarini merged 9 commits intoCenterForTheBuiltEnvironment:developmentfrom
LeoLuosifen:fwan

Conversation

@FengW01
Copy link
Contributor

@FengW01 FengW01 commented Oct 15, 2025

Update and unify color schemes to improve color-blind accessibility.

  • UTCI heatmap: unchanged (keeps the original paper’s scheme)
  • Solar/Cloud coverage: #08306b → #7ec9f3 → #e6eae9 (dark→medium→light)
  • Wind speed / Wind rose: Colorcet CET_L19
  • Wind direction: Viridis

Summary by CodeRabbit

  • Style
    • Standardized color palettes across all weather data visualizations, including temperature, humidity, radiation, sky cover, wind direction, and visibility displays.
    • Refined wind rose visualization with updated speed binning intervals and enhanced color gradient mapping.

@coderabbitai
Copy link

coderabbitai bot commented Oct 15, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

The changes refactor color palette management by centralizing hardcoded color dictionaries into a reusable Common enum in global_variables.py and introducing a dynamic colorscale builder function in global_scheme.py. Wind rose bins are extracted as a public constant and integrated throughout the template graphs module.

Changes

Cohort / File(s) Summary
Color palette centralization
pages/lib/global_variables.py
Introduced Common enum with five color palettes (BLUE_RED_YELLOW, DRY_HUMID, SUN_COLORS, LIGHT_COLORS, SKY_COVER_TRI), three unit conversion constants (PA_TO_PSI, WHM2_TO_BTUFT2, LUX_TO_FC), and UTCI_CATEGORIES_SCALE. Updated all Variables definitions to reference these centralized palettes instead of hardcoded colors.
Dynamic colorscale generation
pages/lib/global_scheme.py
Added WIND_ROSE_BINS constant and _stepped_colorscale_from_bins() helper function for generating stepped colorscales. Replaced predefined color dictionaries with dynamic derivation of wind_speed_colorscale_rose from WIND_ROSE_BINS and Variables.WIND_SPEED.color.
Colorscale integration
pages/lib/template_graphs.py
Imported WIND_ROSE_BINS from global_scheme. Updated heatmap and wind_rose functions to use WIND_ROSE_BINS with unit conversion for IP systems, setting consistent zmin/zmax ranges.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

The changes introduce new centralized constants and a helper function requiring logic validation, but follow consistent patterns across multiple file updates. Most edits are repetitive palette references in variable definitions, reducing complexity. The new colorscale builder and bin constant integration are straightforward and localized.

Poem

🐰 A palette so bright, now in one place to find,
No colors scattered—organized and refined!
Bins aligned with care, windrose spins with grace,
Constants and enums give order to the space! 🌈

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "chore(a11y): update color schemes for color-blind assessment #110" directly reflects the main purpose of the changeset, which implements multiple color scheme updates specifically designed to improve accessibility for color-blind users. The changes across all three modified files center on replacing hardcoded color values with centralized, accessible palettes (Colorcet CET_L19 for wind speed, Viridis for wind direction, and a dark-to-light sequence for solar/cloud coverage). The title is concise, specific enough to convey the nature of the changes, and uses appropriate conventional commit syntax with an accessibility-focused scope indicator (a11y). While the title doesn't enumerate all details like the code refactoring or specific color schemes used, such comprehensiveness is not required and would make the title overly verbose.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai
Copy link

coderabbitai bot commented Oct 16, 2025

Tip

For best results, initiate chat on the files or code changes.

@FedericoTartarini: Hello! How can I help you with this pull request? I can:

  • Review the color scheme changes for accessibility
  • Analyze the implementation details
  • Generate tests or documentation
  • Search the codebase for related code
  • Answer questions about the changes
  • Help with any other aspect of the PR

Please let me know what you'd like me to do!

@FedericoTartarini
Copy link
Contributor

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Oct 16, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (1)
pages/lib/global_variables.py (1)

4-5: Verify that colorcet is in project dependencies.

The new colorcet library is imported but may not be listed in the project's dependencies. Ensure it's added to requirements files to prevent runtime import errors.

This is the same concern raised for pages/lib/global_scheme.py. The verification script provided there will check both files.

🧹 Nitpick comments (1)
pages/lib/global_scheme.py (1)

20-20: Eliminate code duplication with global_variables.py.

The exact formula for generating wind_speed_color is duplicated at line 274 of pages/lib/global_variables.py. This violates the DRY principle and creates a maintenance burden.

Consider extracting this into a shared utility function or referencing a single source of truth. For example, define it once in global_variables.py and import it here:

In global_scheme.py:

+from pages.lib.global_variables import Variables
+
-wind_speed_color = [cc.CET_L19[int(round(i*(len(cc.CET_L19)-1)/(9)))] for i in range(10)]
+wind_speed_color = Variables.WIND_SPEED.get_color()

Or define it in a shared constants module if you prefer to keep the files independent.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between adc5764 and cb79f39.

📒 Files selected for processing (2)
  • pages/lib/global_scheme.py (2 hunks)
  • pages/lib/global_variables.py (5 hunks)
🧰 Additional context used
🪛 GitHub Actions: Python Testing 🐍
pages/lib/global_scheme.py

[error] 1-1: Command 'pipenv run ruff format --check .' reported formatting issues; would reformat this file. Run 'ruff format' to fix code style issues.

pages/lib/global_variables.py

[error] 1-1: Command 'pipenv run ruff format --check .' reported formatting issues; would reformat this file. Run 'ruff format' to fix code style issues.

🔇 Additional comments (7)
pages/lib/global_scheme.py (2)

21-21: LGTM! Viridis is color-blind friendly.

The switch to the Viridis color scheme for wind direction improves accessibility for color-blind users while maintaining good visual distinction.


22-26: cloud_colors is unused in the codebase; the review concern is invalid.

The variable cloud_colors is defined in pages/lib/global_scheme.py but is never imported or referenced anywhere else. Multiple files import various symbols from global_scheme.py (such as month_lst, template, dropdown_names), but none import cloud_colors. Therefore, changing its length from 2 to 3 colors has no impact on any code that assumes a specific array length or uses hardcoded indices.

Likely an incorrect or invalid review comment.

pages/lib/global_variables.py (5)

262-268: LGTM! Viridis is color-blind friendly.

The switch to the Viridis color scheme for wind direction improves accessibility for color-blind users. The use of list(pseq.Viridis) creates a mutable copy of the color sequence, which is appropriate for this configuration.


269-276: LGTM! CET_L19 is optimized for perceptual uniformity.

The switch to Colorcet's CET_L19 palette improves color-blind accessibility. The formula correctly samples 10 evenly-spaced colors from the palette using (len(cc.CET_L19)-1)/9 to ensure the last index maps to the last color.

Note: This formula is duplicated in pages/lib/global_scheme.py line 20. See the refactoring suggestion there.


278-288: No hardcoded assumptions for TOT_SKY_COVER color array length. Prepending #08306b is safe.


289-299: No issues identified; original review comment is incorrect.

Verification shows all OPAQUE_SKY_COVER references in the codebase use only the .col_name attribute (global_scheme.py and extract_df.py). The color array is accessed generically via get_color() method with no hardcoded length assumptions. Additionally, TOT_SKY_COVER already uses an identical 3-element color array, demonstrating this pattern is established and compatible throughout the codebase.


300-311: No impact on visualization compatibility—change is safe to proceed.

The color array is accessed dynamically throughout the codebase:

  • var_color[0] and var_color[-1] extract endpoints regardless of length
  • var_color[len(var_color) // 2] correctly identifies the middle element (2 colors → index 1; 3 colors → index 1)
  • All colorscale=var_color usages pass the array directly to Plotly, which handles variable-length gradients automatically

No hardcoded length assumptions or specific index dependencies exist. The addition of #08306b to the VIS color array is fully compatible with all visualization code.

@FengW01
Copy link
Contributor Author

FengW01 commented Oct 20, 2025

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Oct 20, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (1)
pages/lib/template_graphs.py (1)

501-505: Duplicate logic; consolidate with heatmap_with_filter.

This wind speed bin handling duplicates the logic at lines 433-437. After fixing WIND_ROSE_BINS and importing it, apply the same refactor here to eliminate duplication.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cb79f39 and 1e502cd.

📒 Files selected for processing (3)
  • pages/lib/global_scheme.py (2 hunks)
  • pages/lib/template_graphs.py (2 hunks)
  • requirements.txt (1 hunks)
🔇 Additional comments (3)
requirements.txt (1)

10-10: LGTM! Dependency added correctly.

The colorcet dependency is properly added with an appropriate version constraint that allows minor and patch updates within the 3.x series.

pages/lib/global_scheme.py (2)

2-3: LGTM! Imports added for new color palette sources.

The imports enable dynamic color generation from colorcet and plotly sequential palettes, which aligns with the PR's accessibility objectives.


39-48: LGTM! Color palette updates align with accessibility goals.

The dynamic generation of wind_speed_colorscale_rose, the switch to Viridis for wind direction, and the updated cloud colors with the new leading color #08306b support the PR's objective to improve color-blind accessibility.

@FengW01
Copy link
Contributor Author

FengW01 commented Oct 20, 2025

@FedericoTartarini Please take a look when you have time. Thanks!

@FengW01
Copy link
Contributor Author

FengW01 commented Oct 22, 2025

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Oct 22, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
pages/lib/global_scheme.py (1)

29-38: Add docstring and input validation.

The _stepped_colorscale_from_bins function lacks documentation and doesn't validate that the relationship between bins and colors is correct (should be len(bins) == len(colors) + 1).

Based on past review comments, apply this diff to add documentation and validation:

 def _stepped_colorscale_from_bins(bins, colors):
+    """Build a stepped colorscale from bin edges and colors.
+    
+    Args:
+        bins: List of N+1 bin edges defining N intervals
+        colors: List of N colors, one per interval
+        
+    Returns:
+        List of (position, color) tuples for Plotly colorscale
+    """
+    if len(bins) != len(colors) + 1:
+        raise ValueError(f"Expected {len(colors)+1} bin edges for {len(colors)} colors, got {len(bins)}")
     vmin, vmax = bins[0], bins[-1]
🧹 Nitpick comments (2)
pages/lib/template_graphs.py (1)

566-566: Refactor to use centralized WIND_ROSE_BINS.

The hardcoded bins at line 566 duplicate the WIND_ROSE_BINS constant defined in global_scheme.py. This creates a maintenance burden and risks inconsistency if bins are updated.

Apply this diff to use the centralized constant:

-    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 = list(WIND_ROSE_BINS)
     if si_ip == UnitSystem.IP:
         spd_bins = convert_bins(spd_bins)
pages/lib/global_variables.py (1)

23-25: Code duplication: CET_L19_10 generation repeated.

The same color generation logic appears in both pages/lib/global_variables.py (lines 23-25) and pages/lib/global_scheme.py (lines 22-24). This duplication means any future changes must be made in two places.

Consider one of these approaches:

Option 1 (recommended): Define CET_L19_10 in global_variables.py only and import it in global_scheme.py:

In pages/lib/global_scheme.py:

+from pages.lib.global_variables import CET_L19_10
+
-# Take 10 colors at equal intervals (including both ends)
-wind_speed_color = [
-    cc.CET_L19[int(round(i * (len(cc.CET_L19) - 1) / (9)))] for i in range(10)
-]
+wind_speed_color = CET_L19_10

Option 2: Define it once in global_scheme.py and import in global_variables.py (but this would create a circular dependency risk since global_scheme.py imports from global_variables.py).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1e502cd and b4a51cb.

⛔ Files ignored due to path filters (1)
  • Pipfile.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • Pipfile (1 hunks)
  • pages/lib/global_scheme.py (2 hunks)
  • pages/lib/global_variables.py (12 hunks)
  • pages/lib/template_graphs.py (3 hunks)
🔇 Additional comments (10)
Pipfile (1)

19-19: LGTM! Dependency properly added.

The colorcet dependency has been correctly added with appropriate version constraints, resolving the previous issue where the library was imported but not declared in dependencies.

pages/lib/global_scheme.py (3)

2-4: LGTM! Required imports properly added.

The new imports for colorcet, numpy, and plotly.colors.sequential are necessary for the color scheme improvements and are correctly positioned.


21-26: LGTM! Bin and color generation are correctly aligned.

The color generation produces 10 colors from CET_L19, and WIND_ROSE_BINS defines 11 bin edges (10 intervals), which is the correct relationship for a stepped colorscale.


41-50: LGTM! Color schemes updated for accessibility.

The wind speed colorscale, wind direction colors (Viridis), and cloud colors have been properly updated to improve color-blind accessibility as stated in the PR objectives.

pages/lib/template_graphs.py (3)

9-9: LGTM! Centralized bins imported.

Importing WIND_ROSE_BINS from global_scheme establishes a single source of truth for wind speed binning.


433-437: LGTM! Wind speed heatmap correctly uses centralized bins.

The code properly:

  • Uses WIND_ROSE_BINS from the central definition
  • Converts bins for IP units when needed
  • Sets zmax to the second-to-last bin (20.7), excluding np.inf from the color scale

501-505: LGTM! Consistent bin usage across heatmap functions.

This heatmap function correctly mirrors the approach in heatmap_with_filter, maintaining consistency.

pages/lib/global_variables.py (3)

4-5: LGTM! Required imports added.

The imports for colorcet and plotly.colors.sequential enable the centralized color palette generation.


7-31: LGTM! Centralized palettes improve maintainability.

The centralized color palettes and unit conversion constants consolidate previously scattered color definitions, making them easier to maintain and update.


150-465: LGTM! Comprehensive color palette refactoring.

The systematic replacement of hard-coded color arrays with centralized palettes across all VariableInfo instances improves consistency and maintainability. The use of conversion constants for IP ranges is also well-implemented.

@coderabbitai
Copy link

coderabbitai bot commented Oct 22, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@FengW01
Copy link
Contributor Author

FengW01 commented Oct 22, 2025

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Oct 22, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@FengW01 FengW01 changed the title chore(a11y): update color schemes for color-blind assessment #110Fwan chore(a11y): update color schemes for color-blind assessment #110 Oct 22, 2025
@FengW01
Copy link
Contributor Author

FengW01 commented Oct 22, 2025

504028552-70025559-1e2a-43e0-87e7-275d09f7a8b3

refactored the code by moving these duplicated items to the beginning of the file. This allows other modules to directly reference them, reducing redundancy and improving maintainability.

@FedericoTartarini Please review the update and let me know if any further adjustments are needed. Thank you!

… Enum and drop colorcet in favor of hex color lists
@FengW01
Copy link
Contributor Author

FengW01 commented Oct 24, 2025

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Oct 24, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@FengW01
Copy link
Contributor Author

FengW01 commented Oct 24, 2025

@FedericoTartarini thanks for your feedback!
All other parts have been modified according to your suggestions — only this function (_stepped_colorscale_from_bins) remains, as it’s needed to convert the discrete Wind Rose color bins into a continuous colorscale for the heat map. This ensures both charts use exactly the same color mapping for wind speed values.

@FedericoTartarini FedericoTartarini merged commit fb9de71 into CenterForTheBuiltEnvironment:development Oct 27, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants