Skip to content

Commit d0d22ac

Browse files
Merge pull request #175 from festim-dev/improve-plotting-errors
refactored plotting function
2 parents 6a42660 + 608d5de commit d0d22ac

File tree

1 file changed

+95
-74
lines changed

1 file changed

+95
-74
lines changed

src/backend.py

Lines changed: 95 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,77 @@ def make_csv_payload(scopes):
335335
return csv_payload
336336

337337

338+
def make_plot(simulation):
339+
scopes = [block for block in simulation.blocks if isinstance(block, Scope)]
340+
spectra = [block for block in simulation.blocks if isinstance(block, Spectrum)]
341+
print(f"Found {len(scopes)} scopes and {len(spectra)} spectra")
342+
343+
# FIXME right now only the scopes are converted to CSV
344+
# extra work is needed since spectra and scopes don't share the same x axis
345+
csv_payload = make_csv_payload(scopes)
346+
347+
# Share x only if there are only scopes or only spectra
348+
shared_x = len(scopes) * len(spectra) == 0
349+
n_rows = len(scopes) + len(spectra)
350+
351+
if n_rows == 0:
352+
# No scopes or spectra to plot
353+
return jsonify(
354+
{
355+
"success": True,
356+
"plot": "{}",
357+
"html": "<p>No scopes or spectra to display</p>",
358+
"csv_data": csv_payload,
359+
"message": "Pathsim simulation completed successfully",
360+
}
361+
)
362+
363+
absolute_vertical_spacing = 0.05
364+
relative_vertical_spacing = absolute_vertical_spacing / n_rows
365+
fig = make_subplots(
366+
rows=n_rows,
367+
cols=1,
368+
shared_xaxes=shared_x,
369+
subplot_titles=[scope.label for scope in scopes]
370+
+ [spec.label for spec in spectra],
371+
vertical_spacing=relative_vertical_spacing,
372+
)
373+
374+
# make scope plots
375+
for i, scope in enumerate(scopes):
376+
sim_time, data = scope.read()
377+
378+
for p, d in enumerate(data):
379+
lb = scope.labels[p] if p < len(scope.labels) else f"port {p}"
380+
if isinstance(scope, Spectrum):
381+
d = abs(d)
382+
fig.add_trace(
383+
go.Scatter(x=sim_time, y=d, mode="lines", name=lb),
384+
row=i + 1,
385+
col=1,
386+
)
387+
388+
fig.update_xaxes(title_text="Time", row=len(scopes), col=1)
389+
390+
# make spectrum plots
391+
for i, spec in enumerate(spectra):
392+
freq, data = spec.read()
393+
394+
for p, d in enumerate(data):
395+
lb = spec.labels[p] if p < len(spec.labels) else f"port {p}"
396+
d = abs(d)
397+
fig.add_trace(
398+
go.Scatter(x=freq, y=d, mode="lines", name=lb),
399+
row=len(scopes) + i + 1,
400+
col=1,
401+
)
402+
fig.update_xaxes(title_text="Frequency", row=len(scopes) + i + 1, col=1)
403+
404+
fig.update_layout(height=500 * (len(scopes) + len(spectra)), hovermode="x unified")
405+
406+
return fig, csv_payload
407+
408+
338409
# Function to convert graph to pathsim and run simulation
339410
@app.route("/run-pathsim", methods=["POST"])
340411
def run_pathsim():
@@ -354,93 +425,43 @@ def run_pathsim():
354425
my_simulation.run(duration)
355426

356427
# Generate the plot
357-
scopes = [block for block in my_simulation.blocks if isinstance(block, Scope)]
358-
spectra = [
359-
block for block in my_simulation.blocks if isinstance(block, Spectrum)
360-
]
361-
362-
# FIXME right now only the scopes are converted to CSV
363-
# extra work is needed since spectra and scopes don't share the same x axis
364-
csv_payload = make_csv_payload(scopes)
428+
try:
429+
fig, csv_payload = make_plot(my_simulation)
430+
print("Created plot figure")
365431

366-
# Share x only if there are only scopes or only spectra
367-
shared_x = len(scopes) * len(spectra) == 0
368-
n_rows = len(scopes) + len(spectra)
432+
# Convert plot to JSON
433+
try:
434+
plot_data = plotly_json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)
435+
plot_html = fig.to_html()
436+
print("Converted plot to JSON and HTML")
437+
except Exception as plot_error:
438+
print(f"Error converting plot to JSON: {str(plot_error)}")
439+
return jsonify(
440+
{
441+
"success": False,
442+
"error": f"Plot generation error: {str(plot_error)}",
443+
}
444+
), 500
369445

370-
if n_rows == 0:
371-
# No scopes or spectra to plot
372446
return jsonify(
373447
{
374448
"success": True,
375-
"plot": "{}",
376-
"html": "<p>No scopes or spectra to display</p>",
449+
"plot": plot_data,
450+
"html": plot_html,
377451
"csv_data": csv_payload,
378452
"message": "Pathsim simulation completed successfully",
379453
}
380454
)
381455

382-
absolute_vertical_spacing = 0.05
383-
relative_vertical_spacing = absolute_vertical_spacing / n_rows
384-
fig = make_subplots(
385-
rows=n_rows,
386-
cols=1,
387-
shared_xaxes=shared_x,
388-
subplot_titles=[scope.label for scope in scopes]
389-
+ [spec.label for spec in spectra],
390-
vertical_spacing=relative_vertical_spacing,
391-
)
392-
393-
# make scope plots
394-
for i, scope in enumerate(scopes):
395-
sim_time, data = scope.read()
396-
397-
for p, d in enumerate(data):
398-
lb = scope.labels[p] if p < len(scope.labels) else f"port {p}"
399-
if isinstance(scope, Spectrum):
400-
d = abs(d)
401-
fig.add_trace(
402-
go.Scatter(x=sim_time, y=d, mode="lines", name=lb), row=i + 1, col=1
403-
)
404-
405-
fig.update_xaxes(title_text="Time", row=len(scopes), col=1)
406-
407-
# make spectrum plots
408-
for i, spec in enumerate(spectra):
409-
freq, data = spec.read()
410-
411-
for p, d in enumerate(data):
412-
lb = spec.labels[p] if p < len(spec.labels) else f"port {p}"
413-
d = abs(d)
414-
fig.add_trace(
415-
go.Scatter(x=freq, y=d, mode="lines", name=lb),
416-
row=len(scopes) + i + 1,
417-
col=1,
418-
)
419-
fig.update_xaxes(title_text="Frequency", row=len(scopes) + i + 1, col=1)
420-
421-
fig.update_layout(
422-
height=500 * (len(scopes) + len(spectra)), hovermode="x unified"
423-
)
424-
425-
# Convert plot to JSON
426-
try:
427-
plot_data = plotly_json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)
428-
plot_html = fig.to_html()
429-
except Exception as plot_error:
456+
except Exception as plot_creation_error:
457+
print(f"Error during plot creation: {str(plot_creation_error)}")
430458
return jsonify(
431-
{"success": False, "error": f"Plot generation error: {str(plot_error)}"}
459+
{
460+
"success": False,
461+
"error": f"Plot creation error: {str(plot_creation_error)}",
462+
}
432463
), 500
433464

434-
return jsonify(
435-
{
436-
"success": True,
437-
"plot": plot_data,
438-
"html": plot_html,
439-
"csv_data": csv_payload,
440-
"message": "Pathsim simulation completed successfully",
441-
}
442-
)
443-
444465
except Exception as e:
445466
# Log the full error for debugging
446467
import traceback

0 commit comments

Comments
 (0)