Skip to content

Commit 71619cc

Browse files
EzetowersEzequiel Torres
authored andcommitted
Added a new Window for the IndividualTreeVisualization
1 parent e332d24 commit 71619cc

File tree

9 files changed

+2203
-1896
lines changed

9 files changed

+2203
-1896
lines changed

MLC/Common/LispTreeExpr/LispTreeExpr.py

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,6 @@
2121

2222
import MLC.Log.log as lg
2323
import networkx as nx
24-
import matplotlib
25-
matplotlib.use("Qt5Agg")
26-
import matplotlib.pyplot as plt
2724
import re
2825

2926
from MLC.mlc_parameters.mlc_parameters import Config
@@ -207,27 +204,10 @@ def simplify_tree(self):
207204
self._simplified_tree = '(root ' + self._root.to_string() + ')'
208205
lg.logger_.debug("[LISP_TREE_EXPR] Simplified Expression: " + self._simplified_tree)
209206

210-
def draw(self):
207+
def construct_graph(self):
211208
tree = nx.DiGraph()
212209
self._root.construct_tree(tree)
213-
214-
fig = plt.figure()
215-
# Put figure window on top of all other windows
216-
fig.canvas.manager.window.setWindowModality(Qt.ApplicationModal)
217-
fig.canvas.manager.window.setWindowTitle("Individual Tree Representation")
218-
ax = fig.add_axes([0, 0, 1, 1])
219-
ax.axis('off')
220-
221-
labels = {}
222-
for node_id in tree:
223-
labels[node_id] = tree.node[node_id]['value']
224-
pos = nx.nx_pydot.graphviz_layout(tree, prog='dot')
225-
226-
nodes = nx.draw_networkx_nodes(tree, pos, node_size=1000, node_color='#D3D3D3')
227-
nodes.set_edgecolor('k')
228-
nx.draw_networkx_edges(tree, pos, arrows=False)
229-
nx.draw_networkx_labels(tree, pos, labels, font_size=12)
230-
plt.show()
210+
return tree
231211

232212
def calculate_expression(self, sensor_replacement_list):
233213
class Replace_Sensors_Visitor(TreeVisitor):

MLC/GUI/Autogenerated/autogenerated.py

Lines changed: 1925 additions & 1851 deletions
Large diffs are not rendered by default.

MLC/GUI/Autogenerated/mlc_qtcreator/experiment.ui

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
<rect>
3232
<x>0</x>
3333
<y>0</y>
34-
<width>933</width>
35-
<height>814</height>
34+
<width>947</width>
35+
<height>796</height>
3636
</rect>
3737
</property>
3838
<layout class="QHBoxLayout" name="horizontalLayout_6">
@@ -42,7 +42,7 @@
4242
<enum>QTabWidget::North</enum>
4343
</property>
4444
<property name="currentIndex">
45-
<number>1</number>
45+
<number>0</number>
4646
</property>
4747
<widget class="QWidget" name="experiment_tab">
4848
<property name="layoutDirection">
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ui version="4.0">
3+
<class>IndividualTreeVisualization</class>
4+
<widget class="QMainWindow" name="IndividualTreeVisualization">
5+
<property name="windowModality">
6+
<enum>Qt::ApplicationModal</enum>
7+
</property>
8+
<property name="geometry">
9+
<rect>
10+
<x>0</x>
11+
<y>0</y>
12+
<width>400</width>
13+
<height>135</height>
14+
</rect>
15+
</property>
16+
<property name="sizePolicy">
17+
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
18+
<horstretch>0</horstretch>
19+
<verstretch>0</verstretch>
20+
</sizepolicy>
21+
</property>
22+
<property name="maximumSize">
23+
<size>
24+
<width>400</width>
25+
<height>135</height>
26+
</size>
27+
</property>
28+
<property name="windowTitle">
29+
<string>Individual Tree Visualization</string>
30+
</property>
31+
<widget class="QWidget" name="centralWidget">
32+
<layout class="QVBoxLayout" name="verticalLayout">
33+
<item>
34+
<widget class="QGroupBox" name="groupBox">
35+
<property name="sizePolicy">
36+
<sizepolicy hsizetype="Minimum" vsizetype="Maximum">
37+
<horstretch>0</horstretch>
38+
<verstretch>0</verstretch>
39+
</sizepolicy>
40+
</property>
41+
<property name="title">
42+
<string>Individual Index</string>
43+
</property>
44+
<property name="flat">
45+
<bool>false</bool>
46+
</property>
47+
<layout class="QGridLayout" name="gridLayout">
48+
<item row="1" column="0">
49+
<widget class="QCheckBox" name="simplify_check">
50+
<property name="text">
51+
<string>Simplify</string>
52+
</property>
53+
</widget>
54+
</item>
55+
<item row="0" column="0" colspan="2">
56+
<widget class="QComboBox" name="indiv_index_combo">
57+
<property name="sizePolicy">
58+
<sizepolicy hsizetype="Minimum" vsizetype="Maximum">
59+
<horstretch>0</horstretch>
60+
<verstretch>0</verstretch>
61+
</sizepolicy>
62+
</property>
63+
</widget>
64+
</item>
65+
<item row="1" column="1">
66+
<widget class="QCheckBox" name="evaluate_check">
67+
<property name="text">
68+
<string>Evaluate</string>
69+
</property>
70+
</widget>
71+
</item>
72+
</layout>
73+
</widget>
74+
</item>
75+
<item>
76+
<widget class="QDialogButtonBox" name="ok_cancel_box">
77+
<property name="sizePolicy">
78+
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
79+
<horstretch>0</horstretch>
80+
<verstretch>0</verstretch>
81+
</sizepolicy>
82+
</property>
83+
<property name="standardButtons">
84+
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
85+
</property>
86+
<property name="centerButtons">
87+
<bool>true</bool>
88+
</property>
89+
</widget>
90+
</item>
91+
</layout>
92+
</widget>
93+
</widget>
94+
<resources/>
95+
<connections>
96+
<connection>
97+
<sender>ok_cancel_box</sender>
98+
<signal>accepted()</signal>
99+
<receiver>IndividualTreeVisualization</receiver>
100+
<slot>on_dialog_button_box_clicked()</slot>
101+
<hints>
102+
<hint type="sourcelabel">
103+
<x>205</x>
104+
<y>114</y>
105+
</hint>
106+
<hint type="destinationlabel">
107+
<x>205</x>
108+
<y>67</y>
109+
</hint>
110+
</hints>
111+
</connection>
112+
<connection>
113+
<sender>ok_cancel_box</sender>
114+
<signal>rejected()</signal>
115+
<receiver>IndividualTreeVisualization</receiver>
116+
<slot>close()</slot>
117+
<hints>
118+
<hint type="sourcelabel">
119+
<x>205</x>
120+
<y>114</y>
121+
</hint>
122+
<hint type="destinationlabel">
123+
<x>205</x>
124+
<y>67</y>
125+
</hint>
126+
</hints>
127+
</connection>
128+
</connections>
129+
<slots>
130+
<slot>on_dialog_button_box_clicked()</slot>
131+
</slots>
132+
</ui>

MLC/GUI/Autogenerated/mlc_qtcreator/mlc_qtcreator.pro

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ FORMS += \
3030
pinout_design.ui \
3131
arduino_performance_test.ui \
3232
about.ui \
33-
generic_spinner.ui
33+
generic_spinner.ui \
34+
individual_tree_visualization.ui
3435

3536
DISTFILES +=

MLC/GUI/Common/util.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,4 @@ def add_permissions_to_file(filepath, permissions, user_password=None):
148148
os.system('sudo -K')
149149
return cmd_error_code == 0
150150
else:
151-
return os.system(cmd) == 0
152-
153-
def get_individual_tree(indiv_value):
154-
return LispTreeExpr(indiv_value)
151+
return os.system(cmd) == 0

MLC/GUI/Experiment/ExperimentWindow.py

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@
3030
from MLC.Log.log import get_gui_logger
3131
from MLC.GUI.Common.util import test_individual_value
3232
from MLC.GUI.Common.util import check_if_indiv_pass_preevaluation
33-
from MLC.GUI.Common.util import get_individual_tree
3433
from MLC.GUI.Autogenerated.autogenerated import Ui_ExperimentWindow
3534
from MLC.GUI.Experiment.ArduinoConfigManager.ArduinoBoardManager import ArduinoBoardManager
3635
from MLC.GUI.Experiment.ChartConfiguration import ChartConfiguration
3736
from MLC.GUI.Experiment.ExperimentInProgress import ExperimentInProgress
3837
from MLC.GUI.Experiment.FirstIndividualsManager import FirstIndividualsManager
3938
from MLC.GUI.Experiment.GenealogyWindow import GenealogyWindow
39+
from MLC.GUI.Experiment.IndividualTreeVisualization import IndividualTreeVisualization
4040
from MLC.GUI.Experiment.MatplotlibCanvas.CostPerIndividualCanvas import CostPerIndividualCanvas
4141
from MLC.GUI.Experiment.QtCharts.QtChartWrapper import QtChartWrapper
4242
from MLC.GUI.Tables.ConfigDictTableModel import ConfigDictTableModel
@@ -465,19 +465,12 @@ def on_genealogy_button_clicked(self):
465465

466466
def on_draw_as_tree_button_clicked(self):
467467
logger.debug('[EXPERIMENT {0}] [DRAW_AS_TREE_BUTTON] - Executing on_genealogy_button_clicked function')
468-
469-
# Ask the user which Individual he would like to have displayed
470-
indivs_per_gen = Config.get_instance().getint("POPULATION", "size")
471-
individuals_list = [str(x) for x in xrange(1, indivs_per_gen + 1)]
472-
473-
indiv = QInputDialog.getItem(self, "Individual Tree",
474-
"Select the individual you would like to draw",
475-
individuals_list, 0, False)
476-
477-
if indiv[1] == True:
478-
gen_data = self._individuals_per_generation[self._current_gen - 1]
479-
indiv_tree = get_individual_tree(gen_data[int(indiv[0])][5])
480-
indiv_tree.draw()
468+
gen_data = self._individuals_per_generation[self._current_gen - 1]
469+
tree_window = IndividualTreeVisualization(self,
470+
experiment_name=self._experiment_name,
471+
gen_data=gen_data,
472+
current_gen=self._current_gen)
473+
tree_window.show()
481474

482475
def on_board_config_button_clicked(self):
483476
logger.debug('[EXPERIMENT {0}] [BOARD_CONFIG_BUTTON] - '
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# -*- coding: utf-8 -*-
2+
# MLC (Machine Learning Control): A genetic algorithm library to solve chaotic problems
3+
# Copyright (C) 2015-2017, Thomas Duriez (thomas.duriez@gmail.com)
4+
# Copyright (C) 2015, Adrian Durán (adrianmdu@gmail.com)
5+
# Copyright (C) 2015-2017, Ezequiel Torres Feyuk (ezequiel.torresfeyuk@gmail.com)
6+
# Copyright (C) 2016-2017, Marco Germano Zbrun (marco.germano@intraway.com)
7+
# Copyright (C) 2016-2017, Raúl Lopez Skuba (raulopez0@gmail.com)
8+
#
9+
# This program is free software: you can redistribute it and/or modify
10+
# it under the terms of the GNU General Public License as published by
11+
# the Free Software Foundation, either version 3 of the License, or
12+
# (at your option) any later version.
13+
#
14+
# This program is distributed in the hope that it will be useful,
15+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
# GNU General Public License for more details.
18+
#
19+
# You should have received a copy of the GNU General Public License
20+
# along with this program. If not, see <http://www.gnu.org/licenses/>
21+
22+
# -*- coding: utf-8 -*-
23+
24+
import matplotlib
25+
matplotlib.use("Qt5Agg")
26+
import matplotlib.pyplot as plt
27+
import networkx as nx
28+
import os
29+
import sys
30+
31+
from MLC.Common.LispTreeExpr.LispTreeExpr import LispTreeExpr
32+
from MLC.GUI.Common.util import test_individual_value
33+
from MLC.GUI.Autogenerated.autogenerated import Ui_IndividualTreeVisualization
34+
from MLC.Log.log import get_gui_logger
35+
from MLC.mlc_parameters.mlc_parameters import Config
36+
37+
from PyQt5.QtCore import QPointF
38+
# from PyQt5.QtGui import QFont
39+
from PyQt5.QtCore import Qt
40+
from PyQt5.QtWidgets import QMainWindow
41+
42+
logger = get_gui_logger()
43+
44+
class IndividualTreeVisualization(QMainWindow):
45+
46+
def __init__(self, parent, experiment_name, current_gen, gen_data):
47+
QMainWindow.__init__(self, parent)
48+
self._experiment_name = experiment_name
49+
self._log_prefix = "[INDIV_TREE_VISUALIZATION_WINDOW]"
50+
self._gen_data = gen_data
51+
self._current_gen = current_gen
52+
53+
# Store the GUI objects references to easily access them
54+
self._autogenerated_object = Ui_IndividualTreeVisualization()
55+
self._autogenerated_object.setupUi(self)
56+
self._indiv_index_combo = self._autogenerated_object.indiv_index_combo
57+
self._simplify_check = self._autogenerated_object.simplify_check
58+
self._evaluate_check = self._autogenerated_object.evaluate_check
59+
60+
self._indiv_index_combo.addItems([str(x + 1) for x in xrange(len(self._gen_data))])
61+
62+
def on_dialog_button_box_clicked(self):
63+
logger.debug('{0} [DIALOG_BUTTON_CLICKED] - Executing on_dialog_button_box_clicked function'
64+
.format(self._log_prefix))
65+
66+
pop_index = int(self._indiv_index_combo.currentText()) - 1
67+
indiv_index = self._gen_data[pop_index][1]
68+
value = self._gen_data[pop_index][5]
69+
70+
self._draw_individual_tree(pop_index=pop_index,
71+
indiv_index=indiv_index,
72+
simplify=self._simplify_check.isChecked(),
73+
evaluate=self._evaluate_check.isChecked(),
74+
value=value)
75+
76+
def _draw_individual_tree(self,
77+
pop_index,
78+
indiv_index,
79+
simplify,
80+
evaluate,
81+
value):
82+
fig = plt.figure()
83+
# Put figure window on top of all other windows
84+
fig.canvas.manager.window.setWindowModality(Qt.ApplicationModal)
85+
fig.canvas.manager.window.setWindowTitle("Individual Tree Representation")
86+
87+
# Simplify the tree if neccesary
88+
tree = LispTreeExpr(value)
89+
if simplify == True:
90+
tree.simplify_tree()
91+
graph = tree.construct_graph()
92+
93+
# Evaluate the Individual if necessary
94+
cost = None
95+
if evaluate == True:
96+
cost = test_individual_value(parent=self,
97+
experiment_name=self._experiment_name,
98+
log_prefix=self._log_prefix,
99+
indiv_value=value,
100+
config=Config.get_instance())
101+
102+
# Remove image axes
103+
ax = fig.add_axes([0, 0, 1, 1])
104+
ax.axis('off')
105+
106+
# Networkx use the node id as label. We have to relabel every node
107+
labels = {}
108+
for node_id in graph:
109+
labels[node_id] = graph.node[node_id]['value']
110+
111+
# Use Pygraph to visualize the graph as a hierarchical tree
112+
pos = nx.nx_pydot.graphviz_layout(graph, prog='dot')
113+
114+
# Draw nodes and edges in separated nodes to be able to change
115+
# the perimter color of the nodes
116+
nodes = nx.draw_networkx_nodes(graph, pos, node_size=1000, node_color='#D3D3D3')
117+
nodes.set_edgecolor('k')
118+
nx.draw_networkx_edges(graph, pos, arrows=False)
119+
nx.draw_networkx_labels(graph, pos, labels, font_size=12)
120+
121+
# Set the figure Title
122+
plt.rc('font', family='serif')
123+
title = (u"Generation N°{0} - Individual N°{1} - Simplified: {2}"
124+
.format(self._current_gen, indiv_index, simplify))
125+
126+
if evaluate == True:
127+
title += " - Cost: {0}".format(cost)
128+
129+
plt.suptitle(title, fontsize=12)
130+
plt.show()
131+
self.close()

bugs/precision_bug/expr_test.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ def initialize_config():
5252
expr612 = "(root (- -6.3726 (* -7.1746 S0)))"
5353

5454
tree = LispTreeExpr(expr6)
55-
tree.draw()
5655
x = np.linspace(-10.0, 10.0, num=201)
5756
mlc_y = tree.calculate_expression([x])
5857

0 commit comments

Comments
 (0)