#!/usr/bin/env python3 import pyqtgraph as pg from pyqtgraph.Qt import QtWidgets, QtCore import numpy as np import sys, os # -------------------- Fichiers de données -------------------- REF_FILE = "constellation_ref.dat" RX_FILE = "constellation.dat" ERROR_FILE = "pll_error.dat" # -------------------- Fonctions de chargement -------------------- def load_points(filename): if os.path.exists(filename): return np.loadtxt(filename) else: return np.zeros((0,2)) def load_error(filename): if os.path.exists(filename): return np.loadtxt(filename) else: return np.zeros((0,2)) # -------------------- Application -------------------- app = QtWidgets.QApplication(sys.argv) win = pg.GraphicsLayoutWidget(show=True, title="Constellation") win.resize(900, 900) win.setBackground('#0a0a0a') # fond noir profond plot = win.addPlot() plot.setAspectLocked(True) # axes égaux # -------------------- Axes stylés -------------------- plot.getAxis('left').setPen(pg.mkPen('#AAA', width=2)) plot.getAxis('bottom').setPen(pg.mkPen('#AAA', width=2)) plot.getAxis('left').setTextPen(pg.mkPen('#EEE')) plot.getAxis('bottom').setTextPen(pg.mkPen('#EEE')) plot.setLabel('left', 'Quadrature (Q)', color='#EEE', size='12pt') plot.setLabel('bottom', 'In-phase (I)', color='#EEE', size='12pt') # -------------------- Grille subtile -------------------- grid = pg.GridItem() grid.setPen(pg.mkPen('#444', width=1, style=QtCore.Qt.DotLine)) plot.addItem(grid) # -------------------- Chargement initial -------------------- ref_data = load_points(REF_FILE) rx_data = load_points(RX_FILE) error_data = load_error(ERROR_FILE) # Points référence ref_plot = plot.plot(ref_data[:,0], ref_data[:,1], pen=None, symbol='o', symbolSize=10, symbolBrush=pg.mkBrush('#1E90FF'), # bleu vif symbolPen=None, name='Référence') # Points reçus rx_plot = plot.plot(rx_data[:,0], rx_data[:,1], pen=None, symbol='x', symbolSize=6, symbolBrush=pg.mkBrush('#FF4500'), # orange vif symbolPen=None, name='Reçu') # PLL error en vert error_plot = plot.plot(error_data[:,0], error_data[:,1], pen=pg.mkPen('#00FF00', width=2), symbol=None, name='PLL error') # -------------------- Légende stylée -------------------- legend = plot.addLegend() for item in legend.items: item[1].setPen(pg.mkPen('#FFF', width=2)) # -------------------- Timer pour mise à jour dynamique -------------------- def update(): ref_data = load_points(REF_FILE) rx_data = load_points(RX_FILE) error_data = load_error(ERROR_FILE) if ref_data.size > 0: ref_plot.setData(ref_data[:,0], ref_data[:,1]) if rx_data.size > 0: rx_plot.setData(rx_data[:,0], rx_data[:,1]) if error_data.size > 0: error_plot.setData(error_data[:,0], error_data[:,1]) timer = QtCore.QTimer() timer.timeout.connect(update) timer.start(500) # ms # -------------------- Anti-aliasing -------------------- pg.setConfigOptions(antialias=True) # -------------------- Exécution -------------------- if __name__ == '__main__': sys.exit(app.exec_())