From 764a4250cfb7517fca38c2863711e5da10336b93 Mon Sep 17 00:00:00 2001 From: JOAN VINYALS YLLA CATALA Date: Tue, 3 Sep 2024 15:07:14 +0200 Subject: [PATCH 1/4] Add TALP::Tree backend post processing --- .../post_process/nesmik_talp_tree_viewer.py | 162 ++++++++++++++++++ .../post_process/requirements.txt | 1 + 2 files changed, 163 insertions(+) create mode 100644 src/backends/dlb_talp_tree/post_process/nesmik_talp_tree_viewer.py create mode 100644 src/backends/dlb_talp_tree/post_process/requirements.txt diff --git a/src/backends/dlb_talp_tree/post_process/nesmik_talp_tree_viewer.py b/src/backends/dlb_talp_tree/post_process/nesmik_talp_tree_viewer.py new file mode 100644 index 0000000..01ab746 --- /dev/null +++ b/src/backends/dlb_talp_tree/post_process/nesmik_talp_tree_viewer.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python3 + +import sys +import json + +try: + from PySide6.QtWidgets import QApplication, QTreeView, QMainWindow, QVBoxLayout, QWidget + from PySide6.QtGui import QStandardItemModel, QStandardItem, QColor, QBrush + from PySide6 import QtCore +except ModuleNotFoundError: + print("Error loading MODULES") + print("") + print("Please run `pip install -r requirements.txt`") + print("\tWhich can be found at the same path as this script.") + exit(1) + +# Header Format Operation Width Alignment Gradient +headings= { + ("regionName", 1): ("Region", "{}{}", (lambda x,y: x), 400, QtCore.Qt.AlignLeft, False), + ("elapsedTime", 1): ("Time (s)", "{:11.2f}", (lambda x,y: x / 1000000000), 100, QtCore.Qt.AlignRight, False), + ("elapsedTime", 2): ("Time (%)", "{:11.2f}", (lambda x,y: x / y), 100, QtCore.Qt.AlignRight, False), + ("mpiParallelEfficiency", 1): ("MPI-PE", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), + ("mpiCommunicationEfficiency",1): ("MPI-COM", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), + ("mpiLoadBalance", 1): ("MPI-LB", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), + ("mpiLoadBalanceIn", 1): ("MPI-LBI", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), + ("mpiLoadBalanceOut", 1): ("MPI-LBO", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), + ("ompParallelEfficiency", 1): ("OMP-PE", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), + ("ompSchedulingEfficiency", 1): ("OMP-LB", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), + ("ompSerializationEfficiency", 1): ("OMP-SCH", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), + ("parallelEfficiency", 1): ("OMP-SER", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True) +} + +def parse_nesmik_talp_tree_json_file(filename): + with open(filename, 'r') as file: + json_data = json.load(file) + return json_data + raise Exception("Could not parse json: {}".format(filename)) + + +def construct_header_row(headings): + return [ heading[0][0] for heading in headings.values() ] + + +class TreeTable(QMainWindow): + def __init__(self, json_data): + super().__init__() + + self.json_data = json_data; + self.root_elapsed_time = None + + # Set up the main window + self.setWindowTitle("neSmiK TALP::Tree") + window_width=sum([ heading[3] for heading in headings.values() ]) + 20 + self.setGeometry(100, 100, window_width, 800) + + # Create the tree view and model + self.tree_view = QTreeView() + self.tree_view.setAlternatingRowColors(True) + + self.model = QStandardItemModel() + self.model.setHorizontalHeaderLabels(construct_header_row(headings)) + self.tree_view.setModel(self.model) + + # Set fixed column widths + for (column, width) in enumerate([ heading[3] for heading in headings.values() ]): + self.tree_view.setColumnWidth(column, width) + + # Create the tree structure with color gradients + self.add_tree_data() + + # Set the layout + container = QWidget() + layout = QVBoxLayout() + layout.addWidget(self.tree_view) + container.setLayout(layout) + self.setCentralWidget(container) + + def populate_tree_view(self, json_data, parent): + row_items = self.construct_row(json_data) + parent.appendRow(row_items) + #parent.setExpanded(0, True) + for subregion in sorted(json_data["subregions"], key=lambda region: region["metrics"]["elapsedTime"], reverse=True): + self.populate_tree_view(subregion, row_items[0]) + + def add_tree_data(self): + # Root item + root_item = self.model.invisibleRootItem() + + # Add data with gradients + self.populate_tree_view(self.json_data, root_item) + + def format_value(self, key, data): + value = headings[key][1].format(headings[key][2](data[key], self.root_elapsed_time)) + item = QStandardItem(value) + item.setTextAlignment(headings[key][4]) + if headings[key][5]: + self.apply_gradient_value(item, value) + #else: + # self.apply_gradient_weight(item) + + return item + + def format_region_name(self, region_name): + item = QStandardItem(region_name) + item.setTextAlignment(headings["regionName"][4]) + #self.apply_gradient_weight(item) + return item + + def construct_row(self, json_data): + if self.root_elapsed_time == None: + self.root_elapsed_time = json_data["metrics"]["elapsedTime"] + self.current_opacity = (json_data["metrics"]["elapsedTime"] / self.root_elapsed_time) * 200 + 55 + + row = [self.format_value(key, json_data["metrics"]) for key in headings.keys() if key != "regionName" ] + row.insert(0, self.format_region_name(json_data["regionName"])) + return row + + def add_row(self, values, parent_item): + row_items = [] + for value in values: + item = QStandardItem(str(value)) + item.setTextAlignment(QtCore.Qt.AlignRight) + self.apply_gradient(item,value) + row_items.append(item) + parent_item.appendRow(row_items) + return row_items[0] + + def apply_gradient_value(self, item, value): + try: + # Try to convert to float + float_value=float(value) + + normalized_value = min(max(float_value, 0), 100) / 100.0 + + # Color gradient from red (low) to green (high) + red = int(255 * (1 - normalized_value)) + green = int(255 * normalized_value) + blue = 0 + + # Apply the background color + color = QColor(red, green, blue, self.current_opacity) + #color = QColor(red, green, blue) + item.setBackground(QBrush(color)) + except ValueError: + return + + def apply_gradient_weight(self, item): + # Color gradient from red (low) to green (high) + red = 0 + green = 0 + blue = 127 + + # Apply the background color + color = QColor(red, green, blue, self.current_opacity) + item.setBackground(QBrush(color)) + + +if __name__ == "__main__": + app = QApplication(sys.argv) + window = TreeTable(parse_nesmik_talp_tree_json_file(sys.argv[1])) + window.show() + sys.exit(app.exec()) diff --git a/src/backends/dlb_talp_tree/post_process/requirements.txt b/src/backends/dlb_talp_tree/post_process/requirements.txt new file mode 100644 index 0000000..5d0142e --- /dev/null +++ b/src/backends/dlb_talp_tree/post_process/requirements.txt @@ -0,0 +1 @@ +PySide6==6.7.2 -- GitLab From a6a4d308aea6f6521c3e52043d01aad7ce5af3dd Mon Sep 17 00:00:00 2001 From: JOAN VINYALS YLLA CATALA Date: Tue, 3 Sep 2024 16:07:31 +0200 Subject: [PATCH 2/4] Fix error in metrics report! --- .../post_process/nesmik_talp_tree_viewer.py | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/src/backends/dlb_talp_tree/post_process/nesmik_talp_tree_viewer.py b/src/backends/dlb_talp_tree/post_process/nesmik_talp_tree_viewer.py index 01ab746..ac64b5c 100644 --- a/src/backends/dlb_talp_tree/post_process/nesmik_talp_tree_viewer.py +++ b/src/backends/dlb_talp_tree/post_process/nesmik_talp_tree_viewer.py @@ -14,20 +14,21 @@ except ModuleNotFoundError: print("\tWhich can be found at the same path as this script.") exit(1) + # Header Format Operation Width Alignment Gradient headings= { - ("regionName", 1): ("Region", "{}{}", (lambda x,y: x), 400, QtCore.Qt.AlignLeft, False), - ("elapsedTime", 1): ("Time (s)", "{:11.2f}", (lambda x,y: x / 1000000000), 100, QtCore.Qt.AlignRight, False), - ("elapsedTime", 2): ("Time (%)", "{:11.2f}", (lambda x,y: x / y), 100, QtCore.Qt.AlignRight, False), - ("mpiParallelEfficiency", 1): ("MPI-PE", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), - ("mpiCommunicationEfficiency",1): ("MPI-COM", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), - ("mpiLoadBalance", 1): ("MPI-LB", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), - ("mpiLoadBalanceIn", 1): ("MPI-LBI", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), - ("mpiLoadBalanceOut", 1): ("MPI-LBO", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), - ("ompParallelEfficiency", 1): ("OMP-PE", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), - ("ompSchedulingEfficiency", 1): ("OMP-LB", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), - ("ompSerializationEfficiency", 1): ("OMP-SCH", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), - ("parallelEfficiency", 1): ("OMP-SER", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True) + "regionName": ("Region", "{}{}", (lambda x,y: x), 400, QtCore.Qt.AlignLeft, False), + "elapsedTime": ("Time (%)", "{:11.2f}", (lambda x,y: 100 * x / y), 100, QtCore.Qt.AlignRight, False), + "parallelEfficiency": ("PE", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), + "mpiParallelEfficiency": ("MPI-PE", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), + "mpiCommunicationEfficiency": ("MPI-COM", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), + "mpiLoadBalance": ("MPI-LB", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), + "mpiLoadBalanceIn": ("MPI-LBI", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), + "mpiLoadBalanceOut": ("MPI-LBO", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), + "ompParallelEfficiency": ("OMP-PE", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), + "ompLoadBalance": ("OMP-LB", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), + "ompSchedulingEfficiency": ("OMP-SCH", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), + "ompSerializationEfficiency": ("OMP-SER", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), } def parse_nesmik_talp_tree_json_file(filename): @@ -38,7 +39,7 @@ def parse_nesmik_talp_tree_json_file(filename): def construct_header_row(headings): - return [ heading[0][0] for heading in headings.values() ] + return [ heading[0] for heading in headings.values() ] class TreeTable(QMainWindow): @@ -75,19 +76,25 @@ class TreeTable(QMainWindow): container.setLayout(layout) self.setCentralWidget(container) - def populate_tree_view(self, json_data, parent): + def populate_tree_view(self, json_data, parent, parent_index): row_items = self.construct_row(json_data) parent.appendRow(row_items) - #parent.setExpanded(0, True) + + percent_of_time = json_data["metrics"]["elapsedTime"] / self.root_elapsed_time + row_count = self.model.rowCount(parent_index) + my_index = self.model.index(row_count-1, 0, parent_index) + if percent_of_time >= 0.01: + self.tree_view.expand(my_index) + for subregion in sorted(json_data["subregions"], key=lambda region: region["metrics"]["elapsedTime"], reverse=True): - self.populate_tree_view(subregion, row_items[0]) + self.populate_tree_view(subregion, row_items[0], my_index) def add_tree_data(self): # Root item root_item = self.model.invisibleRootItem() # Add data with gradients - self.populate_tree_view(self.json_data, root_item) + self.populate_tree_view(self.json_data, root_item, self.model.index(0,0)) def format_value(self, key, data): value = headings[key][1].format(headings[key][2](data[key], self.root_elapsed_time)) -- GitLab From 29340af9b34eec2ce141f74b2c989a90f6eb3695 Mon Sep 17 00:00:00 2001 From: JOAN VINYALS YLLA CATALA Date: Tue, 3 Sep 2024 17:43:18 +0200 Subject: [PATCH 3/4] Add export as image option --- .../post_process/nesmik_talp_tree_viewer.py | 39 ++++++++++++------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/src/backends/dlb_talp_tree/post_process/nesmik_talp_tree_viewer.py b/src/backends/dlb_talp_tree/post_process/nesmik_talp_tree_viewer.py index ac64b5c..3116717 100644 --- a/src/backends/dlb_talp_tree/post_process/nesmik_talp_tree_viewer.py +++ b/src/backends/dlb_talp_tree/post_process/nesmik_talp_tree_viewer.py @@ -1,17 +1,19 @@ #!/usr/bin/env python3 +import os import sys import json try: - from PySide6.QtWidgets import QApplication, QTreeView, QMainWindow, QVBoxLayout, QWidget - from PySide6.QtGui import QStandardItemModel, QStandardItem, QColor, QBrush + from PySide6.QtWidgets import QApplication, QTreeView, QMainWindow, QVBoxLayout, QWidget, QPushButton + from PySide6.QtGui import QStandardItemModel, QStandardItem, QColor, QBrush, QPixmap from PySide6 import QtCore + from PySide6.QtCore import QRect except ModuleNotFoundError: print("Error loading MODULES") print("") print("Please run `pip install -r requirements.txt`") - print("\tWhich can be found at the same path as this script.") + print("") exit(1) @@ -30,22 +32,21 @@ headings= { "ompSchedulingEfficiency": ("OMP-SCH", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), "ompSerializationEfficiency": ("OMP-SER", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), } - -def parse_nesmik_talp_tree_json_file(filename): - with open(filename, 'r') as file: - json_data = json.load(file) - return json_data - raise Exception("Could not parse json: {}".format(filename)) - +# "elapsedTime": ("Time (s)", "{:11.2f}", (lambda x,y: x / 1000000000), 100, QtCore.Qt.AlignRight, False), def construct_header_row(headings): return [ heading[0] for heading in headings.values() ] class TreeTable(QMainWindow): - def __init__(self, json_data): + def __init__(self, filename): super().__init__() + self.filename = filename + + with open(filename, 'r') as file: + json_data = json.load(file) + self.json_data = json_data; self.root_elapsed_time = None @@ -69,10 +70,14 @@ class TreeTable(QMainWindow): # Create the tree structure with color gradients self.add_tree_data() + self.export_button = QPushButton("Export as Image") + self.export_button.clicked.connect(self.export_as_image) + # Set the layout container = QWidget() layout = QVBoxLayout() layout.addWidget(self.tree_view) + layout.addWidget(self.export_button) container.setLayout(layout) self.setCentralWidget(container) @@ -116,7 +121,7 @@ class TreeTable(QMainWindow): def construct_row(self, json_data): if self.root_elapsed_time == None: self.root_elapsed_time = json_data["metrics"]["elapsedTime"] - self.current_opacity = (json_data["metrics"]["elapsedTime"] / self.root_elapsed_time) * 200 + 55 + self.current_opacity = (json_data["metrics"]["elapsedTime"] / self.root_elapsed_time) * 200 + 20 row = [self.format_value(key, json_data["metrics"]) for key in headings.keys() if key != "regionName" ] row.insert(0, self.format_region_name(json_data["regionName"])) @@ -161,9 +166,17 @@ class TreeTable(QMainWindow): color = QColor(red, green, blue, self.current_opacity) item.setBackground(QBrush(color)) + def export_as_image(self): + rect = self.tree_view.viewport().rect() + + pixmap = QPixmap(rect.size()) + self.tree_view.render(pixmap) + + pixmap.save(os.path.splitext(self.filename)[0]+'.png') + if __name__ == "__main__": app = QApplication(sys.argv) - window = TreeTable(parse_nesmik_talp_tree_json_file(sys.argv[1])) + window = TreeTable(sys.argv[1]) window.show() sys.exit(app.exec()) -- GitLab From de0177058dc99cf5c0e8883d78743aba7956cac6 Mon Sep 17 00:00:00 2001 From: JOAN VINYALS YLLA CATALA Date: Mon, 16 Sep 2024 08:37:34 +0200 Subject: [PATCH 4/4] Some styling --- .../post_process/nesmik_talp_tree_viewer.py | 63 ++++++++++++------- 1 file changed, 42 insertions(+), 21 deletions(-) diff --git a/src/backends/dlb_talp_tree/post_process/nesmik_talp_tree_viewer.py b/src/backends/dlb_talp_tree/post_process/nesmik_talp_tree_viewer.py index 3116717..a70eb51 100644 --- a/src/backends/dlb_talp_tree/post_process/nesmik_talp_tree_viewer.py +++ b/src/backends/dlb_talp_tree/post_process/nesmik_talp_tree_viewer.py @@ -3,12 +3,15 @@ import os import sys import json +import math try: from PySide6.QtWidgets import QApplication, QTreeView, QMainWindow, QVBoxLayout, QWidget, QPushButton from PySide6.QtGui import QStandardItemModel, QStandardItem, QColor, QBrush, QPixmap from PySide6 import QtCore from PySide6.QtCore import QRect + import matplotlib.pyplot as plt + import matplotlib.colors as mcolors except ModuleNotFoundError: print("Error loading MODULES") print("") @@ -20,17 +23,17 @@ except ModuleNotFoundError: # Header Format Operation Width Alignment Gradient headings= { "regionName": ("Region", "{}{}", (lambda x,y: x), 400, QtCore.Qt.AlignLeft, False), - "elapsedTime": ("Time (%)", "{:11.2f}", (lambda x,y: 100 * x / y), 100, QtCore.Qt.AlignRight, False), - "parallelEfficiency": ("PE", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), - "mpiParallelEfficiency": ("MPI-PE", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), - "mpiCommunicationEfficiency": ("MPI-COM", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), - "mpiLoadBalance": ("MPI-LB", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), - "mpiLoadBalanceIn": ("MPI-LBI", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), - "mpiLoadBalanceOut": ("MPI-LBO", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), - "ompParallelEfficiency": ("OMP-PE", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), - "ompLoadBalance": ("OMP-LB", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), - "ompSchedulingEfficiency": ("OMP-SCH", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), - "ompSerializationEfficiency": ("OMP-SER", "{:11.2f}", (lambda x,y: x * 100), 100, QtCore.Qt.AlignRight, True), + "elapsedTime": ("Time (%)", "{:11.2f}", (lambda x,y: 100 * x / y), 70, QtCore.Qt.AlignRight, True), + "parallelEfficiency": ("PE", "{:11.2f}", (lambda x,y: x * 100), 70, QtCore.Qt.AlignRight, True), + "mpiParallelEfficiency": ("MPI-PE", "{:11.2f}", (lambda x,y: x * 100), 70, QtCore.Qt.AlignRight, True), + "mpiCommunicationEfficiency": ("MPI-COM", "{:11.2f}", (lambda x,y: x * 100), 70, QtCore.Qt.AlignRight, True), + "mpiLoadBalance": ("MPI-LB", "{:11.2f}", (lambda x,y: x * 100), 70, QtCore.Qt.AlignRight, True), + "mpiLoadBalanceIn": ("MPI-LBI", "{:11.2f}", (lambda x,y: x * 100), 70, QtCore.Qt.AlignRight, True), + "mpiLoadBalanceOut": ("MPI-LBO", "{:11.2f}", (lambda x,y: x * 100), 70, QtCore.Qt.AlignRight, True), + "ompParallelEfficiency": ("OMP-PE", "{:11.2f}", (lambda x,y: x * 100), 70, QtCore.Qt.AlignRight, True), + "ompLoadBalance": ("OMP-LB", "{:11.2f}", (lambda x,y: x * 100), 70, QtCore.Qt.AlignRight, True), + "ompSchedulingEfficiency": ("OMP-SCH", "{:11.2f}", (lambda x,y: x * 100), 70, QtCore.Qt.AlignRight, True), + "ompSerializationEfficiency": ("OMP-SER", "{:11.2f}", (lambda x,y: x * 100), 70, QtCore.Qt.AlignRight, True), } # "elapsedTime": ("Time (s)", "{:11.2f}", (lambda x,y: x / 1000000000), 100, QtCore.Qt.AlignRight, False), @@ -121,7 +124,9 @@ class TreeTable(QMainWindow): def construct_row(self, json_data): if self.root_elapsed_time == None: self.root_elapsed_time = json_data["metrics"]["elapsedTime"] - self.current_opacity = (json_data["metrics"]["elapsedTime"] / self.root_elapsed_time) * 200 + 20 + self.current_opacity = (json_data["metrics"]["elapsedTime"] / self.root_elapsed_time) * 100 + self.current_opacity = (math.log(self.current_opacity, 10) / 2) * 155 + 100 + self.current_percent = (json_data["metrics"]["elapsedTime"] / self.root_elapsed_time) * 100 row = [self.format_value(key, json_data["metrics"]) for key in headings.keys() if key != "regionName" ] row.insert(0, self.format_region_name(json_data["regionName"])) @@ -138,16 +143,23 @@ class TreeTable(QMainWindow): return row_items[0] def apply_gradient_value(self, item, value): + + # Set color theme + color_map='RdYlGn' + lower_bound=70 + upper_bound=100 + + norm = mcolors.Normalize(vmin=lower_bound, vmax=upper_bound) + cmap = plt.get_cmap(color_map) + try: # Try to convert to float float_value=float(value) + color = cmap(norm(float_value)) - normalized_value = min(max(float_value, 0), 100) / 100.0 - - # Color gradient from red (low) to green (high) - red = int(255 * (1 - normalized_value)) - green = int(255 * normalized_value) - blue = 0 + red = color[0] * 256 + green = color[1] * 256 + blue = color[2] * 256 # Apply the background color color = QColor(red, green, blue, self.current_opacity) @@ -157,10 +169,19 @@ class TreeTable(QMainWindow): return def apply_gradient_weight(self, item): + # Set color theme + color_map='RdYlGn' + lower_bound=0 + upper_bound=100 + + norm = mcolors.Normalize(vmin=lower_bound, vmax=upper_bound) + cmap = plt.get_cmap(color_map) + + color = cmap(norm(self.current_percent)) # Color gradient from red (low) to green (high) - red = 0 - green = 0 - blue = 127 + red = color[0] * 256 + green = color[1] * 256 + blue = color[2] * 256 # Apply the background color color = QColor(red, green, blue, self.current_opacity) -- GitLab