Skip to content

Conversation

@FBumann
Copy link
Member

@FBumann FBumann commented Jan 21, 2026

Summary

Add color parameter to all component classes and provide bulk color assignment methods via flow_system.topology.

Changes

Added color parameter to component classes:

  • LinearConverter, Storage, Transmission, Source, Sink
  • Convenience classes: Boiler, Power2Heat, HeatPump, CoolingTower, CHP, HeatPumpWithSource

Added bulk color assignment methods to TopologyAccessor:

  • set_component_color(label, color) - single component
  • set_component_colors(colors, overwrite=True) - multiple components
  • set_carrier_color(carrier, color) - carrier colors (affects bus colors)

Usage

# At instantiation
boiler = fx.Boiler('Boiler', ..., color='#D35400')
storage = fx.Storage('Battery', ..., color='green')

# Bulk assignment via topology accessor
flow_system.topology.set_component_colors({
    'Boiler': '#D35400',
    'CHP': 'darkred',
})

# Colorscale for groups
flow_system.topology.set_component_colors({
    'Oranges': ['Solar1', 'Solar2'],
    'Blues': ['Wind1', 'Wind2'],
})

# Apply colorscale to all components
flow_system.topology.set_component_colors('turbo')

# Only set colors for components without existing colors
flow_system.topology.set_component_colors('turbo', overwrite=False)

Type of Change

  • New feature

Testing

  • I have tested my changes
  • Existing tests still pass

Checklist

  • My code follows the project style
  • I have updated documentation if needed

Summary by CodeRabbit

Release Notes

  • New Features

    • Added optional color parameter to component constructors for visualization customization at instantiation.
    • Introduced topology-based color API with new methods: set_component_color(), set_component_colors(), and set_carrier_color() for flexible color management.
    • Support for bulk color assignment and colorscale mapping.
  • Documentation

    • Updated user guide with examples demonstrating the new color parameter and topology-based color API.

✏️ Tip: You can customize this high-level summary in your review settings.

…s.py, flixopt/linear_converters.py):

  - LinearConverter, Storage, Transmission, Source, Sink
  - Boiler, Power2Heat, HeatPump, CoolingTower, CHP, HeatPumpWithSource

  2. Added bulk color assignment methods to TopologyAccessor (flixopt/topology_accessor.py):

  # Single component
  flow_system.topology.set_component_color('Boiler', '#D35400')

  # Multiple components - direct assignment
  flow_system.topology.set_component_colors({
      'Boiler': '#D35400',
      'CHP': 'darkred',
  })

  # Multiple components - colorscale for groups
  flow_system.topology.set_component_colors({
      'Oranges': ['Solar1', 'Solar2'],
      'Blues': ['Wind1', 'Wind2'],
  })

  # All components with colorscale
  flow_system.topology.set_component_colors('turbo')

  # Carrier color (affects bus colors)
  flow_system.topology.set_carrier_color('electricity', '#FECB52')

  3. Cache invalidation - _invalidate_color_caches() resets cached color dicts when colors change.

  4. Updated documentation (docs/user-guide/results-plotting.md) - Fixed the incorrect flow_system.colors references to use flow_system.topology.

  Read-only accessors still available:
  flow_system.topology.component_colors  # dict[str, str]
  flow_system.topology.carrier_colors    # dict[str, str]
  flow_system.topology.bus_colors        # dict[str, str]
  Summary:

  # Set colors only for components that don't have one yet
  flow_system.topology.set_component_colors('turbo', overwrite=False)

  # With dict - skips components that already have colors
  flow_system.topology.set_component_colors({
      'Boiler': 'red',    # Skipped if Boiler already has a color
      'CHP': 'blue',      # Skipped if CHP already has a color
  }, overwrite=False)

  Returns only the colors that were actually assigned, so you can see what changed.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 21, 2026

📝 Walkthrough

Walkthrough

This PR extends component constructors with an optional color parameter and introduces topology-based color management APIs (set_component_color, set_component_colors, set_carrier_color) to replace the prior colors accessor. It refactors color resolution logic in the plotting pipeline and updates documentation accordingly.

Changes

Cohort / File(s) Summary
Documentation
CHANGELOG.md, docs/user-guide/results-plotting.md
Documents new color parameter support in component constructors and replaces color accessor references with topology-based API examples (set_component_colors, set_component_color, set_carrier_color). Updates persistence path from loaded.colors to loaded.topology.component_colors.
Component Color Parameters
flixopt/components.py
Adds color: str | None = None parameter to constructors of LinearConverter, Storage, Transmission, Source, Sink, and SourceAndSink; all forward color to super().init.
Linear Converter Color Parameters
flixopt/linear_converters.py
Adds color: str | None = None parameter to Boiler, Power2Heat, HeatPump, CoolingTower, CHP, and HeatPumpWithSource constructors; all propagate color via super().init to LinearConverter.
Topology Color Management API
flixopt/topology_accessor.py
Introduces new public methods: _invalidate_color_caches(), set_component_color(label, color), set_component_colors(colors dict/str, overwrite), set_carrier_color(carrier, color). Supports bulk assignment with colorscale normalization and cache invalidation.
Color Resolution Refactoring
flixopt/statistics_accessor.py
Refactors SankeyPlotAccessor._get_node_colors to separately resolve bus_colors and component_colors; applies fallback color computation only to uncolored nodes instead of globally.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Poem

🐰 A rainbow of components, now dressed in their finest hue,
Colors set at creation, or topology's avenue,
From Boiler's warm orange to Storage's cool green,
The prettiest flow diagrams you've ever seen! ✨🎨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding a color parameter to components and bulk color assignment methods via the topology accessor.
Description check ✅ Passed The PR description comprehensively covers the changes with clear sections on what was added, code examples, type of change, and testing status. It aligns well with the template structure.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

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.

…nctionality:

  def set_component_colors(
      self,
      colors: dict[str, str | list[str]] | str,
      overwrite: bool = True,
  ) -> dict[str, str]:
      components = self._fs.components

      # Normalize to {label: color} mapping
      if isinstance(colors, str):
          color_map = process_colors(colors, list(components.keys()))
      else:
          color_map = {}
          for key, value in colors.items():
              if isinstance(value, list):
                  missing = [c for c in value if c not in components]
                  if missing:
                      raise KeyError(f"Components not found: {missing}")
                  color_map.update(process_colors(key, value))
              else:
                  if key not in components:
                      raise KeyError(f"Component '{key}' not found")
                  color_map[key] = value

      # Apply colors (respecting overwrite flag)
      result = {}
      for label, color in color_map.items():
          if overwrite or components[label].color is None:
              components[label].color = color
              result[label] = color

      self._invalidate_color_caches()
      return result

  Key improvements:
  - Normalize all inputs to a {label: color} dict first
  - Single pass to apply colors
  - Cleaner error messages
  - Shorter docstring with inline examples
@FBumann FBumann changed the title Feature/colors Add color parameter to components and bulk color assignment via topology accessor Jan 21, 2026
@FBumann
Copy link
Member Author

FBumann commented Jan 21, 2026

coderabbitai review

@FBumann FBumann marked this pull request as ready for review January 21, 2026 14:59
Copy link
Contributor

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
flixopt/components.py (1)

1703-1718: Missing color parameter in SourceAndSink for API consistency.

All other component classes (LinearConverter, Storage, Transmission, Source, Sink) now accept a color parameter, but SourceAndSink does not. For a consistent API surface, consider adding the color parameter here as well.

Suggested fix
 def __init__(
     self,
     label: str,
     inputs: list[Flow] | None = None,
     outputs: list[Flow] | None = None,
     prevent_simultaneous_flow_rates: bool = True,
     meta_data: dict | None = None,
+    color: str | None = None,
 ):
     super().__init__(
         label,
         inputs=inputs,
         outputs=outputs,
         prevent_simultaneous_flows=(inputs or []) + (outputs or []) if prevent_simultaneous_flow_rates else None,
         meta_data=meta_data,
+        color=color,
     )
     self.prevent_simultaneous_flow_rates = prevent_simultaneous_flow_rates
🧹 Nitpick comments (1)
flixopt/linear_converters.py (1)

615-633: LGTM! Color parameter correctly added to HeatPumpWithSource.

Completes the consistent addition of the color parameter across all LinearConverter subclasses.

Optional: The class docstrings for Boiler, Power2Heat, HeatPump, CoolingTower, CHP, and HeatPumpWithSource could be updated to document the new color parameter in their Args sections. However, since the parameter is inherited from the base class and the behavior is documented in the user guide, this is a nice-to-have improvement.

@FBumann FBumann merged commit f766121 into main Jan 21, 2026
9 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