Skip to content
Snippets Groups Projects

Draft: Added support for plotting result from many simulations. Solves #209

Open Petter Källström requested to merge MultiSimPlot into master
4 unresolved threads
2 files
+ 94
13
Compare changes
  • Side-by-side
  • Inline
Files
2
@@ -47,7 +47,7 @@ class PlotWindow(QWidget):
@@ -47,7 +47,7 @@ class PlotWindow(QWidget):
def __init__(
def __init__(
self,
self,
sim_result: Mapping[ResultKey, Sequence[Num]],
sim_result: Mapping[ResultKey, Sequence[Num]],
sfg_name: Optional[str] = None,
figure_name: Optional[str] = None,
):
):
super().__init__()
super().__init__()
self.setWindowFlags(
self.setWindowFlags(
@@ -57,8 +57,8 @@ class PlotWindow(QWidget):
@@ -57,8 +57,8 @@ class PlotWindow(QWidget):
| Qt.WindowMaximizeButtonHint
| Qt.WindowMaximizeButtonHint
)
)
title = (
title = (
f"Simulation results: {sfg_name}"
f"Simulation results: {figure_name}"
if sfg_name is not None
if figure_name is not None
else "Simulation results"
else "Simulation results"
)
)
self.setWindowTitle(title)
self.setWindowTitle(title)
@@ -238,8 +238,8 @@ class PlotWindow(QWidget):
@@ -238,8 +238,8 @@ class PlotWindow(QWidget):
# Add additional checkboxes
# Add additional checkboxes
self._legend = self._plot_axes.legend()
self._legend = self._plot_axes.legend()
self._legend_checkbox = QCheckBox("&Legend")
self._legend_checkbox = QCheckBox("&Legend")
self._legend_checkbox.stateChanged.connect(self._legend_checkbox_change)
self._legend_checkbox.setCheckState(Qt.CheckState.Checked)
self._legend_checkbox.setCheckState(Qt.CheckState.Checked)
 
self._legend_checkbox.stateChanged.connect(self._legend_checkbox_change)
self._legend_checkbox.setIcon(get_icon('legend'))
self._legend_checkbox.setIcon(get_icon('legend'))
listlayout.addWidget(self._legend_checkbox)
listlayout.addWidget(self._legend_checkbox)
# self.ontop_checkbox = QCheckBox("&On top")
# self.ontop_checkbox = QCheckBox("&On top")
@@ -261,12 +261,63 @@ class PlotWindow(QWidget):
@@ -261,12 +261,63 @@ class PlotWindow(QWidget):
# self.plotcanvas.draw()
# self.plotcanvas.draw()
self._auto_redraw = True
self._auto_redraw = True
 
def add_result(self, name, result) -> None:
 
"""
 
Add another result to the plot.
 
 
The new signals are added in natural order without sorting them.
 
---
 
name: str
 
The name of the result
 
result: dict
 
The result from one simulation.
 
"""
 
markers = ".ov<^>s+*xd|_"
 
ix = 0
 
self._auto_redraw = False
 
for key, res in result.items():
 
key2 = name + "." + key
 
ischecked = Qt.CheckState.Unchecked
 
if re.fullmatch(r"[0-9]+", key):
 
key2 = name + '.out' + key
 
ischecked = Qt.CheckState.Checked
 
 
if len(res) <= 100:
 
fmt = markers[ix] + '-'
 
ix = (ix + 1) % len(markers)
 
else:
 
fmt = '-'
 
 
def addline(key, vector, checked):
 
line = self._plot_axes.plot(np.real(res), fmt, label=key)
 
self._lines[key] = line[0]
 
list_item = QListWidgetItem(key)
 
list_item.setCheckState(
 
Qt.CheckState.Unchecked
 
) # will add it if checked
 
self._checklist.addItem(list_item)
 
self._lines[
 
key
 
].remove() # remove the line from plot. Keep it in _lines.
 
list_item.setCheckState(checked) # will add it if checked
 
 
if all(np.imag(np.real_if_close(res)) == 0):
 
# real: add one line with corresponding checkbox
 
addline(key2, np.real(res), ischecked)
 
else:
 
# complex: add '_re', '_im', '_mag', '_ang'
 
addline(key2 + "_re", np.real(res), ischecked)
 
addline(key2 + "_im", np.imag(res), ischecked)
 
addline(key2 + "_mag", np.absolute(res), Qt.CheckState.Unchecked)
 
addline(key2 + "_ang", np.angle(res), Qt.CheckState.Unchecked)
 
self._auto_redraw = True
 
self._update_legend()
 
self._plot_canvas.draw()
 
def _legend_checkbox_change(self, check_state):
def _legend_checkbox_change(self, check_state):
self._legend.set(visible=(check_state == Qt.CheckState.Checked))
self._legend.set(visible=(check_state == Qt.CheckState.Checked))
if self._auto_redraw:
self._update_legend()
if check_state == Qt.CheckState.Checked:
self._plot_canvas.draw()
self._legend = self._plot_axes.legend()
self._plot_canvas.draw()
# def _ontop_checkbox_change(self, checkState):
# def _ontop_checkbox_change(self, checkState):
# Bugg: It seems the window closes if you change the WindowStaysOnTopHint.
# Bugg: It seems the window closes if you change the WindowStaysOnTopHint.
@@ -281,10 +332,12 @@ class PlotWindow(QWidget):
@@ -281,10 +332,12 @@ class PlotWindow(QWidget):
self._checklist.item(x).setCheckState(Qt.CheckState.Checked)
self._checklist.item(x).setCheckState(Qt.CheckState.Checked)
self._auto_redraw = True
self._auto_redraw = True
self._update_legend()
self._update_legend()
 
self._plot_canvas.draw()
def _update_legend(self):
def _update_legend(self):
self._legend = self._plot_axes.legend()
# if self._legend_checkbox.checkState == Qt.CheckState.Checked:
self._plot_canvas.draw()
if self._legend_checkbox.isChecked():
 
self._legend = self._plot_axes.legend()
def _button_none_click(self, event):
def _button_none_click(self, event):
self._auto_redraw = False
self._auto_redraw = False
@@ -292,6 +345,7 @@ class PlotWindow(QWidget):
@@ -292,6 +345,7 @@ class PlotWindow(QWidget):
self._checklist.item(x).setCheckState(Qt.CheckState.Unchecked)
self._checklist.item(x).setCheckState(Qt.CheckState.Unchecked)
self._auto_redraw = True
self._auto_redraw = True
self._update_legend()
self._update_legend()
 
self._plot_canvas.draw()
def _item_change(self, listitem):
def _item_change(self, listitem):
key = listitem.text()
key = listitem.text()
@@ -301,6 +355,7 @@ class PlotWindow(QWidget):
@@ -301,6 +355,7 @@ class PlotWindow(QWidget):
self._lines[key].remove()
self._lines[key].remove()
if self._auto_redraw:
if self._auto_redraw:
self._update_legend()
self._update_legend()
 
self._plot_canvas.draw()
def _relim(self, event=None):
def _relim(self, event=None):
self._plot_axes.relim(True)
self._plot_axes.relim(True)
@@ -312,6 +367,13 @@ class PlotWindow(QWidget):
@@ -312,6 +367,13 @@ class PlotWindow(QWidget):
def start_simulation_dialog(
def start_simulation_dialog(
sim_results: Dict[str, List[complex]], sfg_name: Optional[str] = None
sim_results: Dict[str, List[complex]], sfg_name: Optional[str] = None
 
):
 
"""Deprecated. Use `show_simulation_result` instead."""
 
show_simulation_result(sim_results, sfg_name)
 
 
 
def show_simulation_result(
 
sim_results: Dict[str, List[complex]], figure_name: Optional[str] = None
):
):
"""
"""
Display the simulation results window.
Display the simulation results window.
@@ -328,7 +390,7 @@ def start_simulation_dialog(
@@ -328,7 +390,7 @@ def start_simulation_dialog(
app = QApplication(sys.argv)
app = QApplication(sys.argv)
else:
else:
app = QApplication.instance()
app = QApplication.instance()
win = PlotWindow(sim_result=sim_results, sfg_name=sfg_name)
win = PlotWindow(sim_result=sim_results, figure_name=figure_name)
win.show()
win.show()
app.exec_()
app.exec_()
@@ -360,8 +422,18 @@ if __name__ == "__main__":
@@ -360,8 +422,18 @@ if __name__ == "__main__":
't3': [0, 0, 0, 1],
't3': [0, 0, 0, 1],
}
}
res3 = {
res3 = {
'0': np.random.rand(200).tolist(),
#'0': np.random.rand(50).tolist(),
 
'0': np.random.rand(50),
'1': np.random.rand(200).tolist(),
'1': np.random.rand(200).tolist(),
}
}
 
res4 = {
 
'0': np.random.rand(60).tolist(),
 
'1': np.random.rand(220).tolist(),
 
't4': np.random.rand(50).tolist(),
 
}
# start_simulation_dialog(res3)
# start_simulation_dialog(res3)
start_simulation_dialog(['Real', res1, 'Cpx', res2, res3], "Test data")
app = QApplication(sys.argv)
 
win2 = PlotWindow(['Real', res1, 'Cpx', res2, res3], "Test data")
 
win2.add_result('res4', res4)
 
win2.show()
 
app.exec_()
Loading