From f8db17cc5bb072d57f0248c4b7dbd7ac0a4613b1 Mon Sep 17 00:00:00 2001 From: "gael.pongnot" Date: Wed, 27 Jul 2022 14:52:08 +0200 Subject: [PATCH] Transformation des axes temporels et vectoriel en objets --- MLI_vectorielle.py | 245 ++++++++++++++++++++++++++++++--------------- 1 file changed, 163 insertions(+), 82 deletions(-) diff --git a/MLI_vectorielle.py b/MLI_vectorielle.py index 26d29cb..ca34e97 100644 --- a/MLI_vectorielle.py +++ b/MLI_vectorielle.py @@ -4,12 +4,149 @@ import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt from matplotlib.widgets import Slider, Button +from matplotlib.axes import Axes +from matplotlib.projections.polar import PolarAxes PI = np.pi N_PTS = 400 -class MLI_plot: + +class TriPlot_TimeAxe(Axes): + """Classe d'axe temporel""" + + phase = 2*PI/3*np.array([0, 1, 2]) + phasor = np.linspace(0-phase, 2*PI-phase, N_PTS).T + theta = phasor[0,:] + + def __init__(self, v_max, phi, fig, rect): + Axes.__init__(self, fig, rect) + self.timegraph_plot = [] + self.v_max = v_max + self.phi = phi + self.v_ref = np.zeros(self.phasor.shape) + return + + def setup(self): + self.get_figure().add_axes(self) + self.timegraph_plot = [self.plot(self.theta, self.v_ref[i])[0] for i in range(3)] + + self.grid() + self.set_xlim([0, 2*PI]) + self.set_xticks([i*PI/6 for i in range(13)]) + self.set_xticklabels([str(30*i)+"°" for i in range(13)]) + self.set_xlabel("Phase") + self.set_ylim([-2.2*self.v_max, +2.2*self.v_max]) + self.set_ylabel("Tension [V]") + + self.timegraph_plot.append( + self.plot([self.phi*PI/180, self.phi*PI/180], + self.get_ylim(), + '--r')[0] + ) + self.timegraph_plot.append( + self.scatter(3*[self.phi*PI/180], + [self.v_max*np.cos((self.phi-i*120)*PI/180) for i in range(3)], + c=["C0", "C1", "C2"])) + + return + + def refresh(self): + self.timegraph_plot[0].set_ydata(self.v_ref[0]) + self.timegraph_plot[1].set_ydata(self.v_ref[1]) + self.timegraph_plot[2].set_ydata(self.v_ref[2]) + self.timegraph_plot[3].set_xdata(2*[self.phi*PI/180]) + self.timegraph_plot[4].set_offsets( + np.array([3*[self.phi*PI/180], + [self.v_max*np.cos((self.phi-i*120)*PI/180) for i in range(3)]] + ).T + ) + return + + def set_vmax(self, v_max): + self.v_max = v_max + self.v_ref = self.v_max*np.cos(self.phasor) + return + + def set_phi(self, phi): + self.phi = phi + return + + +class TriPlot_VectAxe(PolarAxes): + """Classe d'axe vectoriel""" + + phase = 2*PI/3*np.array([0, 1, 2]) + phasor = np.linspace(0-phase, 2*PI-phase, N_PTS).T + theta = phasor[0,:] + + def __init__(self, v_max, phi, fig, rect): + PolarAxes.__init__(self, fig, rect) + self.plot_list = [] + self.arrow_list = [] + self.v_max = v_max + self.phi = phi + self.v_ref = np.zeros(self.phasor.shape) + return + + def setup(self): + self.get_figure().add_axes(self) + self.set_rorigin(0) + self.set_ylim(0, 2.2*self.v_max) + + theta_ticks = np.arange(0, 360, 30) + theta_labels = [str(t * (t<=180) + + (t-360) * (t>180)) + "°" + for t in theta_ticks] + self.set_thetagrids(theta_ticks, labels=theta_labels) + + self.plot_list.append( + self.plot( + self.theta, self.v_max*np.ones(self.theta.shape), 'r' + )[0] + ) + self.arrow_list = [ + self.arrow(0, 0, 0, self.v_max, + lw=2, head_width=0.05, head_length=self.v_max/15, + color="C"+str(i), length_includes_head=True, + transform=( + mpl.transforms.Affine2D().translate( + (self.phi-i*120)*PI/180, 0 + ) + + self.transData + ) + ) + for i in range(3)] + return + + def refresh(self): + self.plot_list[0].set_ydata( + self.v_max*np.ones( + self.theta.shape + ) + ) + + for i, arrow in enumerate(self.arrow_list): + arrow.set_data(dy=self.v_max) + arrow.set_transform( + mpl.transforms.Affine2D().translate( + (self.phi-i*120)*PI/180, 0 + ) + + self.transData + ) + return + + def set_vmax(self, v_max): + self.v_max = v_max + self.v_ref = self.v_max*np.cos(self.phasor) + return + + def set_phi(self, phi): + self.phi = phi + return + + +class TriPlot: """Classe de graphique MLI""" phase = 2*PI/3*np.array([0, 1, 2]) @@ -26,8 +163,8 @@ class MLI_plot: # Attributs graphiques self.fig = plt.figure() self.ax = [ - plt.axes([0.1, 0.2, 0.40, 0.6]), - plt.axes([0.45, 0.1, 0.55, 0.8]), + TriPlot_TimeAxe(self.v_max, self.phi, self.fig, [0.1, 0.2, 0.4, 0.6]), + TriPlot_VectAxe(self.v_max, self.phi, self.fig, [0.5, 0.2, 0.5, 0.6]), plt.axes([0.01, 0.1, 0.03, 0.8]), plt.axes([0.1, 0.01, 0.8, 0.03])] self.amp_slider = Slider( @@ -47,113 +184,57 @@ class MLI_plot: orientation="horizontal" ) self.amp_slider - self.timegraph_plot = [] self.vectorgraph_plot = [] self.vectorgraph_arrow = [] # Tracé du graphique self.setup() - self.update() + self.refresh() return def setup(self): self.fig.subplots_adjust(left=0.25) - self.setup_timegraph() - self.setup_vectorgraph() - - self.amp_slider.on_changed(self.update) - self.phi_slider.on_changed(self.update) - return - - def setup_timegraph(self): - self.timegraph_plot = [self.ax[0].plot(self.theta, self.v_ref[i])[0] for i in range(3)] - - self.ax[0].grid() - self.ax[0].set_xlim([0, 2*PI]) - self.ax[0].set_xticks([i*PI/6 for i in range(13)]) - self.ax[0].set_xticklabels([str(30*i)+"°" for i in range(13)]) - self.ax[0].set_xlabel("Angle") - self.ax[0].set_ylim([-3*self.v_eff, +3*self.v_eff]) - self.ax[0].set_ylabel("Tension [V]") - - self.timegraph_plot.append( - self.ax[0].plot([self.phi*PI/180, self.phi*PI/180], - self.ax[0].get_ylim(), - '--r')[0] - ) - self.timegraph_plot.append( - self.ax[0].scatter(3*[self.phi*PI/180], - [self.v_max*np.cos((self.phi-i*120)*PI/180) for i in range(3)], - c=["C0", "C1", "C2"])) - - return - - def setup_vectorgraph(self): - self.ax[1] = plt.subplot(122, polar=True) - self.ax[1].set_rorigin(0) - self.ax[1].set_ylim(0, 3*self.v_eff) - - theta_ticks = np.arange(0, 360, 30) - theta_labels = [str(t * (t<=180) - + (t-360) * (t>180)) + "°" - for t in theta_ticks] - self.ax[1].set_thetagrids(theta_ticks, labels=theta_labels) + self.ax[0].setup() + self.ax[1].setup() - self.vectorgraph_plot.append(self.ax[1].plot(self.theta, self.v_max*np.ones(self.theta.shape), 'r')[0]) - self.vectorgraph_arrow = [self.ax[1].arrow(0, 0, 0, self.v_max, - lw=2, head_width=0.05, head_length=self.v_max/15, - color="C"+str(i), length_includes_head=True, - transform=(mpl.transforms.Affine2D().translate((self.phi-i*120)*PI/180, 0) - +self.ax[1].transData) - ) - for i in range(3)] + self.amp_slider.on_changed(self.refresh) + self.phi_slider.on_changed(self.refresh) return - def update(self, val=None): + def refresh(self, val=None): self.set_veff(self.amp_slider.val) - self.phi = self.phi_slider.val - self.update_timegraph() - self.update_vectorgraph() - return - - def update_timegraph(self): - self.timegraph_plot[0].set_ydata(self.v_ref[0]) - self.timegraph_plot[1].set_ydata(self.v_ref[1]) - self.timegraph_plot[2].set_ydata(self.v_ref[2]) - self.timegraph_plot[3].set_xdata(2*[self.phi*PI/180]) - self.timegraph_plot[4].set_offsets( - np.array([3*[self.phi*PI/180], - [self.v_max*np.cos((self.phi-i*120)*PI/180) for i in range(3)]] - ).T - ) - return - - def update_vectorgraph(self): - self.vectorgraph_plot[0].set_ydata(self.v_max*np.ones(self.theta.shape)) - - for i, arrow in enumerate(self.vectorgraph_arrow): - arrow.set_data(dy=self.v_max) - arrow.set_transform(mpl.transforms.Affine2D().translate((self.phi-i*120)*PI/180, 0) - +self.ax[1].transData) + self.set_phi(self.phi_slider.val) + self.ax[0].refresh() + self.ax[1].refresh() return def reset(self, event=None): return def set_veff(self, v_eff): - self.v_eff = v_eff - self.v_max = np.sqrt(2)*v_eff - self.v_ref = self.v_max*np.cos(self.phasor) + self.set_vmax(np.sqrt(2)*v_eff) return def set_vmax(self, v_max): self.v_max = v_max self.v_eff = v_max/np.sqrt(2) self.v_ref = self.v_max*np.cos(self.phasor) + + self.ax[0].set_vmax(self.v_max) + self.ax[1].set_vmax(self.v_max) + + return + + def set_phi(self, phi): + self.phi = phi + self.ax[0].set_phi(self.phi) + self.ax[1].set_phi(self.phi) return if __name__ == '__main__': # Execute when the module is not initialized from an import statement. plt.close('all') - myMLI_plot = MLI_plot() \ No newline at end of file + my_plot = TriPlot() + + plt.show(block=False)