plotting with random data

This commit is contained in:
Brendan Haines 2024-12-21 13:09:56 -07:00
parent 2f7b9fc1eb
commit 6d920c6809

View File

@ -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)