flixopt 2.1.0__py3-none-any.whl → 2.2.0b0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of flixopt might be problematic. Click here for more details.
- docs/release-notes/v2.2.0.md +55 -0
- docs/user-guide/Mathematical Notation/Investment.md +115 -0
- flixopt/calculation.py +65 -37
- flixopt/components.py +119 -74
- flixopt/core.py +966 -451
- flixopt/effects.py +269 -65
- flixopt/elements.py +83 -52
- flixopt/features.py +134 -85
- flixopt/flow_system.py +99 -16
- flixopt/interface.py +142 -51
- flixopt/io.py +56 -27
- flixopt/linear_converters.py +3 -3
- flixopt/plotting.py +34 -16
- flixopt/results.py +807 -109
- flixopt/structure.py +64 -10
- flixopt/utils.py +6 -9
- {flixopt-2.1.0.dist-info → flixopt-2.2.0b0.dist-info}/METADATA +1 -1
- {flixopt-2.1.0.dist-info → flixopt-2.2.0b0.dist-info}/RECORD +21 -20
- {flixopt-2.1.0.dist-info → flixopt-2.2.0b0.dist-info}/WHEEL +1 -1
- {flixopt-2.1.0.dist-info → flixopt-2.2.0b0.dist-info}/top_level.txt +0 -1
- site/release-notes/_template.txt +0 -32
- {flixopt-2.1.0.dist-info → flixopt-2.2.0b0.dist-info}/licenses/LICENSE +0 -0
flixopt/linear_converters.py
CHANGED
|
@@ -165,7 +165,7 @@ class CoolingTower(LinearConverter):
|
|
|
165
165
|
label,
|
|
166
166
|
inputs=[P_el, Q_th],
|
|
167
167
|
outputs=[],
|
|
168
|
-
conversion_factors=[{P_el.label: 1, Q_th.label:
|
|
168
|
+
conversion_factors=[{P_el.label: -1, Q_th.label: specific_electricity_demand}],
|
|
169
169
|
on_off_parameters=on_off_parameters,
|
|
170
170
|
meta_data=meta_data,
|
|
171
171
|
)
|
|
@@ -177,12 +177,12 @@ class CoolingTower(LinearConverter):
|
|
|
177
177
|
|
|
178
178
|
@property
|
|
179
179
|
def specific_electricity_demand(self):
|
|
180
|
-
return
|
|
180
|
+
return self.conversion_factors[0][self.Q_th.label]
|
|
181
181
|
|
|
182
182
|
@specific_electricity_demand.setter
|
|
183
183
|
def specific_electricity_demand(self, value):
|
|
184
184
|
check_bounds(value, 'specific_electricity_demand', self.label_full, 0, 1)
|
|
185
|
-
self.conversion_factors[0][self.Q_th.label] =
|
|
185
|
+
self.conversion_factors[0][self.Q_th.label] = value
|
|
186
186
|
|
|
187
187
|
|
|
188
188
|
@register_class_for_io
|
flixopt/plotting.py
CHANGED
|
@@ -209,7 +209,7 @@ class ColorProcessor:
|
|
|
209
209
|
|
|
210
210
|
def with_plotly(
|
|
211
211
|
data: pd.DataFrame,
|
|
212
|
-
|
|
212
|
+
style: Literal['stacked_bar', 'line', 'area', 'grouped_bar'] = 'stacked_bar',
|
|
213
213
|
colors: ColorType = 'viridis',
|
|
214
214
|
title: str = '',
|
|
215
215
|
ylabel: str = '',
|
|
@@ -222,7 +222,7 @@ def with_plotly(
|
|
|
222
222
|
Args:
|
|
223
223
|
data: A DataFrame containing the data to plot, where the index represents time (e.g., hours),
|
|
224
224
|
and each column represents a separate data series.
|
|
225
|
-
|
|
225
|
+
style: The plotting style. Use 'stacked_bar' for stacked bar charts, 'line' for stepped lines,
|
|
226
226
|
or 'area' for stacked area charts.
|
|
227
227
|
colors: Color specification, can be:
|
|
228
228
|
- A string with a colorscale name (e.g., 'viridis', 'plasma')
|
|
@@ -235,7 +235,8 @@ def with_plotly(
|
|
|
235
235
|
Returns:
|
|
236
236
|
A Plotly figure object containing the generated plot.
|
|
237
237
|
"""
|
|
238
|
-
|
|
238
|
+
if style not in ['stacked_bar', 'line', 'area', 'grouped_bar']:
|
|
239
|
+
raise ValueError(f"'style' must be one of {['stacked_bar', 'line', 'area', 'grouped_bar']}")
|
|
239
240
|
if data.empty:
|
|
240
241
|
return go.Figure()
|
|
241
242
|
|
|
@@ -243,23 +244,40 @@ def with_plotly(
|
|
|
243
244
|
|
|
244
245
|
fig = fig if fig is not None else go.Figure()
|
|
245
246
|
|
|
246
|
-
if
|
|
247
|
+
if style == 'stacked_bar':
|
|
247
248
|
for i, column in enumerate(data.columns):
|
|
248
249
|
fig.add_trace(
|
|
249
250
|
go.Bar(
|
|
250
251
|
x=data.index,
|
|
251
252
|
y=data[column],
|
|
252
253
|
name=column,
|
|
253
|
-
marker=dict(color=processed_colors[i]
|
|
254
|
+
marker=dict(color=processed_colors[i],
|
|
255
|
+
line=dict(width=0, color='rgba(0,0,0,0)')), #Transparent line with 0 width
|
|
254
256
|
)
|
|
255
257
|
)
|
|
256
258
|
|
|
257
259
|
fig.update_layout(
|
|
258
|
-
barmode='relative'
|
|
260
|
+
barmode='relative',
|
|
259
261
|
bargap=0, # No space between bars
|
|
260
|
-
bargroupgap=0, # No space between
|
|
262
|
+
bargroupgap=0, # No space between grouped bars
|
|
261
263
|
)
|
|
262
|
-
|
|
264
|
+
if style == 'grouped_bar':
|
|
265
|
+
for i, column in enumerate(data.columns):
|
|
266
|
+
fig.add_trace(
|
|
267
|
+
go.Bar(
|
|
268
|
+
x=data.index,
|
|
269
|
+
y=data[column],
|
|
270
|
+
name=column,
|
|
271
|
+
marker=dict(color=processed_colors[i])
|
|
272
|
+
)
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
fig.update_layout(
|
|
276
|
+
barmode='group',
|
|
277
|
+
bargap=0.2, # No space between bars
|
|
278
|
+
bargroupgap=0, # space between grouped bars
|
|
279
|
+
)
|
|
280
|
+
elif style == 'line':
|
|
263
281
|
for i, column in enumerate(data.columns):
|
|
264
282
|
fig.add_trace(
|
|
265
283
|
go.Scatter(
|
|
@@ -270,7 +288,7 @@ def with_plotly(
|
|
|
270
288
|
line=dict(shape='hv', color=processed_colors[i]),
|
|
271
289
|
)
|
|
272
290
|
)
|
|
273
|
-
elif
|
|
291
|
+
elif style == 'area':
|
|
274
292
|
data = data.copy()
|
|
275
293
|
data[(data > -1e-5) & (data < 1e-5)] = 0 # Preventing issues with plotting
|
|
276
294
|
# Split columns into positive, negative, and mixed categories
|
|
@@ -345,7 +363,7 @@ def with_plotly(
|
|
|
345
363
|
|
|
346
364
|
def with_matplotlib(
|
|
347
365
|
data: pd.DataFrame,
|
|
348
|
-
|
|
366
|
+
style: Literal['stacked_bar', 'line'] = 'stacked_bar',
|
|
349
367
|
colors: ColorType = 'viridis',
|
|
350
368
|
title: str = '',
|
|
351
369
|
ylabel: str = '',
|
|
@@ -360,7 +378,7 @@ def with_matplotlib(
|
|
|
360
378
|
Args:
|
|
361
379
|
data: A DataFrame containing the data to plot. The index should represent time (e.g., hours),
|
|
362
380
|
and each column represents a separate data series.
|
|
363
|
-
|
|
381
|
+
style: Plotting style. Use 'stacked_bar' for stacked bar charts or 'line' for stepped lines.
|
|
364
382
|
colors: Color specification, can be:
|
|
365
383
|
- A string with a colormap name (e.g., 'viridis', 'plasma')
|
|
366
384
|
- A list of color strings (e.g., ['#ff0000', '#00ff00'])
|
|
@@ -376,19 +394,19 @@ def with_matplotlib(
|
|
|
376
394
|
A tuple containing the Matplotlib figure and axes objects used for the plot.
|
|
377
395
|
|
|
378
396
|
Notes:
|
|
379
|
-
- If `
|
|
397
|
+
- If `style` is 'stacked_bar', bars are stacked for both positive and negative values.
|
|
380
398
|
Negative values are stacked separately without extra labels in the legend.
|
|
381
|
-
- If `
|
|
399
|
+
- If `style` is 'line', stepped lines are drawn for each data series.
|
|
382
400
|
- The legend is placed below the plot to accommodate multiple data series.
|
|
383
401
|
"""
|
|
384
|
-
assert
|
|
402
|
+
assert style in ['stacked_bar', 'line'], f"'style' must be one of {['stacked_bar', 'line']} for matplotlib"
|
|
385
403
|
|
|
386
404
|
if fig is None or ax is None:
|
|
387
405
|
fig, ax = plt.subplots(figsize=figsize)
|
|
388
406
|
|
|
389
407
|
processed_colors = ColorProcessor(engine='matplotlib').process_colors(colors, list(data.columns))
|
|
390
408
|
|
|
391
|
-
if
|
|
409
|
+
if style == 'stacked_bar':
|
|
392
410
|
cumulative_positive = np.zeros(len(data))
|
|
393
411
|
cumulative_negative = np.zeros(len(data))
|
|
394
412
|
width = data.index.to_series().diff().dropna().min() # Minimum time difference
|
|
@@ -419,7 +437,7 @@ def with_matplotlib(
|
|
|
419
437
|
)
|
|
420
438
|
cumulative_negative += negative_values.values
|
|
421
439
|
|
|
422
|
-
elif
|
|
440
|
+
elif style == 'line':
|
|
423
441
|
for i, column in enumerate(data.columns):
|
|
424
442
|
ax.step(data.index, data[column], where='post', color=processed_colors[i], label=column)
|
|
425
443
|
|