plotting with random data
This commit is contained in:
parent
2f7b9fc1eb
commit
6d920c6809
|
@ -1,13 +1,14 @@
|
||||||
# %% imports
|
# %% imports
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Callable, List, Tuple
|
from typing import Callable, List, Literal, Tuple
|
||||||
|
|
||||||
import matplotlib as mpl
|
import matplotlib as mpl
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import xarray as xr
|
import xarray as xr
|
||||||
from matplotlib import pyplot as plt
|
from matplotlib import pyplot as plt
|
||||||
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg
|
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg
|
||||||
|
from matplotlib.lines import Line2D
|
||||||
from matplotlib.ticker import EngFormatter
|
from matplotlib.ticker import EngFormatter
|
||||||
from numpy import typing as npt
|
from numpy import typing as npt
|
||||||
from PySide6.QtGui import QAction, QKeySequence
|
from PySide6.QtGui import QAction, QKeySequence
|
||||||
|
@ -34,20 +35,21 @@ DEFAULT_CONFIG = dict(
|
||||||
|
|
||||||
|
|
||||||
class PlotWidget(QWidget):
|
class PlotWidget(QWidget):
|
||||||
enabled_ports: List[Tuple[int | str]]
|
traces: List[Tuple[int | str]]
|
||||||
|
lines: List[Line2D]
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, type_: str = "logmag"):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.enabled_ports = [(1, 1)]
|
self.traces = [(1, 1)]
|
||||||
|
|
||||||
layout = QVBoxLayout()
|
layout = QVBoxLayout()
|
||||||
self.setLayout(layout)
|
self.setLayout(layout)
|
||||||
|
|
||||||
self.fig = plt.Figure(figsize=(5, 4), dpi=100, tight_layout=True)
|
self.fig = plt.Figure(figsize=(5, 4), dpi=100, tight_layout=True)
|
||||||
self.ax = self.fig.add_subplot(111)
|
self.ax = self.fig.add_subplot(111)
|
||||||
self.setup_logmag()
|
self.set_plot_type(type_)
|
||||||
# self.setup_smith()
|
self.lines = [self.ax.plot([np.nan], [np.nan], label="$S_{" + str(m) + str(n) + "}$") for m, n in self.traces]
|
||||||
self.ax.legend(loc="upper right")
|
self.ax.legend(loc="upper right")
|
||||||
|
|
||||||
canvas = FigureCanvasQTAgg(self.fig)
|
canvas = FigureCanvasQTAgg(self.fig)
|
||||||
|
@ -57,6 +59,37 @@ class PlotWidget(QWidget):
|
||||||
# toolbar.addAction("blah")
|
# toolbar.addAction("blah")
|
||||||
# self.addToolBar(toolbar)
|
# self.addToolBar(toolbar)
|
||||||
|
|
||||||
|
def set_plot_type(
|
||||||
|
self,
|
||||||
|
type_: Literal["logmag", "phase", "vswr", "smith"],
|
||||||
|
sweep_type: Literal["frequency", "time"] = "frequency",
|
||||||
|
) -> None:
|
||||||
|
if sweep_type != "frequency":
|
||||||
|
raise NotImplementedError("Only frequency sweeps are currently supported")
|
||||||
|
|
||||||
|
if type_ == "logmag":
|
||||||
|
self.setup_logmag()
|
||||||
|
elif type_ == "phase":
|
||||||
|
self.setup_phase()
|
||||||
|
elif type_ == "vswr":
|
||||||
|
self.setup_vswr()
|
||||||
|
elif type_ == "smith":
|
||||||
|
self.setup_smith()
|
||||||
|
else:
|
||||||
|
raise ValueError(f"Unknown plot type: {type_}")
|
||||||
|
|
||||||
|
self._plot_type = type_
|
||||||
|
|
||||||
|
def update_plot(self, data: xr.DataArray):
|
||||||
|
if self._plot_type == "logmag":
|
||||||
|
self.update_logmag(data)
|
||||||
|
elif self._plot_type == "phase":
|
||||||
|
self.update_phase(data)
|
||||||
|
elif self._plot_type == "vswr":
|
||||||
|
self.update_vswr(data)
|
||||||
|
elif self._plot_type == "smith":
|
||||||
|
self.update_smith(data)
|
||||||
|
|
||||||
def setup_rect(self) -> None:
|
def setup_rect(self) -> None:
|
||||||
self.ax.grid(True)
|
self.ax.grid(True)
|
||||||
self.ax.xaxis.set_major_formatter(EngFormatter())
|
self.ax.xaxis.set_major_formatter(EngFormatter())
|
||||||
|
@ -67,8 +100,11 @@ class PlotWidget(QWidget):
|
||||||
# remove old lines
|
# remove old lines
|
||||||
for line in self.ax.lines:
|
for line in self.ax.lines:
|
||||||
line.remove()
|
line.remove()
|
||||||
for m, n in self.enabled_ports:
|
for ii, (m, n) in enumerate(self.traces):
|
||||||
self.ax.plot(data["frequency"], func(data.sel(m=m, n=n)))
|
self.lines[ii] = self.ax.plot(data["frequency"], func(data.sel(m=m, n=n)))[0]
|
||||||
|
|
||||||
|
self.fig.canvas.draw()
|
||||||
|
self.fig.canvas.flush_events()
|
||||||
|
|
||||||
def setup_logmag(self, ylim: List[float] = [-30, 30]) -> None:
|
def setup_logmag(self, ylim: List[float] = [-30, 30]) -> None:
|
||||||
self.setup_rect()
|
self.setup_rect()
|
||||||
|
@ -106,9 +142,9 @@ class PlotWidget(QWidget):
|
||||||
# remove old lines
|
# remove old lines
|
||||||
for line in self.ax.lines:
|
for line in self.ax.lines:
|
||||||
line.remove()
|
line.remove()
|
||||||
for m, n in self.enabled_ports:
|
for ii, (m, n) in enumerate(self.traces):
|
||||||
sel = data.sel(m=m, n=n)
|
sel = data.sel(m=m, n=n)
|
||||||
self.ax.plot(sel.real, sel.imag)
|
self.lines[ii] = self.ax.plot(sel.real, sel.imag)[0]
|
||||||
|
|
||||||
|
|
||||||
# Subclass QMainWindow to customize your application's main window
|
# Subclass QMainWindow to customize your application's main window
|
||||||
|
@ -116,6 +152,8 @@ class MainWindow(QMainWindow):
|
||||||
config_path: Path | None
|
config_path: Path | None
|
||||||
# device: Charon
|
# device: Charon
|
||||||
|
|
||||||
|
plots: List[PlotWidget]
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
|
@ -157,22 +195,31 @@ class MainWindow(QMainWindow):
|
||||||
menu_calibration = QMenu("&Calibration")
|
menu_calibration = QMenu("&Calibration")
|
||||||
menubar.addMenu(menu_calibration)
|
menubar.addMenu(menu_calibration)
|
||||||
|
|
||||||
|
menu_simulation = QMenu("Si&mulation")
|
||||||
|
menubar.addMenu(menu_simulation)
|
||||||
|
action_generate_data = QAction("&Generate data", self)
|
||||||
|
menu_file.addAction(action_generate_data)
|
||||||
|
action_generate_data.triggered.connect(self.generate_sim_data)
|
||||||
|
action_generate_data.setShortcut(QKeySequence("Ctrl+G"))
|
||||||
|
|
||||||
# Content
|
# Content
|
||||||
window_layout = QVBoxLayout()
|
window_layout = QVBoxLayout()
|
||||||
|
|
||||||
prog_sweep = QProgressBar()
|
prog_sweep = QProgressBar()
|
||||||
prog_sweep.setMinimum(0)
|
prog_sweep.setMinimum(0)
|
||||||
prog_sweep.setMaximum(100)
|
prog_sweep.setMaximum(100)
|
||||||
prog_sweep.setTextVisible(False)
|
prog_sweep.setFormat("%v / %m")
|
||||||
|
# prog_sweep.setTextVisible(False)
|
||||||
prog_sweep.setValue(50)
|
prog_sweep.setValue(50)
|
||||||
window_layout.addWidget(prog_sweep)
|
window_layout.addWidget(prog_sweep)
|
||||||
|
|
||||||
# window_widget.se
|
# window_widget.se
|
||||||
plot_layout = QVBoxLayout()
|
plot_layout = QVBoxLayout()
|
||||||
# TODO: handle plots properly
|
# TODO: handle plots properly
|
||||||
for i in range(2):
|
self.plots = []
|
||||||
plot0 = PlotWidget()
|
for type_ in ["logmag", "phase", "vswr"]:
|
||||||
plot_layout.addWidget(plot0)
|
self.plots.append(PlotWidget(type_=type_))
|
||||||
|
plot_layout.addWidget(self.plots[-1])
|
||||||
plot_widget = QWidget()
|
plot_widget = QWidget()
|
||||||
plot_widget.setLayout(plot_layout)
|
plot_widget.setLayout(plot_layout)
|
||||||
window_layout.addWidget(plot_widget)
|
window_layout.addWidget(plot_widget)
|
||||||
|
@ -200,6 +247,19 @@ class MainWindow(QMainWindow):
|
||||||
print("loading config")
|
print("loading config")
|
||||||
# TODO: load config
|
# TODO: load config
|
||||||
|
|
||||||
|
def generate_sim_data(self) -> None:
|
||||||
|
coords = {"frequency": np.linspace(1e9, 2e9, 101), "m": [1], "n": [1]}
|
||||||
|
shape = tuple(len(v) for v in coords.values())
|
||||||
|
print(shape)
|
||||||
|
data = xr.DataArray(
|
||||||
|
((-1 + 2 * np.random.rand(*shape)) + 1j * (-1 + 2 * np.random.rand(*shape))) / np.sqrt(2),
|
||||||
|
dims=list(coords.keys()),
|
||||||
|
coords=coords,
|
||||||
|
)
|
||||||
|
|
||||||
|
for plot in self.plots:
|
||||||
|
plot.update_plot(data)
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
app = QApplication(sys.argv)
|
app = QApplication(sys.argv)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user