Created
November 3, 2023 12:36
-
-
Save noc0lour/1f17a0efaacc5ca310f3f30a886227c8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
"""Plot Constellation and animate it.""" | |
from PySide6.QtWidgets import ( | |
QWidget, | |
QLabel, | |
QGridLayout, | |
QApplication, | |
QMainWindow, | |
QSlider, | |
) | |
import numpy as np | |
import pyqtgraph as pg | |
from PySide6.QtGui import QIcon | |
from PySide6.QtCore import Qt, QPropertyAnimation | |
import argparse | |
import sys | |
import os | |
import pandas as pd | |
vhex = np.vectorize(hex) | |
def ints2bits(ints, m): | |
"""Convert integers to their bit representations MSB first. | |
:param ints: array of ints | |
:param m: bit-width per int | |
:returns: array of bit arrays | |
""" | |
b = np.expand_dims(ints, 1) | |
B = np.flip( | |
np.unpackbits(b.view(np.uint8), axis=1, count=m, bitorder="little"), axis=1 | |
)[:, :m] | |
return B | |
def hex2bits(hexs, m): | |
"""Convert list of hex strings to their bit representation MSB first. | |
:param hexs: list of hex strings | |
:param m: bit-width per hex | |
:returns: array of bit arrays | |
""" | |
ints = np.array([int("0x" + h, 0) for h in hexs]) | |
bits = ints2bits(ints, m) | |
return bits | |
class Window(QMainWindow): | |
def __init__(self, min_epoch, max_epoch, constellations, constellation_size): | |
super().__init__() | |
# setting title | |
self.setWindowTitle("Constellations") | |
# Set parameters | |
self.min_epoch = min_epoch | |
self.max_epoch = max_epoch | |
self.constellations = constellations | |
self.constellation_size = constellation_size | |
# setting geometry | |
self.setGeometry(100, 100, 600, 500) | |
# icon | |
icon = QIcon("skin.png") | |
# setting icon to the window | |
self.setWindowIcon(icon) | |
# calling method | |
self.UiComponents() | |
# showing all the widgets | |
self.show() | |
def plotPoints(self, epoch): | |
constellation_df = self.constellations[self.constellations["epoch"] == epoch] | |
constellation = constellation_df["constellation"].iloc[0] | |
labels = constellation_df["labels"].iloc[0] | |
bitstrings = [str(s) for s in hex2bits(labels, 6)] | |
self.scatter.setData(pos=constellation) | |
for bitstring, point, label in zip(bitstrings, constellation, self.labeltexts): | |
label.setText(bitstring) | |
label.setPos(float(point[0]), float(point[1])) | |
def slider_valuechanged(self): | |
epoch = self.slider.value() | |
self.plotPoints(epoch) | |
self.epoch_text.setText(f"Epoch: {epoch}") | |
information_rate = self.constellations[self.constellations["epoch"] == epoch][ | |
"information_rate" | |
].iloc[0] | |
self.informationrate_text.setText(f"IR: {information_rate}") | |
# method for components | |
def UiComponents(self): | |
# creating a widget object | |
widget = QWidget() | |
# creating a plot window | |
plot = pg.plot() | |
# creating a scatter plot item | |
# of size = 10 | |
# using brush to enlarge the of white color with transparency is 50% | |
self.scatter = pg.ScatterPlotItem(size=10, brush=pg.mkBrush(255, 255, 255, 120)) | |
self.labeltexts = [pg.TextItem() for _ in range(self.constellation_size)] | |
self.epoch_text = QLabel("Epoch: 0") | |
self.informationrate_text = QLabel("IR: ") | |
self.slider = QSlider(Qt.Orientation.Horizontal, self) | |
self.slider.setGeometry(50, 50, 200, 50) | |
self.slider.setMinimum(self.min_epoch) | |
self.slider.setMaximum(self.max_epoch) | |
self.slider.setTickPosition(QSlider.TickPosition.TicksBelow) | |
self.slider.setTickInterval(1) | |
self.slider.valueChanged.connect(self.slider_valuechanged) | |
self.anim = QPropertyAnimation(self.slider, b"value") | |
self.anim.setStartValue(self.min_epoch) | |
self.anim.setEndValue(self.max_epoch) | |
self.anim.setDuration(10000) | |
self.anim.start() | |
self.plotPoints(0) | |
# add item to plot window | |
# adding scatter plot item to the plot window | |
plot.addItem(self.scatter) | |
for label in self.labeltexts: | |
plot.addItem(label) | |
# Creating a grid layout | |
layout = QGridLayout() | |
# setting this layout to the widget | |
widget.setLayout(layout) | |
# plot window goes on right side, spanning 3 rows | |
layout.addWidget(plot, 0, 0, 3, 6) | |
layout.addWidget(self.slider, 4, 1, 1, 3) | |
layout.addWidget(self.epoch_text, 4, 4, 1, 1) | |
layout.addWidget(self.informationrate_text, 4, 5, 1, 1) | |
# setting this widget as central widget of the main window | |
self.setCentralWidget(widget) | |
if __name__ == "__main__": | |
constellations_df = pd.DataFrame( | |
( | |
{ | |
"constellation": np.random.normal(size=(64,2)), | |
"epoch": e, | |
"information_rate": "0.1", | |
"labels": list(str(v)[2:].upper() for v in vhex(np.arange(64))), | |
} | |
for e in range(1000) | |
), | |
dtype=object, | |
) | |
start_epoch = int(constellations_df["epoch"].min()) | |
end_epoch = int(constellations_df["epoch"].max()) | |
constellation_size = ( | |
constellations_df[constellations_df["epoch"] == 1]["constellation"] | |
.iloc[0] | |
.shape[0] | |
) | |
# create pyqt5 app | |
App = QApplication(sys.argv) | |
# create the instance of our Window | |
window = Window(start_epoch, end_epoch, constellations_df, constellation_size) | |
# start the app | |
sys.exit(App.exec()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment