2023-01-30 07:24:40 +01:00
|
|
|
import sys
|
2023-01-31 13:51:32 +01:00
|
|
|
from twin_plot import plot_config_get_dict, plot_config_get, plot_config_get_enable, plot_nb, csv_read, plots_static # Gestion communes des graphiques (Qt, wx)
|
2023-01-30 07:24:40 +01:00
|
|
|
|
2023-01-31 11:15:21 +01:00
|
|
|
import wx # GUI wxPython
|
|
|
|
import matplotlib # Grapheur Matplotlib
|
2023-01-30 07:24:40 +01:00
|
|
|
from matplotlib.figure import Figure
|
|
|
|
from matplotlib.backends.backend_wxagg import (FigureCanvasWxAgg as FigureCanvas, NavigationToolbar2WxAgg as NavigationToolbar)
|
|
|
|
|
|
|
|
###############################################################################
|
|
|
|
# twin_plot_wx.py
|
|
|
|
# @title: Visualisation des données (wxPython + Matplotlib)
|
|
|
|
# @project: Blender-EduTech
|
|
|
|
# @lang: fr
|
|
|
|
# @authors: Philippe Roy <philippe.roy@ac-grenoble.fr>
|
|
|
|
# @copyright: Copyright (C) 2023 Philippe Roy
|
|
|
|
# @license: GNU GPL
|
|
|
|
###############################################################################
|
|
|
|
|
|
|
|
plot_config={}
|
|
|
|
|
|
|
|
###############################################################################
|
|
|
|
# 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')
|
|
|
|
|
|
|
|
# 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:
|
2023-01-31 11:15:21 +01:00
|
|
|
plt = self.figure.subplots(plot_nb(plot_config), 1, sharex=True) # plot_nb() : nombre de graphiques
|
|
|
|
self.canvas = FigureCanvas(self, -1, self.figure)
|
|
|
|
|
|
|
|
# Création des graphive à partir du fichier CSV
|
|
|
|
fields, xdata, ydata = csv_read(sys.argv[1])
|
2023-01-31 13:51:32 +01:00
|
|
|
plots_static(self.canvas, fields, xdata, ydata, plot_config, sys.argv[1])
|
2023-01-31 11:15:21 +01:00
|
|
|
self.show()
|
|
|
|
|
|
|
|
# # Dessin
|
|
|
|
# plot_draw(plt)
|
2023-01-30 07:24:40 +01:00
|
|
|
|
|
|
|
# Implantation de la fenêtre (canvas)
|
|
|
|
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__":
|
2023-01-31 11:15:21 +01:00
|
|
|
|
|
|
|
# Configuration des plots
|
|
|
|
plot_config=plot_config_get_dict()
|
|
|
|
|
|
|
|
# Fenêtre
|
2023-01-30 07:24:40 +01:00
|
|
|
app = App()
|
2023-01-31 11:15:21 +01:00
|
|
|
app.MainLoop() # StaticPlot()
|