Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
176 commits
Select commit Hold shift + click to select a range
cc7de38
Feature/398 feature facet plots in results (#419)
FBumann Oct 18, 2025
fedd6b6
Feature/398 feature facet plots in results heatmaps (#418)
FBumann Oct 18, 2025
84aa03d
Feature/398 feature facet plots in results charge state (#417)
FBumann Oct 18, 2025
51da844
Fix Error handling in plot_heatmap()
FBumann Oct 18, 2025
b94f223
Feature/398 feature facet plots in results pie (#421)
FBumann Oct 18, 2025
b2b8eb7
6. Optimized time-step check
FBumann Oct 18, 2025
c747faf
Typo
FBumann Oct 18, 2025
bf4e33d
Improve type handling
FBumann Oct 18, 2025
0c5764c
Update other tests
FBumann Oct 18, 2025
59ada64
Handle backwards compatability
FBumann Oct 18, 2025
b56ed12
Add better error messages if both new and old api are used
FBumann Oct 18, 2025
980d7de
Add old api explicitly
FBumann Oct 18, 2025
9aea60e
Add old api explicitly
FBumann Oct 18, 2025
922a95f
Improve consistency and properly deprectae the indexer parameter
FBumann Oct 18, 2025
bd88fb1
Remove amount of new tests
FBumann Oct 18, 2025
f156d3a
Remove amount of new tests
FBumann Oct 18, 2025
ab9e4a8
Fix CONTRIBUTING.md
FBumann Oct 18, 2025
a77b942
Remove old test file
FBumann Oct 18, 2025
18ba271
Add tests/test_heatmap_reshape.py
FBumann Oct 18, 2025
894533c
Add tests/test_heatmap_reshape.py
FBumann Oct 18, 2025
30ab7ec
Remove unused method
FBumann Oct 18, 2025
4763c29
- Implemented dashed line styling for "mixed" variables (variables …
FBumann Oct 18, 2025
e180e88
- Added fill parameter to module-level plot_heatmap function (line …
FBumann Oct 18, 2025
9c3c580
- Added np.random.seed(42) for reproducible test results
FBumann Oct 18, 2025
5938829
Improve Error Message if too many dims for matplotlib
FBumann Oct 18, 2025
33cd72a
Improve Error Message if too many dims for matplotlib
FBumann Oct 18, 2025
505edca
Improve Error Message if too many dims for matplotlib
FBumann Oct 18, 2025
33c4bec
Rename _apply_indexer_to_data() to _apply_selection_to_data()
FBumann Oct 19, 2025
b37dc6a
Bugfix
FBumann Oct 19, 2025
9ce25ab
Update CHANGELOG.md
FBumann Oct 19, 2025
bbad6cb
Catch edge case in with_plotly()
FBumann Oct 19, 2025
92d0590
Add strict=True
FBumann Oct 19, 2025
ae05346
Improve scenario_example.py
FBumann Oct 19, 2025
904be27
Improve scenario_example.py
FBumann Oct 19, 2025
2c8bd7f
Change logging level in essage about time reshape
FBumann Oct 19, 2025
55dfde9
Update CHANGELOG.md
FBumann Oct 19, 2025
770615c
Add XarrayColorMapper
FBumann Oct 19, 2025
f1a395f
Add XarrayColorMapper to CalculationResults
FBumann Oct 19, 2025
00010af
Renamed variable
FBumann Oct 19, 2025
0e42a17
Add test file
FBumann Oct 19, 2025
2aeecd8
Improve integration of the ColorMapper
FBumann Oct 19, 2025
3c1a9c0
Improve integration of the ColorMapper
FBumann Oct 19, 2025
8c2c933
Update resolve_colors and move to plotting.py
FBumann Oct 19, 2025
0644e9f
Temporalily add example script to show/document intended usage
FBumann Oct 19, 2025
78e1894
Add method create_color_mapper
FBumann Oct 19, 2025
3d4788a
Improve docstring
FBumann Oct 19, 2025
60c44a9
Remove example file again
FBumann Oct 19, 2025
a269ed7
Update CHANGELOG.md
FBumann Oct 19, 2025
c4a675c
Add create_color_mapper to SegmentedResults
FBumann Oct 19, 2025
60bc43b
Add create_color_mapper to complex_example
FBumann Oct 19, 2025
f5cc7ab
Missed some renames
FBumann Oct 19, 2025
601f849
Fix warning in plot_charge_state()
FBumann Oct 19, 2025
9ad5c24
Allow for discrete color assignments with rules
FBumann Oct 19, 2025
ced84d4
Remove some half baked validation
FBumann Oct 19, 2025
7ac3781
Add more color families
FBumann Oct 19, 2025
483b8df
Use 1:7 colors for more distinct colors
FBumann Oct 19, 2025
6a5293c
Add color mapper to complex example
FBumann Oct 19, 2025
2589819
Update CHANGELOG.md
FBumann Oct 19, 2025
b83fc4e
Merge remote-tracking branch 'origin/main' into feature/plotting-colors
FBumann Oct 19, 2025
26d27b6
Convert numpy style docstrings to google style
FBumann Oct 19, 2025
78c59d1
Use re.search instead of re.match
FBumann Oct 19, 2025
f6b31fb
Update tests
FBumann Oct 20, 2025
567c6a0
Applying ordering to Dataset as well
FBumann Oct 19, 2025
35b6259
This approach:
FBumann Oct 19, 2025
e4c104e
Improve Error Message
FBumann Oct 20, 2025
565ef26
Enable sorting fpr Datasets
FBumann Oct 20, 2025
211a743
completed the integration of XarrayColorMapper into both with_plotly …
FBumann Oct 20, 2025
8033aed
simplified with_matplotlib significantly
FBumann Oct 20, 2025
1017238
Update plotting methods to focus on xr.DataArray only
FBumann Oct 20, 2025
329876e
Remove duplication
FBumann Oct 20, 2025
a536809
Remove duplication
FBumann Oct 20, 2025
5972ffe
Make check faster
FBumann Oct 20, 2025
67672ec
Make check faster
FBumann Oct 20, 2025
0c2bac4
Make check faster
FBumann Oct 20, 2025
d26ed42
Fixx plotting issues
FBumann Oct 20, 2025
aad4fb4
Switch back to Dataset first
FBumann Oct 20, 2025
83c1b1d
Remove redundant code
FBumann Oct 20, 2025
e275f4e
XarrayColorMapper is now Dataset-only!
FBumann Oct 20, 2025
7623285
Update tests accordingly
FBumann Oct 20, 2025
5d8d83d
Fix issue in aggregation.py with new plotting
FBumann Oct 21, 2025
fc81107
Fix issue plotting in examples (using dataframes)
FBumann Oct 21, 2025
6a7b639
Fix issue plotting in examples (using dataframes)
FBumann Oct 21, 2025
5b40a2a
Fix issue plotting scalar Datasets
FBumann Oct 21, 2025
988aa10
Improve labeling of plots
FBumann Oct 21, 2025
0e5baf0
Improve handling of time reshape in plots
FBumann Oct 21, 2025
764b1c2
Update usage of plotting methods
FBumann Oct 21, 2025
e9bbe11
Update pie plots to use Dataset instead of DataFrame
FBumann Oct 21, 2025
53c1259
Makde charge state line in plots black always
FBumann Oct 21, 2025
a0d958b
Improve examples
FBumann Oct 21, 2025
ee3b528
Make plotting methods much more flexible
FBumann Oct 21, 2025
695d259
Add test
FBumann Oct 21, 2025
790c0fc
Add plotting kwargs to plotting functions
FBumann Oct 21, 2025
0249d60
add imshow kwargs
FBumann Oct 21, 2025
a207242
Fix nans in plots
FBumann Oct 21, 2025
e4c5a46
Replace XarrayColorMapper with ComponentColorManager
FBumann Oct 21, 2025
a583240
Add repr and str method
FBumann Oct 21, 2025
f9c28e5
Added tests
FBumann Oct 21, 2025
7f6d875
Add caching to ColorManager
FBumann Oct 21, 2025
6e6997f
Test caching
FBumann Oct 21, 2025
9f8fa1c
Change default colormap and improve colormap settings
FBumann Oct 21, 2025
7b436f1
Automatically initiallize the ColorManager
FBumann Oct 21, 2025
7a8933e
Use Dark24 as the default colormap
FBumann Oct 21, 2025
1861e69
Rename auto_group_components() to apply_colors()
FBumann Oct 21, 2025
695228c
Use ColorManager in examples
FBumann Oct 21, 2025
66185d3
Fix tests
FBumann Oct 21, 2025
97c1b85
Extend config to cover plotting settings
FBumann Oct 21, 2025
d9606be
Centralize behaviour
FBumann Oct 21, 2025
606e81b
More config options
FBumann Oct 21, 2025
54f2d1b
More config options
FBumann Oct 21, 2025
fbe491a
More config options
FBumann Oct 21, 2025
46ed8ca
Rename config parameter
FBumann Oct 21, 2025
0211ef9
Improve color defaults
FBumann Oct 21, 2025
1e72171
Removed 'auto' and Simplified Color Resolution
FBumann Oct 21, 2025
c0c792f
Fix ColorProcessor to accept qualitative colorscales
FBumann Oct 21, 2025
6612157
Fix ColorProcessor to accept qualitative colorscales
FBumann Oct 21, 2025
6bcee9c
Remove old test
FBumann Oct 21, 2025
cd650a0
Simplified tests
FBumann Oct 21, 2025
009e740
Update examples and CHANGELOG.md
FBumann Oct 21, 2025
07fbad8
Update method name
FBumann Oct 21, 2025
d95056e
Update examples
FBumann Oct 21, 2025
eb6b996
extended ComponentColorManager to support flow-level color distinctio
FBumann Oct 21, 2025
a56d207
Change default flow shading
FBumann Oct 21, 2025
043e408
Improve Setup_colors
FBumann Oct 22, 2025
97c5c19
Use external dependency for color handling
FBumann Oct 22, 2025
f20652f
Make colour dependency optional
FBumann Oct 22, 2025
4092a73
streamlined the ColorManager configuration API
FBumann Oct 22, 2025
1ea66e4
streamlined the ColorManager configuration API
FBumann Oct 22, 2025
a5f43a5
Update usages of new api
FBumann Oct 22, 2025
cd5146e
Merge remote-tracking branch 'refs/remotes/origin/main' into feature/…
FBumann Oct 22, 2025
5e6e628
Update CHANGELOG.md
FBumann Oct 22, 2025
8592e07
Update examples
FBumann Oct 22, 2025
5ea9bf4
use turbo as the new default sequential colormap
FBumann Oct 22, 2025
93bd4fb
Add support for direct mappings of components
FBumann Oct 22, 2025
684e0c8
Add support for direct mappings of components
FBumann Oct 22, 2025
43a9196
Add configurable flow_variation
FBumann Oct 22, 2025
837f70a
Update tests
FBumann Oct 22, 2025
4c58cbb
Make color getter mroe robust
FBumann Oct 22, 2025
cf97881
Make color getter mroe robust
FBumann Oct 22, 2025
2836aa2
Temp
FBumann Oct 22, 2025
c634da7
Update default colormap
FBumann Oct 22, 2025
d109bf8
Update default colormap to default colorscale
FBumann Oct 22, 2025
1bbee1b
Update default Improve colorscale handling
FBumann Oct 22, 2025
c921859
Update default color families
FBumann Oct 22, 2025
e455c6f
Update plotly template
FBumann Oct 22, 2025
1192caa
Update example
FBumann Oct 22, 2025
617b77f
Simplify test
FBumann Oct 22, 2025
e1ac8a0
Update color family defaults
FBumann Oct 22, 2025
6cf8851
Simplify documentation
FBumann Oct 22, 2025
f8bcf60
Typo
FBumann Oct 22, 2025
b4ef8c2
Make matplotlib backend switch more robst
FBumann Oct 22, 2025
f52eae0
Update setup_colors() in SegmentedCalculationResults
FBumann Oct 22, 2025
ab2957e
Fix example
FBumann Oct 22, 2025
5c0e398
Update CHANGELOG.md
FBumann Oct 22, 2025
c583c42
Simplify export_figure()
FBumann Oct 22, 2025
0d2b8ae
Merge remote-tracking branch 'origin/main' into feature/plotting-colors
FBumann Oct 22, 2025
67cb5a1
Update Examples and CHANGELOG.md
FBumann Oct 22, 2025
a01a7e2
Simplified Config
FBumann Oct 23, 2025
c636bd9
Simplified Colormanagement
FBumann Oct 23, 2025
f7ee19f
Simplified Colormanagement
FBumann Oct 23, 2025
950f8e0
Simplified Colormanagement
FBumann Oct 23, 2025
31a3cc6
Add element name itself to color dict
FBumann Oct 23, 2025
87608b0
Fix examples
FBumann Oct 23, 2025
c958c4c
Bugfix
FBumann Oct 23, 2025
309ecfa
Bugfix
FBumann Oct 23, 2025
09ddf80
Remove coloring related stuff
FBumann Oct 23, 2025
2921ff3
Reverse color and CONFIG related changes in plotting.py
FBumann Oct 23, 2025
b4584d4
Reverse color and CONFIG related changes in plotting.py
FBumann Oct 23, 2025
ac62b87
Reverse color and CONFIG related changes in plotting.py
FBumann Oct 23, 2025
a96fd80
Reverse color and CONFIG related changes in plotting.py
FBumann Oct 23, 2025
3793fbe
Reverse color and CONFIG related changes in plotting.py
FBumann Oct 23, 2025
407aa79
Update CHANGELOG.md
FBumann Oct 23, 2025
33bcd3b
Update CHANGELOG.md
FBumann Oct 23, 2025
8274162
Remove duplicate resolve color calls
FBumann Oct 23, 2025
34b9a75
Improve pie plot
FBumann Oct 23, 2025
2e06d44
Simplify pie plot
FBumann Oct 23, 2025
0d857f0
Simplify pie plot
FBumann Oct 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,16 @@ If upgrading from v2.x, see the [v3.0.0 release notes](https://github.com/flixOp
### 💥 Breaking Changes

### ♻️ Changed
- **Template integration**: Plotly templates now fully control plot styling without hardcoded overrides
- **Dataset first plotting**: Underlying plotting methods in plotting.py now use `xr.Dataset` as the main datatype, converting to it if they get a DataFrame passed

### 🗑️ Deprecated

### 🔥 Removed

### 🐛 Fixed
- Improved error messages for matplotlib with multidimensional data
- Better dimension validation in `plot_heatmap()`

### 🔒 Security

Expand Down
5 changes: 3 additions & 2 deletions examples/02_Complex/complex_example_results.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@
# --- Detailed Plots ---
# In depth plot for individual flow rates ('__' is used as the delimiter between Component and Flow
results.plot_heatmap('Wärmelast(Q_th_Last)|flow_rate')
for flow_rate in results['BHKW2'].inputs + results['BHKW2'].outputs:
results.plot_heatmap(flow_rate)
for bus in results.buses.values():
bus.plot_node_balance_pie()
bus.plot_node_balance()

# --- Plotting internal variables manually ---
results.plot_heatmap('BHKW2(Q_th)|on')
Expand Down
10 changes: 5 additions & 5 deletions examples/03_Calculation_types/example_calculation_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,35 +202,35 @@ def get_solutions(calcs: list, variable: str) -> xr.Dataset:

# --- Plotting for comparison ---
fx.plotting.with_plotly(
get_solutions(calculations, 'Speicher|charge_state').to_dataframe(),
get_solutions(calculations, 'Speicher|charge_state'),
mode='line',
title='Charge State Comparison',
ylabel='Charge state',
).write_html('results/Charge State.html')

fx.plotting.with_plotly(
get_solutions(calculations, 'BHKW2(Q_th)|flow_rate').to_dataframe(),
get_solutions(calculations, 'BHKW2(Q_th)|flow_rate'),
mode='line',
title='BHKW2(Q_th) Flow Rate Comparison',
ylabel='Flow rate',
).write_html('results/BHKW2 Thermal Power.html')

fx.plotting.with_plotly(
get_solutions(calculations, 'costs(temporal)|per_timestep').to_dataframe(),
get_solutions(calculations, 'costs(temporal)|per_timestep'),
mode='line',
title='Operation Cost Comparison',
ylabel='Costs [€]',
).write_html('results/Operation Costs.html')

fx.plotting.with_plotly(
pd.DataFrame(get_solutions(calculations, 'costs(temporal)|per_timestep').to_dataframe().sum()).T,
get_solutions(calculations, 'costs(temporal)|per_timestep').sum('time'),
mode='stacked_bar',
title='Total Cost Comparison',
ylabel='Costs [€]',
).update_layout(barmode='group').write_html('results/Total Costs.html')

fx.plotting.with_plotly(
pd.DataFrame([calc.durations for calc in calculations], index=[calc.name for calc in calculations]),
pd.DataFrame([calc.durations for calc in calculations], index=[calc.name for calc in calculations]).to_xarray(),
mode='stacked_bar',
).update_layout(title='Duration Comparison', xaxis_title='Calculation type', yaxis_title='Time (s)').write_html(
'results/Speed Comparison.html'
Expand Down
6 changes: 4 additions & 2 deletions flixopt/aggregation.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,12 @@ def plot(self, colormap: str = 'viridis', show: bool = True, save: pathlib.Path
df_agg = self.aggregated_data.copy().rename(
columns={col: f'Aggregated - {col}' for col in self.aggregated_data.columns}
)
fig = plotting.with_plotly(df_org, 'line', colors=colormap)
fig = plotting.with_plotly(df_org.to_xarray(), 'line', colors=colormap, xlabel='Time in h')
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify DataFrame index structure for xarray conversion.

The explicit to_xarray() calls convert pandas DataFrames to xarray Datasets before passing them to plotting.with_plotly. Since with_plotly accepts both xr.Dataset | pd.DataFrame and has internal conversion logic, ensure that:

  1. The DataFrame index (from self.original_data and self.aggregated_data) is properly named (e.g., 'time') for correct xarray dimension naming.
  2. The explicit conversion produces the expected Dataset structure that with_plotly requires, or clarify whether the internal conversion in with_plotly would handle DataFrames differently.

Run the following script to verify the DataFrame structure and resulting xarray conversion:

Also applies to: 156-156


🏁 Script executed:

#!/bin/bash
# Description: Check the DataFrame creation and structure of original_data and aggregated_data

# Search for where original_data and aggregated_data are created/assigned
rg -n -B3 -A3 'self\.original_data\s*=' --type=py

# Search for where these DataFrames are populated or transformed
rg -n -B3 -A3 'self\.aggregated_data\s*=' --type=py

# Check if there are any index naming operations on these DataFrames
rg -n -B2 -A2 '\.index\.name\s*=' --type=py -g 'aggregation.py'

Length of output: 1032


🏁 Script executed:

#!/bin/bash
# Check the __init__ method signature and type hints
rg -n -B2 -A15 'def __init__' flixopt/aggregation.py | head -40

# Check imports to understand tsam
rg -n 'import.*tsam|from.*tsam' flixopt/aggregation.py

# Check the plotting.with_plotly function signature and implementation
rg -n -B2 -A20 'def with_plotly' flixopt/plotting.py

# Check if DataFrame index is being set anywhere in the plot method
rg -n -B5 -A5 'def plot' flixopt/aggregation.py | head -60

Length of output: 248


🏁 Script executed:

#!/bin/bash
# Check the __init__ method signature and type hints
rg -n -B2 -A15 'def __init__' flixopt/aggregation.py | head -50

# Check imports to understand tsam
rg -n 'import.*tsam|from.*tsam' flixopt/aggregation.py

# Check the plotting.with_plotly function signature and implementation
rg -n -B2 -A25 'def with_plotly' flixopt/plotting.py

# Check if DataFrame index is being set anywhere
rg -n '\.index\.name' flixopt/aggregation.py

Length of output: 3063


🏁 Script executed:

#!/bin/bash
# Get the full plot method implementation around lines 144-173
rg -n -B5 -A30 'def plot' flixopt/aggregation.py | grep -A 35 'def plot'

# Check with_plotly's internal conversion logic (_ensure_dataset)
rg -n -B2 -A15 '_ensure_dataset' flixopt/plotting.py

# Check if the plot method creates dataframes and how
rg -n 'df_org\|df_agg' flixopt/aggregation.py

# Check the Aggregation class to see data structure
ast-grep --pattern 'class Aggregation { $$$ }'

Length of output: 5776


Remove redundant explicit .to_xarray() calls — pass DataFrames directly to with_plotly.

The explicit .to_xarray() conversions at lines 153 and 156 are unnecessary. The with_plotly function already handles DataFrame-to-Dataset conversion internally via _ensure_dataset() (line 473 in plotting.py), which calls .to_xarray() on DataFrames automatically. Passing DataFrames directly simplifies the code without changing behavior:

fig = plotting.with_plotly(df_org, 'line', colors=colormap, xlabel='Time in h')

instead of:

fig = plotting.with_plotly(df_org.to_xarray(), 'line', colors=colormap, xlabel='Time in h')

Apply this change to both lines 153 and 156.

🤖 Prompt for AI Agents
In flixopt/aggregation.py around lines 153 and 156, remove the redundant
`.to_xarray()` calls and pass the pandas DataFrame objects directly into
plotting.with_plotly (e.g., replace `plotting.with_plotly(df_org.to_xarray(),
...)` with `plotting.with_plotly(df_org, ...)` for both occurrences); ensure
function arguments and variable names remain unchanged and run tests/linters to
confirm no type issues.

for trace in fig.data:
trace.update(dict(line=dict(dash='dash')))
fig = plotting.with_plotly(df_agg, 'line', colors=colormap, fig=fig)
fig2 = plotting.with_plotly(df_agg.to_xarray(), 'line', colors=colormap, xlabel='Time in h')
for trace in fig2.data:
fig.add_trace(trace)

fig.update_layout(
title='Original vs Aggregated Data (original = ---)', xaxis_title='Index', yaxis_title='Value'
Expand Down
Loading
Loading