class PrimaryPlotWidget(QWidget): def __init__(self, parent=None, model=None): super().__init__(parent) self._model = model self._plot = PlotWidget(parent=None, toolbar=True) self._grid = QGridLayout() self._grid.addWidget(self._plot, 0, 0) self.setLayout(self._grid) self._init() def _init(self): self._plot.subplots_adjust(bottom=0.150) self._plot.set_xlabel(self._model.xLabel) self._plot.set_ylabel(self._model.yLabel) self._plot.grid(b=True, which='major', color='0.5', linestyle='-') def clear(self): self._plot.clear() def plot(self): self.clear() self._init() self._plot.plot(self._model.xs, self._model.ys) self._plot.plot(self._model.xs, self._model.filteredYs)
class SingleMeasureWidget(QWidget): def __init__(self, parent=None, domain=None): super().__init__(parent) self._domain = domain self._plot = PlotWidget(parent=None, toolbar=True) self._layout = QHBoxLayout() self._layout.addWidget(self._plot) self.setLayout(self._layout) self._init() def _init(self): self._plot.subplots_adjust(bottom=0.150) self._plot.set_title('Коэффициент преобразования для N-гармоники') self._plot.set_xscale('log') self._plot.set_xlabel('F, Гц', labelpad=-2) self._plot.set_ylabel('К-т пр., дБ', labelpad=-2) self._plot.grid(b=True, which='minor', color='0.7', linestyle='--') self._plot.grid(b=True, which='major', color='0.5', linestyle='-') def clear(self): self._plot.clear() self._init() def plot(self): print('plotting single measurement') self.clear() self._plot.plot(self._domain.singleMeasureXs, self._domain.singleMeasureYs, color='0.4')
class PowSweepWidget(QWidget): def __init__(self, parent=None, controller=None): super().__init__(parent=parent) self._controller = controller self._ui = uic.loadUi('powsweepwidget.ui', self) self._plot = PlotWidget(parent=None, toolbar=True) # self._ui.verticalLayout.addWidget(self._plot) self._ui.btnPowSweep.hide() self._init() def _init(self): self._plot.set_title('Прогон по мощности') self._plot.set_xlabel('F, GHz', labelpad=-2) self._plot.set_ylabel('Pow, dB', labelpad=-2) self._plot.set_xlim(4, 8) # self._plot.set_ylim(pars['ylim'][0], pars['ylim'][1]) self._plot.grid(b=True, which='major', color='0.5', linestyle='-') self._plot.tight_layout() @pyqtSlot() def on_btnPowSweep_clicked(self): freqs, amps = self._controller.pow_sweep() self._plot.clear() self._init() self._plot.plot(freqs, amps)
class PhasePlotWidget(QWidget): def __init__(self, parent=None, domain=None): super().__init__(parent) self._domain = domain self._plot = PlotWidget(parent=None, toolbar=True) self._layout = QVBoxLayout() self._layout.addWidget(self._plot) self.setLayout(self._layout) self._title = '' self._stats = list() self._init() def _init(self): self._plot.set_title(self._title) self._plot.set_xlabel('Offset frequency, Hz') self._plot.set_ylabel('Phase noise, dBc/Hz') self._plot.set_xscale('log') # self._plot.set_xlim(pars['xlim'][0], pars['xlim'][1]) # self._plot.set_ylim(pars['ylim'][0], pars['ylim'][1]) self._plot.grid(b=True, which='major', color='0.5', linestyle='--') def clear(self): self._plot.clear() def plot(self): legend = [ Line2D([0], [0], color='0.2', linestyle='-', label=lbl) for lbl in self._stats ] self._plot.clear() self._init() self._plot.legend(handles=legend) self._plot.plot(self._domain.xs, self._domain.ys) self._plot.plot(self._domain.xs, self._domain.smoothYs) def addMarkers(self, markers): for marker in markers: self._plot.axvline(marker, 0, 1, linewidth=0.8, color='0.3', linestyle='-') def tightLayout(self): self._plot.tight_layout()
class HarmonicMeasureWidget(QWidget): def __init__(self, parent=None, domain=None): super().__init__(parent) self._domain = domain self._plot = PlotWidget(parent=None, toolbar=True) self.btnMeasure = QPushButton('Измерить') self.btnMeasure.setEnabled(False) self._hlay = QHBoxLayout() self._hlay.addWidget(self.btnMeasure) self._hlay.addStretch() self._layout = QVBoxLayout() self._layout.addItem(self._hlay) self._layout.addWidget(self._plot) self.setLayout(self._layout) self._init() def _init(self): self._plot.subplots_adjust(bottom=0.150) self._plot.set_title('Подавление 2й и 3й гармоник') self._plot.set_xlabel('Код', labelpad=-2) self._plot.set_ylabel('Подавление, дБ', labelpad=-2) self._plot.grid(b=True, which='minor', color='0.7', linestyle='--') self._plot.grid(b=True, which='major', color='0.5', linestyle='-') def clear(self): self._plot.clear() self._init() def plot(self): print(f'plotting harmonic deltas') for key, values in self._domain.harm_deltas.items(): self._plot.plot(self._domain.codes, values, label=f'f x {key}') self._plot.legend()
class StatPlotWidget(QWidget): def __init__(self, parent=None, domain=None): super().__init__(parent) self._domain = domain self._grid = QGridLayout() self._plot11 = PlotWidget(parent=None, toolbar=True) self._plot12 = PlotWidget(parent=None, toolbar=True) self._plot21 = PlotWidget(parent=None, toolbar=True) self._plot22 = PlotWidget(parent=None, toolbar=True) self._grid.addWidget(self._plot11, 0, 0) self._grid.addWidget(self._plot12, 0, 1) self._grid.addWidget(self._plot21, 1, 0) self._grid.addWidget(self._plot22, 1, 1) self.setLayout(self._grid) self._init() def _init(self): # self._plot11.set_tight_layout(True) self._plot11.subplots_adjust(bottom=0.150) self._plot11.set_title('Коэффициент преобразования') self._plot11.set_xscale('log') self._plot11.set_xlabel('F, Гц', labelpad=-2) self._plot11.set_ylabel('К-т пр., дБ', labelpad=-2) # self._plot11.set_ylim([-60, 30]) self._plot11.grid(b=True, which='minor', color='0.7', linestyle='--') self._plot11.grid(b=True, which='major', color='0.5', linestyle='-') # self._plot12.set_tight_layout(True) self._plot12.subplots_adjust(bottom=0.150) self._plot12.set_title( f'Частота среза по уровню {self._domain.cutoffMag} дБ') self._plot12.set_xlabel('Код', labelpad=-2) self._plot12.set_ylabel('F, МГц', labelpad=-2) self._plot12.set_yscale('log') self._plot12.grid(b=True, which='minor', color='0.7', linestyle='--') self._plot12.grid(b=True, which='major', color='0.5', linestyle='-') # self._plot21.set_tight_layout(True) self._plot21.subplots_adjust(bottom=0.150) self._plot21.set_title('Дельта частоты среза') self._plot21.set_xlabel('Код') self._plot21.set_ylabel('dF, МГц') self._plot21.grid(b=True, which='major', color='0.5', linestyle='-') # self._plot22.set_tight_layout(True) self._plot22.subplots_adjust(bottom=0.150) self._plot22.set_title('Затухание на x2 и x3 частоте среза') self._plot22.set_xlabel('Код') self._plot22.set_ylabel('Подавление, дБ') # self._plot22.set_ylim([-60, 30]) self._plot22.grid(b=True, which='major', color='0.5', linestyle='-') def clear(self): self._plot11.clear() self._plot12.clear() self._plot21.clear() self._plot22.clear() self._init() def plotCode(self): print('plotting code') self._plot11.plot(self._domain.lastXs, self._domain.lastYs, color='0.4') def plotStats(self): print('plotting stats') self._plot12.plot(self._domain.cutoffXs, self._domain.cutoffYs, color='0.4') self._plot21.plot(self._domain.deltaXs, self._domain.deltaYs, color='0.4') self._plot22.plot(self._domain.lossDoubleXs, self._domain.lossDoubleYs, color='0.4') self._plot22.plot(self._domain.lossTripleXs, self._domain.lossTripleYs, color='0.4') self._plot11.axhline(self._domain.cutoffAmp, 0, 1, linewidth=0.8, color='0.3', linestyle='--') self._plot11.set_yticks( sorted( set( list(self._plot11.get_yticks()[0]) + [self._domain.cutoffMag]))) def save(self, img_path='./image'): try: os.makedirs(img_path) except OSError as ex: if ex.errno != errno.EEXIST: raise IOError('Error creating image dir.') for plot, name in zip( [self._plot11, self._plot12, self._plot21, self._plot22], ['stats.png', 'cutoff.png', 'delta.png', 'double-triple.png']): plot.savefig(img_path + name, dpi=400)