parent
82afd08b20
commit
300ddadaa9
1 changed files with 159 additions and 0 deletions
@ -0,0 +1,159 @@ |
|||||||
|
# -*- 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() |
Loading…
Reference in new issue