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 ()
0 commit comments