Skip to content

Commit f0f6233

Browse files
committed
fixed docs and linting
1 parent 0bd0686 commit f0f6233

File tree

2 files changed

+82
-104
lines changed

2 files changed

+82
-104
lines changed

docs/conf.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,17 @@ def get_latest_git_tag():
7575
# -- Options for HTML output ------
7676
html_theme = "furo"
7777

78-
# Configure JavaScript files for Plotly support
79-
html_js_files = [
80-
"require.min.js",
81-
"custom.js",
82-
]
78+
nbsphinx_prolog = r"""
79+
.. raw:: html
80+
81+
<script src='https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js'></script>
82+
<script src='https://cdn.plot.ly/plotly-2.27.0.min.js'></script>
83+
<script>
84+
require.config({
85+
paths: {
86+
'plotly': 'https://cdn.plot.ly/plotly-2.27.0.min.js'
87+
}
88+
});
89+
</script>
90+
91+
"""

vessim/plot.py

Lines changed: 68 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def plot_trace(
1515
default_visible: Optional[str] = None,
1616
scale: Optional[float] = None,
1717
y_axis_title: Optional[str] = None,
18-
dataset_name: Optional[str] = None
18+
dataset_name: Optional[str] = None,
1919
) -> Figure:
2020
"""Plot a Vessim Trace using Plotly.
2121
@@ -60,22 +60,15 @@ def plot_trace(
6060
go.Scatter(
6161
x=df.index,
6262
y=df[column_name],
63-
name=column_name if len(df.columns) == 1 else "Carbon Intensity"
63+
name=column_name if len(df.columns) == 1 else "Carbon Intensity",
6464
)
6565
)
6666
showlegend = False
6767
else:
6868
# Multi-column datasets (like solar data)
6969
for col in df.columns:
7070
visible = True if col == default_visible else "legendonly"
71-
fig.add_trace(
72-
go.Scatter(
73-
x=df.index,
74-
y=df[col],
75-
visible=visible,
76-
name=col
77-
)
78-
)
71+
fig.add_trace(go.Scatter(x=df.index, y=df[col], visible=visible, name=col))
7972
showlegend = True
8073

8174
# Update layout
@@ -84,9 +77,9 @@ def plot_trace(
8477
xaxis_title="Date",
8578
yaxis_title=y_axis_title,
8679
showlegend=showlegend,
87-
hovermode='x unified' if len(df.columns) > 1 else 'x',
80+
hovermode="x unified" if len(df.columns) > 1 else "x",
8881
margin={"l": 0, "t": 40, "b": 0, "r": 0},
89-
autosize=True
82+
autosize=True,
9083
)
9184

9285
return fig
@@ -98,10 +91,9 @@ def plot_microgrid_trace(
9891
actors: Optional[List[str]] = None,
9992
include_system_power: bool = True,
10093
include_storage: bool = True,
101-
title: Optional[str] = None,
102-
height: int = 800,
94+
height: int = 600,
10395
actor_colors: Optional[dict] = None,
104-
layout: str = "detailed"
96+
layout: str = "detailed",
10597
) -> Figure:
10698
"""Plot microgrid trace with actors, system power, and battery state.
10799
@@ -114,7 +106,6 @@ def plot_microgrid_trace(
114106
actors: List of actor names to plot. If None, auto-detects from columns ending in '.p'
115107
include_system_power: Whether to include the system power (p_delta, p_grid)
116108
include_storage: Whether to include the storage subplot (storage.soc)
117-
title: Overall plot title. If None, uses auto-generated title
118109
height: Total plot height in pixels
119110
actor_colors: Dict mapping actor names to colors. If None, uses default Plotly colors
120111
layout: "detailed" for 3 subplots, "overview" for 2 subplots (default: "detailed")
@@ -137,40 +128,38 @@ def plot_microgrid_trace(
137128
"""
138129
# Auto-detect actors if not specified
139130
if actors is None:
140-
actors = [col.replace('.p', '') for col in df.columns if col.endswith('.p')]
131+
actors = [col.replace(".p", "") for col in df.columns if col.endswith(".p")]
141132

142133
# Handle layout options
143134
if layout == "overview":
144135
# Use overview layout: combine actors and system power in one subplot
145-
has_storage = include_storage and 'storage.soc' in df.columns
136+
has_storage = include_storage and "storage.soc" in df.columns
146137
subplot_count = 2 if has_storage else 1
147-
138+
148139
subplot_titles = ["Power Overview"]
149140
if has_storage:
150141
subplot_titles.append("Battery State of Charge")
151-
142+
152143
row_heights = [0.67, 0.33] if subplot_count == 2 else [1.0]
153-
144+
154145
else: # detailed layout
155146
# Determine subplot configuration - separate subplots
156147
subplot_count = 1 # Always include actors
157148
if include_system_power:
158149
subplot_count += 1
159-
if include_storage and 'storage.soc' in df.columns:
150+
if include_storage and "storage.soc" in df.columns:
160151
subplot_count += 1
161152

162153
# Create subplot titles
163154
subplot_titles = ["Actor Power"]
164155
if include_system_power:
165156
subplot_titles.append("System Power")
166-
if include_storage and 'storage.soc' in df.columns:
157+
if include_storage and "storage.soc" in df.columns:
167158
subplot_titles.append("Battery State of Charge")
168159

169160
# Calculate height ratios - give more space to actors plot
170161
row_heights = (
171-
[0.5] + [0.5 / (subplot_count - 1)] * (subplot_count - 1)
172-
if subplot_count > 1
173-
else [1]
162+
[0.5] + [0.5 / (subplot_count - 1)] * (subplot_count - 1) if subplot_count > 1 else [1]
174163
)
175164

176165
# Create subplots
@@ -180,18 +169,18 @@ def plot_microgrid_trace(
180169
shared_xaxes=True,
181170
subplot_titles=subplot_titles,
182171
row_heights=row_heights,
183-
vertical_spacing=0.08
172+
vertical_spacing=0.08,
184173
)
185174

186175
# Define default colors for common actor types
187176
default_colors = {
188-
'server': '#d62728', # red
189-
'solar_panel': '#ff7f0e', # orange
190-
'solar': '#ff7f0e', # orange
191-
'wind': '#2ca02c', # green
192-
'storage': '#9467bd', # purple
193-
'load': '#8c564b', # brown
194-
'battery': '#9467bd', # purple
177+
"server": "#d62728", # red
178+
"solar_panel": "#ff7f0e", # orange
179+
"solar": "#ff7f0e", # orange
180+
"wind": "#2ca02c", # green
181+
"storage": "#9467bd", # purple
182+
"load": "#8c564b", # brown
183+
"battery": "#9467bd", # purple
195184
}
196185

197186
current_row = 1
@@ -210,12 +199,12 @@ def plot_microgrid_trace(
210199
color = default_colors[actor]
211200

212201
# Create display name
213-
display_name = actor.replace('_', ' ').title()
202+
display_name = actor.replace("_", " ").title()
214203
if layout == "overview":
215204
# Match notebook naming
216-
if 'server' in actor.lower():
205+
if "server" in actor.lower():
217206
display_name = f"{display_name} power"
218-
elif 'solar' in actor.lower():
207+
elif "solar" in actor.lower():
219208
display_name = f"{display_name} power"
220209

221210
fig.add_trace(
@@ -224,146 +213,128 @@ def plot_microgrid_trace(
224213
y=df[actor_col],
225214
name=display_name,
226215
line=dict(color=color) if color else {},
227-
hovertemplate=f"{actor}: %{{y:.1f}} W<extra></extra>"
216+
hovertemplate=f"{actor}: %{{y:.1f}} W<extra></extra>",
228217
),
229218
row=current_row,
230-
col=1
219+
col=1,
231220
)
232221

233222
# Add system power to first subplot if overview layout
234223
if layout == "overview" and include_system_power:
235-
if 'p_delta' in df.columns:
224+
if "p_delta" in df.columns:
236225
fig.add_trace(
237226
go.Scatter(
238-
x=df.index,
239-
y=df['p_delta'],
240-
name="Delta power",
241-
line=dict(color='gray')
227+
x=df.index, y=df["p_delta"], name="Delta power", line=dict(color="gray")
242228
),
243229
row=current_row,
244-
col=1
230+
col=1,
245231
)
246-
247-
if 'p_grid' in df.columns:
232+
233+
if "p_grid" in df.columns:
248234
fig.add_trace(
249-
go.Scatter(
250-
x=df.index,
251-
y=df['p_grid'],
252-
name="Grid power",
253-
line=dict(color='blue')
254-
),
235+
go.Scatter(x=df.index, y=df["p_grid"], name="Grid power", line=dict(color="blue")),
255236
row=current_row,
256-
col=1
237+
col=1,
257238
)
258239

259240
# Format first subplot
260241
fig.update_yaxes(title_text="Power (W)", row=current_row, col=1)
261242
fig.update_xaxes(
262-
showgrid=True, gridwidth=1, gridcolor='rgba(128,128,128,0.3)', row=current_row, col=1
243+
showgrid=True, gridwidth=1, gridcolor="rgba(128,128,128,0.3)", row=current_row, col=1
263244
)
264245
fig.update_yaxes(
265-
showgrid=True, gridwidth=1, gridcolor='rgba(128,128,128,0.3)', row=current_row, col=1
246+
showgrid=True, gridwidth=1, gridcolor="rgba(128,128,128,0.3)", row=current_row, col=1
266247
)
267248

268249
current_row += 1
269250

270251
# 2. System Power Plot (detailed layout only)
271252
if layout == "detailed" and include_system_power and current_row <= subplot_count:
272-
if 'p_delta' in df.columns:
253+
if "p_delta" in df.columns:
273254
fig.add_trace(
274255
go.Scatter(
275256
x=df.index,
276-
y=df['p_delta'],
257+
y=df["p_delta"],
277258
name="Delta Power",
278-
line=dict(color='gray'),
279-
hovertemplate="Delta Power: %{y:.1f} W<extra></extra>"
259+
line=dict(color="gray"),
260+
hovertemplate="Delta Power: %{y:.1f} W<extra></extra>",
280261
),
281262
row=current_row,
282-
col=1
263+
col=1,
283264
)
284265

285-
if 'p_grid' in df.columns:
266+
if "p_grid" in df.columns:
286267
fig.add_trace(
287268
go.Scatter(
288269
x=df.index,
289-
y=df['p_grid'],
270+
y=df["p_grid"],
290271
name="Grid Power",
291-
line=dict(color='blue'),
292-
hovertemplate="Grid Power: %{y:.1f} W<extra></extra>"
272+
line=dict(color="blue"),
273+
hovertemplate="Grid Power: %{y:.1f} W<extra></extra>",
293274
),
294275
row=current_row,
295-
col=1
276+
col=1,
296277
)
297278

298279
fig.update_yaxes(title_text="Power (W)", row=current_row, col=1)
299280
fig.update_xaxes(
300-
showgrid=True, gridwidth=1, gridcolor='rgba(128,128,128,0.3)', row=current_row, col=1
281+
showgrid=True, gridwidth=1, gridcolor="rgba(128,128,128,0.3)", row=current_row, col=1
301282
)
302283
fig.update_yaxes(
303-
showgrid=True, gridwidth=1, gridcolor='rgba(128,128,128,0.3)', row=current_row, col=1
284+
showgrid=True, gridwidth=1, gridcolor="rgba(128,128,128,0.3)", row=current_row, col=1
304285
)
305286

306287
current_row += 1
307288

308289
# 3. Battery State of Charge Plot
309-
if include_storage and 'storage.soc' in df.columns and current_row <= subplot_count:
290+
if include_storage and "storage.soc" in df.columns and current_row <= subplot_count:
310291
# Main SoC trace
311292
fig.add_trace(
312293
go.Scatter(
313294
x=df.index,
314-
y=df['storage.soc'] * 100,
295+
y=df["storage.soc"] * 100,
315296
name="Battery SoC",
316-
line=dict(color='green'),
317-
fill='tonexty' if len(fig.data) == 0 else 'tozeroy',
318-
fillcolor='rgba(0,128,0,0.1)',
319-
hovertemplate="SoC: %{y:.1f}%<extra></extra>"
297+
line=dict(color="green"),
298+
fill="tonexty" if len(fig.data) == 0 else "tozeroy",
299+
fillcolor="rgba(0,128,0,0.1)",
300+
hovertemplate="SoC: %{y:.1f}%<extra></extra>",
320301
),
321302
row=current_row,
322-
col=1
303+
col=1,
323304
)
324305

325306
# Add minimum SoC line if available
326-
if 'storage.min_soc' in df.columns:
327-
min_soc_value = df['storage.min_soc'].iloc[0] * 100
307+
if "storage.min_soc" in df.columns:
308+
min_soc_value = df["storage.min_soc"].iloc[0] * 100
328309
fig.add_hline(
329310
y=min_soc_value,
330311
line_dash="dash",
331312
line_color="gray",
332313
annotation_text=f"Min SoC ({min_soc_value:.0f}%)",
333314
annotation_position="top right",
334315
row=current_row,
335-
col=1
316+
col=1,
336317
)
337318

338319
fig.update_yaxes(title_text="State of Charge (%)", range=[0, 100], row=current_row, col=1)
339320
fig.update_xaxes(
340-
showgrid=True, gridwidth=1, gridcolor='rgba(128,128,128,0.3)', row=current_row, col=1
321+
showgrid=True, gridwidth=1, gridcolor="rgba(128,128,128,0.3)", row=current_row, col=1
341322
)
342323
fig.update_yaxes(
343-
showgrid=True, gridwidth=1, gridcolor='rgba(128,128,128,0.3)', row=current_row, col=1
324+
showgrid=True, gridwidth=1, gridcolor="rgba(128,128,128,0.3)", row=current_row, col=1
344325
)
345326

346-
# Auto-generate title if not provided
347-
if title is None:
348-
if layout == "overview":
349-
title = "Solar vs Grid Power Over 24 Hours" if include_storage else "Power Overview"
350-
else:
351-
title = "Simulation Results"
352-
353327
# Update overall layout
354328
fig.update_layout(
355-
title=title,
356329
height=height,
357-
hovermode='x unified',
330+
hovermode="x unified",
358331
showlegend=True,
359-
legend=dict(
360-
orientation="h",
361-
yanchor="bottom",
362-
y=1.02,
363-
xanchor="right",
364-
x=1
365-
) if layout == "detailed" else None,
366-
margin=dict(l=0, t=60, b=0, r=0) if layout == "overview" else None
332+
legend=(
333+
dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1)
334+
if layout == "detailed"
335+
else None
336+
),
337+
margin=dict(l=0, t=60, b=0, r=0) if layout == "overview" else None,
367338
)
368339

369340
# Format x-axis for bottom subplot only
@@ -372,7 +343,6 @@ def plot_microgrid_trace(
372343
return fig
373344

374345

375-
376346
def _generate_title(dataset_name: str) -> str:
377347
"""Generate a title from dataset name."""
378348
if "solcast2022_global" in dataset_name:
@@ -397,4 +367,3 @@ def _detect_y_axis_title(dataset_name: str, scale: Optional[float] = None) -> st
397367
return "g/kWh"
398368
else:
399369
return "Value"
400-

0 commit comments

Comments
 (0)