# -*- coding: utf-8 -*- import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt from matplotlib.widgets import Slider, Button PI = np.pi N_PTS = 400 class MLI_plot: """Classe de graphique MLI""" 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): # Attributs scalaires self.v_eff = 100 self.v_max = np.sqrt(2)*self.v_eff self.v_ref = np.zeros(self.phasor.shape) self.phi = 30 # 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]), plt.axes([0.01, 0.1, 0.03, 0.8]), plt.axes([0.1, 0.01, 0.8, 0.03])] self.amp_slider = Slider( ax=self.ax[2], label="Tension\nefficace", valmin=0, valmax=2*self.v_eff, valinit=self.v_eff, orientation="vertical" ) self.phi_slider = Slider( ax=self.ax[3], label="Phase [°]", valmin=0, valmax=360, valinit=self.phi, orientation="horizontal" ) self.amp_slider self.timegraph_plot = [] self.vectorgraph_plot = [] self.vectorgraph_arrow = [] # Tracé du graphique self.setup() self.update() 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.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)] return def update(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) 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) 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) return if __name__ == '__main__': # Execute when the module is not initialized from an import statement. plt.close('all') myMLI_plot = MLI_plot()