Commit 8f86b4b6 authored by LIGNEUL CLEMENT's avatar LIGNEUL CLEMENT
Browse files

add update plot

parent 1821b2e0
......@@ -4,13 +4,35 @@ from pandas.io.parsers import read_csv
import plotly.express as px
import sys
if len(sys.argv) != 4:
print(
"Usage : " + sys.argv[0] + " <nb of generations> <nb of plots> <csv file>",
file=sys.stderr,
)
# arguments [nb_gen, nb_plots, csv_file, title, f1, f2, f3]
if len(sys.argv) != 8:
# print(
# "Usage : " + sys.argv[0] + " <nb of generations> <nb of plots> <csv file>",
# file=sys.stderr,
# )
exit(1)
if sys.argv[4] :
titre = sys.argv[4]
else :
titre = "Results"
if sys.argv[5] :
name_x = sys.argv[5]
else :
name_x = "f1"
if sys.argv[6] :
name_y = sys.argv[6]
else :
name_y = "f2"
if sys.argv[7] :
name_z = sys.argv[7]
else :
name_z = "f3"
df = read_csv(
sys.argv[3], header=0, delimiter=" ", usecols=[0, 1, 2], names=["f1", "f2", "f3"]
)
......@@ -20,9 +42,12 @@ fig = px.scatter_3d(
)
fig.update_layout(
title="Results",
title= titre,
margin=dict(l=65, r=0, b=10, t=90),
scene=dict(
xaxis_title=name_x,
yaxis_title=name_y,
zaxis_title=name_z,
xaxis=dict(
backgroundcolor="rgb(200,200,255)",
gridcolor="white",
......
// index.ts
import { QTabWidget, QIcon, QMainWindow, QWidget, WidgetEventTypes, QMenu } from '@nodegui/nodegui';
import { spawn, ChildProcess } from 'child_process';
import { Compile } from './compile_tab';
......@@ -11,15 +13,17 @@ import os from 'os';
import { exit } from 'process';
// arrays of running child processes
/** arrays of running child processes */
export let running_proc: ChildProcess[] = [];
/** @remarks arrays of plotting child processes */
export let running_plot: ChildProcess[] = [];
// main window
/** main window */
const global_win = new QMainWindow();
global_win.setWindowTitle("EASEA Compiler");
// main widget
/** main widget */
const centralWidget = new QWidget();
const general_layout = new QGridLayout();
......@@ -41,7 +45,7 @@ help_action.addEventListener('triggered', () => {
command = 'open';
}
// spawn(command, ['https://git.unistra.fr/ligneul/easea-compiler-app'], { detached: true });
spawn(command, [process.cwd() + '/documentation/doc_en.html'], { detached: true });
spawn(command, [process.cwd() + '/documentation/manual/doc_en.html'], { detached: true });
});
const EASEA_action = new QAction();
......
......@@ -5,12 +5,13 @@ import plotly.graph_objects as go
import sys
from math import ceil
# parameters = [nb_gen, nb_plots, title]
# if len(sys.argv) != 3:
# print(
# "Usage : " + sys.argv[0] + " <nb of generations> <nb of plots>", file=sys.stderr
# )
# exit(1)
if len(sys.argv) != 4:
print(
"Usage : " + sys.argv[0] + " <nb of generations> <nb of plots>", file=sys.stderr
)
exit(1)
# number of generations
nb_gen = int(sys.argv[1])
......@@ -18,6 +19,13 @@ nb_gen = int(sys.argv[1])
# number of violin plots
nb_plots = int(sys.argv[2])
# plot title
if sys.argv[3]:
titre = sys.argv[3]
else :
titre = "Results"
treshold = ceil(nb_gen / nb_plots)
df = read_csv("plotting/data.csv")
......@@ -45,7 +53,7 @@ fig.update_traces(box_visible=True, meanline_visible=True, points="all")
fig.update_layout(
title={
"text": "Fitness through generations",
"text": titre,
"y": 0.9,
"x": 0.5,
"xanchor": "center",
......
......@@ -5,6 +5,7 @@ import { running_plot } from "./index";
import { run_obj } from './index'
import os from 'os'
import { Win_alert } from "./win_alert";
import { Update_graph_win } from "./update_graph_win";
const SCRIPT_2D_PATH = 'src/plot.py';
......@@ -19,7 +20,9 @@ export class Plot_result {
btn_widget: QWidget;
save_static_btn: QPushButton;
save_interactive_btn: QPushButton;
update_graph: QPushButton;
scroll_image: QScrollArea;
update_label: QLabel;
constructor() {
this.widget = new QWidget();
......@@ -29,17 +32,19 @@ export class Plot_result {
this.image_label = new QLabel();
this.save_static_btn = new QPushButton();
this.save_interactive_btn = new QPushButton();
this.update_graph = new QPushButton();
this.scroll_image = new QScrollArea();
this.btn_widget = new QWidget();
this.update_label = new QLabel();
}
update_plot(path: string, plot_size: number, type: string, ez_path: string) {
update_plot(path: string, plot_size: number, type: string, csv_path: string, title: string, x_name: string, y_name: string, z_name: string) {
var run: ChildProcess;
var nb_gen = run_obj.option_obj.nb_gen
var plot_path = '';
if (type === '') {
if (type === '2D') {
if (existsSync(SCRIPT_2D_PATH)) {
plot_path = 'src/plot.py';
} else if (existsSync('plot.py')) {
......@@ -49,7 +54,7 @@ export class Plot_result {
this.image_label.setText('Error : plot script not found');
console.log('Error : plot script not found');
}
} else {
} else if (type === '3D') {
if (existsSync(SCRIPT_3D_PATH)) {
plot_path = 'src/3D_plot.py';
} else if (existsSync('3D_plot.py')) {
......@@ -64,10 +69,26 @@ export class Plot_result {
if (isNaN(nb_gen)) {
var val = this.get_generations(run_obj.ez_file_address);
console.log('nb gen detected in file : ' + val);
val === -1 ? nb_gen = 30 : nb_gen = val;
if(val === -1){
nb_gen = 30;
} else{
nb_gen = val;
run_obj.total_generations = val;
}
} else {
run_obj.total_generations = nb_gen;
}
run = spawn('python3', [plot_path, nb_gen.toString(), plot_size.toString(), ez_path], { timeout: 20000 });
console.log('updating plot...');
this.btn_widget.setEnabled(false);
if(type === '2D'){
run = spawn('python3', [plot_path, nb_gen.toString(), plot_size.toString(), title], { timeout: 20000 });
} else if(type === '3D'){
run = spawn('python3', [plot_path, nb_gen.toString(), plot_size.toString(), csv_path, title, x_name, y_name, z_name], { timeout: 20000 });
} else {
return;
}
running_plot.push(run);
......@@ -76,7 +97,7 @@ export class Plot_result {
console.log(data);
});
run.stdout?.on('data', (data) => {
run.stderr?.on('data', (data) => {
console.log('Plot script : ');
console.log(data);
});
......@@ -92,6 +113,7 @@ export class Plot_result {
this.image_label.setPixmap(this.image.scaled(800, 500));
this.image_label.setFixedSize(800, 500);
this.btn_widget.show();
this.update_label.hide();
} else {
this.image_label.setFixedSize(200, 30);
this.image_label.setText('Error : graph not found');
......@@ -115,6 +137,8 @@ export class Plot_result {
run_obj.running_label.setText('Interrupted');
run_obj.running_label.show();
}
this.btn_widget.setEnabled(true);
});
}
......@@ -192,11 +216,26 @@ export class Plot_result {
}
});
// updating label
this.update_label.setText('updating ...');
// this.update_label.setFixedSize(80,30);
this.update_label.setAlignment(AlignmentFlag.AlignCenter);
this.update_label.hide();
// update graph button
const graph_option = new Update_graph_win();
this.update_graph.setFixedSize(150, 30);
this.update_graph.setText('Update Plot');
this.update_graph.addEventListener('clicked', () =>{
graph_option.execution();
});
btn_layout.addWidget(this.save_static_btn);
btn_layout.addWidget(this.update_graph);
btn_layout.addWidget(this.save_interactive_btn);
this.btn_widget.hide();
// graph
// static graph
this.image_label.setPixmap(this.image);
this.image_label.setText('No graph to display');
......@@ -212,7 +251,8 @@ export class Plot_result {
this.scroll_image.setAlignment(AlignmentFlag.AlignCenter);
this.layout.addWidget(this.scroll_image, 0, 0);
this.layout.addWidget(this.btn_widget, 1, 0);
this.layout.addWidget(this.update_label, 1, 0);
this.layout.addWidget(this.btn_widget, 2, 0);
return this.layout;
}
......
......@@ -192,7 +192,7 @@ export class Pseudo_term {
run_obj.running_label.setText('Plotting results ...');
run_obj.running_label.show();
plot_obj.update_plot(process.cwd() + '/plotting/fig.svg', plot_size, type, run_obj.dir_path + '/objectives');
plot_obj.update_plot(process.cwd() + '/plotting/fig.svg', plot_size, type, run_obj.dir_path + '/objectives', '', '', '', '');
console.log("child process terminated with code " + code);
run_obj.finished_label.setText('Completed Runs : ' + (run_obj.batch_size - running_proc.length) + '/' + run_obj.batch_size);
......
......@@ -598,7 +598,7 @@ export class Run_options {
errors.push('First GPU NOT used for computation');
}
if (ok !== 0) {
if (ok) {
this.window.close();
} else {
util.print_errors(errors);
......
......@@ -33,6 +33,8 @@ export class Run_tab {
finished_label: QLabel = new QLabel();
nb_plots: number = 1;
progress_bar: QProgressBar = new QProgressBar();
plot_type: string = '2D';
total_generations: number = 0;
// buttons
activate_island_model: QCheckBox = new QCheckBox();
......@@ -340,21 +342,15 @@ export class Run_tab {
if (!isNaN(this.parent_obj.reduce_pressure) && this.parent_obj.reduce_pressure !== 2)
this.options = this.options.concat(' --reduceParentsPressure ' + this.parent_obj.reduce_pressure.toString());
// run starts here
if (compile_obj.nsgaii) {
var run = output_run.run(cmd, this.nb_plots, 'nsgaii', this.options, this.dir_path, i + 1);
} else if (compile_obj.nsgaiii) {
var run = output_run.run(cmd, this.nb_plots, 'nsgaiii', this.options, this.dir_path, i + 1);
} else if (compile_obj.asrea) {
var run = output_run.run(cmd, this.nb_plots, 'asrea', this.options, this.dir_path, i + 1);
} else if (compile_obj.ibea) {
var run = output_run.run(cmd, this.nb_plots, 'ibea', this.options, this.dir_path, i + 1);
} else if (compile_obj.cdas) {
var run = output_run.run(cmd, this.nb_plots, 'cdas', this.options, this.dir_path, i + 1);
// start runs here
if (compile_obj.nsgaii || compile_obj.nsgaiii || compile_obj.asrea || compile_obj.ibea || compile_obj.cdas){
this.plot_type = '3D';
} else {
var run = output_run.run(cmd, this.nb_plots, '', this.options, this.dir_path, i + 1);
this.plot_type = '2D';
}
var run = output_run.run(cmd, this.nb_plots, this.plot_type, this.options, this.dir_path, i + 1);
if (i === 0)
initial_proc = run;
......
import { QBoxLayout, QDialog, QGridLayout, QLineEdit, QPushButton, QWidget, WindowType } from "@nodegui/nodegui";
import { plot_obj, run_obj } from ".";
import { Advanced_option_widget } from "./advanced_option_widget";
import * as util from './utilities';
import { general_css } from "./style";
export class Update_graph_win {
window: QDialog;
title: string;
x_axis: string;
y_axis: string;
z_axis: string;
nb_plots: number;
changed: boolean = false;
constructor(){
this.window = new QDialog();
this.title = 'Results';
this.x_axis = 'f1';
this.y_axis = 'f2';
this.z_axis = 'f3';
this.nb_plots = 1;
this.window.setWindowTitle('Plot Parameters');
this.window.setWindowFlag(WindowType.CustomizeWindowHint, true);
this.window.setWindowFlag(WindowType.WindowCloseButtonHint, false);
const layout = new QBoxLayout(2);
this.window.setLayout(layout);
const title_box = new Advanced_option_widget('Plot Title : ', 0, 'Results');
title_box.text_edit.addEventListener('textChanged', () => {
var text = title_box.text_edit.text();
if(!text){
this.title = 'Results';
} else {
this.title = text;
}
});
const axe_x_box = new Advanced_option_widget('x axis name : ', 0, 'f1');
axe_x_box.text_edit.addEventListener('textChanged', () => {
var text = axe_x_box.text_edit.text();
if(!text){
this.x_axis = 'f1';
} else {
this.x_axis = text;
}
});
const axe_y_box = new Advanced_option_widget('y axis name : ', 0, 'f2');
axe_y_box.text_edit.addEventListener('textChanged', () => {
var text = axe_y_box.text_edit.text();
if(!text){
this.y_axis = 'f2';
} else {
this.y_axis = text;
}
});
const axe_z_box = new Advanced_option_widget('z axis name : ', 0, 'f3');
axe_z_box.text_edit.addEventListener('textChanged', () => {
var text = axe_z_box.text_edit.text();
if(!text){
this.z_axis = 'f3';
} else {
this.z_axis = text;
}
});
const plots = new Advanced_option_widget('Nb Plots : ', 0, '1');
plots.text_edit.addEventListener('textChanged', () => {
var val = Number(plots.text_edit.text());
if(isNaN(val) || val < 1 || val > run_obj.total_generations ){
this.nb_plots = 1;
} else {
this.nb_plots = val;
}
});
// buttons
const btn_widget = new QWidget();
const btn_layout = new QGridLayout();
const save_btn = new QPushButton();
save_btn.setText('Update');
save_btn.setFixedSize(100, 25);
save_btn.addEventListener('clicked', () => {
var errors = [];
var ok = 1;
var nplots = Number(plots.text_edit.text())
if(isNaN(nplots) || nplots > run_obj.total_generations || nplots < 1 && plots.text_edit.text()){
errors.push('Number of plots (must be \u2264 nb generations)');
ok = 0;
}
if(run_obj.plot_type === '3D' && plots.text_edit.text()){
errors.push('Number of plots available only for 2D graphs');
ok = 0;
}
if(run_obj.plot_type === '2D'){
if(axe_x_box.text_edit.text()){
errors.push('x axis name only available for 3D graphs');
ok = 0;
}
if(axe_y_box.text_edit.text()){
errors.push('y axis name only available for 3D graphs');
ok = 0;
}
if(axe_z_box.text_edit.text()){
errors.push('z Axis name only available for 3D graphs');
ok = 0;
}
}
if(ok){
this.changed = true;
this.window.close();
} else {
util.print_errors(errors);
}
});
const close_btn = new QPushButton();
close_btn.setText('Close');
close_btn.setFixedSize(100, 25);
close_btn.addEventListener('clicked', () => {
this.changed = false;
this.window.close();
});
const reset_btn = new QPushButton();
reset_btn.setText('Reset');
reset_btn.setFixedSize(100, 25);
reset_btn.addEventListener('clicked', () => {
title_box.text_edit.clear();
axe_x_box.text_edit.clear();
axe_y_box.text_edit.clear();
axe_z_box.text_edit.clear();
plots.text_edit.clear();
});
btn_layout.addWidget(save_btn, 0, 0);
btn_layout.addWidget(reset_btn, 0, 3);
btn_layout.addWidget(close_btn,0,1);
btn_widget.setLayout(btn_layout);
//display
layout.addWidget(title_box.widget);
layout.addWidget(axe_x_box.widget);
layout.addWidget(axe_y_box.widget);
layout.addWidget(axe_z_box.widget);
layout.addWidget(plots.widget);
layout.addWidget(btn_widget);
this.window.adjustSize();
this.window.setFixedSize(this.window.size().width(), this.window.size().height());
this.window.setStyleSheet(general_css);
}
execution() {
this.window.exec();
if(this.changed){
plot_obj.update_label.show();
plot_obj.update_plot(process.cwd() + '/plotting/fig.svg', this.nb_plots, run_obj.plot_type, run_obj.dir_path + '/objectives', this.title, this.x_axis, this.y_axis, this.z_axis);
}
return ;
}
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment