From 22b4853344bacdd8e51a471a576f0454e25bab9c Mon Sep 17 00:00:00 2001 From: Philippe Roy <2550090-phroy@users.noreply.gitlab.com> Date: Mon, 30 Jan 2023 06:24:40 +0000 Subject: [PATCH] =?UTF-8?q?T=C3=A9l=C3=A9verser=20un=20nouveau=20fichier?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- twin_plot_wx.py | 239 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 twin_plot_wx.py diff --git a/twin_plot_wx.py b/twin_plot_wx.py new file mode 100644 index 0000000..b3e9956 --- /dev/null +++ b/twin_plot_wx.py @@ -0,0 +1,239 @@ +import sys +import random +import importlib +import csv +import xml.etree.ElementTree as ET # Creating/parsing XML file + +import wx +import matplotlib +from matplotlib.figure import Figure +from matplotlib.backends.backend_wxagg import (FigureCanvasWxAgg as FigureCanvas, NavigationToolbar2WxAgg as NavigationToolbar) + +import numpy as np + +############################################################################### +# twin_plot_wx.py +# @title: Visualisation des données (wxPython + Matplotlib) +# @project: Blender-EduTech +# @lang: fr +# @authors: Philippe Roy +# @copyright: Copyright (C) 2023 Philippe Roy +# @license: GNU GPL +############################################################################### + +# Lecture des configurations +twin_config = ET.parse('twin_config.xml').getroot() +plot_config_tree = ET.parse('plot_config.xml').getroot() +plot_config={} + +############################################################################### +# Configuration des graphiques +############################################################################### + +## +# Génère le dictionnaire plot_config à partir du fichier XML plot_config.xml +## + +def plot_config_dict(): + for var in plot_config_tree[0][0]: + var_dict={} + for i in range (len(var)): + if var[i] is not None: + var_dict.update({var[i].tag : var[i].text}) + plot_config.update({var.text: var_dict}) + +## +# Returne une valeur du dictionnaire plot_config +## + +def plot_config_get(var, key): + if key in plot_config[var]: + return plot_config[var][key] + else: + return None + +## +# Nombre de groupe de courbe(s) +## + +def plot_nb(): + plot_config_list=list(plot_config) + nbgroup = 0 + + # Regroupement ('group' > 0) + for var in plot_config_list: + if ('group' in plot_config[var]): + if nbgroup < int(plot_config[var]['group']): + nbgroup = int(plot_config[var]['group']) + + # Plot solitaire ('group' = 0) + # 'group' = -1 -> variable non affichée + for var in plot_config_list: + if ('group' in plot_config[var]): + if int(plot_config[var]['group']) == 0: + nbgroup +=1 + + return nbgroup + + +############################################################################### +# Création des graphiques +############################################################################### + +def plot_draw(plt): + + # Lecture fichier CSV + fields = [] + rows = [] + with open(sys.argv[1], newline='') as csv_buff: + csv_reader = csv.reader(csv_buff, delimiter=';') + fields = next(csv_reader) + for row in csv_reader: + rows.append(row) + + # Mise en tableau à deux colonnes (xdata,ydata) + xdata=[] + ydata=[] + i=0 + for field in fields: + xdata_row=[] + ydata_row=[] + for row in rows: + xdata_row.append(float(row[0].replace(',', '.'))) # Revenir au format US des décimaux + ydata_row.append(float(row[i].replace(',', '.'))) # Revenir au format US des décimaux + xdata.append(xdata_row) + ydata.append(ydata_row) + i+=1 + + # Plots + # Groupe de plots : si group = 0 -> nouveau groupe, plot solitaire + # si group = -1 -> pas de plot + # si group > 0 -> numéro du groupe + plt_i=0 # Compteur de plot + plt_grp=[] # Groupe de plot [[numéro du plot, groupe du fichier CSV]] + for i in range(len(fields)): + var = fields[i] + plt_current=-1 # Numéro du plot à créer + + if ('group' in plot_config[var]): # Pas de Plot + if int(plot_config[var]['group']) !=-1: # Pas de Plot + + # Plot solitaire + if int(plot_config[var]['group']) ==0: + plt_current = plt_i + plt_grp.append([plt_i, 0]) + plt_i +=1 + + # Plot groupé + else: + plt_new = True # Flag d'un nouveau groupe + for j in range(len(plt_grp)): + if plt_grp[j][1] == int(plot_config[var]['group']): # Groupe déjà existant + plt_current = plt_grp[j][0] + plt_new = False + break + + # Nouveau groupe + if plt_new: + plt_current = plt_i + plt_grp.append([plt_i, int(plot_config[var]['group'])]) + plt_i +=1 + + # Création du plot unique + if plot_nb() ==1: + if twin_config[1][0].text == "True": # Configuration des plots activée + plt.plot(xdata[i], ydata[i], label=var, color=plot_config_get(var, 'color'), linewidth=plot_config_get(var, 'linewidth'), + linestyle=plot_config_get(var, 'linestyle'), marker=plot_config_get(var, 'marker')) + else: + plt.plot(xdata[i], ydata[i], '.-', label=var) # Configuration matplotlib par défaut + + # Légende ou titre d'axe y + if plt_grp[plt_current][1]==0: + plt.set_ylabel(var) + else: + plt.legend() + + # Création des subplots + if plot_nb() >1: + if twin_config[1][0].text == "True": # Configuration des plots activée + plt[plt_current].plot(xdata[i], ydata[i], label=var, color=plot_config_get(var, 'color'), linewidth=plot_config_get(var, 'linewidth'), + linestyle=plot_config_get(var, 'linestyle'), marker=plot_config_get(var, 'marker')) + else: + plt[plt_current].plot(xdata[i], ydata[i], '.-', label=var) # Configuration matplotlib par défaut + + # Légende ou titre d'axe y + if plt_grp[plt_current][1]==0: + plt[plt_current].set_ylabel(var) + else: + plt[plt_current].legend() + + # Décoration + if plot_nb() ==1: # 1 plot + plt.set_xlabel("Temps (s)") + # self.canvas.plt[0].set_ylabel("Valeurs") + plt.set_title(sys.argv[1]) + plt.axhline(linewidth=1, color='k') + plt.grid(True, linestyle='--') + # self.canvas.plt.legend() + else: # Plusieurs plots + plt[plt_i-1].set_xlabel("Temps (s)") + # self.canvas.plt[0].set_ylabel("Valeurs") + plt[0].set_title(sys.argv[1]) + for i in range (plt_i): + plt[i].axhline(linewidth=1, color='k') + plt[i].grid(True, linestyle='--') + # self.canvas.plt[i].legend() + + +############################################################################### +# Zone de dessin +############################################################################### + + +class CanvasFrame(wx.Frame): + + def __init__(self): + super().__init__(None, -1, 'Visualisation des données') + + # Configuration des graphiques + plot_config_dict() + + # Création des zones graphique (Plots) + self.figure = Figure() + if plot_nb() ==1: # plot_nb() : nombre de graphiques + plt = self.figure.subplots() # plot_nb() : nombre de graphiques + else: + plt = self.figure.subplots(plot_nb(), 1, sharex=True) # plot_nb() : nombre de graphiques + + # Dessin + plot_draw(plt) + + # Implantation de la fenêtre (canvas) + self.canvas = FigureCanvas(self, -1, self.figure) + self.sizer = wx.BoxSizer(wx.VERTICAL) + self.sizer.Add(self.canvas, 1, wx.TOP | wx.LEFT | wx.EXPAND) + self.add_toolbar() + self.SetSizer(self.sizer) + self.Fit() + + def add_toolbar(self): + self.toolbar = NavigationToolbar(self.canvas) + self.toolbar.Realize() + self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND) + self.toolbar.update() + + +############################################################################### +# Application +############################################################################### + +class App(wx.App): + def OnInit(self): + frame = CanvasFrame() + frame.Show(True) + return True + +if __name__ == "__main__": + app = App() + app.MainLoop() +