Ajout de la projection + bouton reset

main
Gaël Pongnot 2 years ago
parent f8db17cc5b
commit a156905d25
  1. 162
      MLI_vectorielle.py

@ -3,7 +3,7 @@
import numpy as np import numpy as np
import matplotlib as mpl import matplotlib as mpl
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button from matplotlib.widgets import Slider, Button, CheckButtons
from matplotlib.axes import Axes from matplotlib.axes import Axes
from matplotlib.projections.polar import PolarAxes from matplotlib.projections.polar import PolarAxes
@ -19,8 +19,8 @@ class TriPlot_TimeAxe(Axes):
phasor = np.linspace(0-phase, 2*PI-phase, N_PTS).T phasor = np.linspace(0-phase, 2*PI-phase, N_PTS).T
theta = phasor[0,:] theta = phasor[0,:]
def __init__(self, v_max, phi, fig, rect): def __init__(self, v_max, phi, fig, rect, *args, **kwargs):
Axes.__init__(self, fig, rect) Axes.__init__(self, fig, rect, *args, **kwargs)
self.timegraph_plot = [] self.timegraph_plot = []
self.v_max = v_max self.v_max = v_max
self.phi = phi self.phi = phi
@ -36,7 +36,7 @@ class TriPlot_TimeAxe(Axes):
self.set_xticks([i*PI/6 for i in range(13)]) self.set_xticks([i*PI/6 for i in range(13)])
self.set_xticklabels([str(30*i)+"°" for i in range(13)]) self.set_xticklabels([str(30*i)+"°" for i in range(13)])
self.set_xlabel("Phase") self.set_xlabel("Phase")
self.set_ylim([-2.2*self.v_max, +2.2*self.v_max]) self.set_ylim([-1.6*self.v_max, +1.6*self.v_max])
self.set_ylabel("Tension [V]") self.set_ylabel("Tension [V]")
self.timegraph_plot.append( self.timegraph_plot.append(
@ -72,6 +72,9 @@ class TriPlot_TimeAxe(Axes):
self.phi = phi self.phi = phi
return return
def set_parameters(self, p):
return
class TriPlot_VectAxe(PolarAxes): class TriPlot_VectAxe(PolarAxes):
"""Classe d'axe vectoriel""" """Classe d'axe vectoriel"""
@ -80,19 +83,20 @@ class TriPlot_VectAxe(PolarAxes):
phasor = np.linspace(0-phase, 2*PI-phase, N_PTS).T phasor = np.linspace(0-phase, 2*PI-phase, N_PTS).T
theta = phasor[0,:] theta = phasor[0,:]
def __init__(self, v_max, phi, fig, rect): def __init__(self, v_max, phi, fig, rect, *args, **kwargs):
PolarAxes.__init__(self, fig, rect) PolarAxes.__init__(self, fig, rect, *args, **kwargs)
self.plot_list = [] self.plot_list = []
self.arrow_list = [] self.arrow_list = []
self.v_max = v_max self.v_max = v_max
self.phi = phi self.phi = phi
self.v_ref = np.zeros(self.phasor.shape) self.v_ref = np.zeros(self.phasor.shape)
self.parameters = {"projection": False}
return return
def setup(self): def setup(self):
self.get_figure().add_axes(self) self.get_figure().add_axes(self)
self.set_rorigin(0) self.set_rorigin(0)
self.set_ylim(0, 2.2*self.v_max) self.set_ylim(0, 1.6*self.v_max)
theta_ticks = np.arange(0, 360, 30) theta_ticks = np.arange(0, 360, 30)
theta_labels = [str(t * (t<=180) theta_labels = [str(t * (t<=180)
@ -105,8 +109,20 @@ class TriPlot_VectAxe(PolarAxes):
self.theta, self.v_max*np.ones(self.theta.shape), 'r' self.theta, self.v_max*np.ones(self.theta.shape), 'r'
)[0] )[0]
) )
for i in range(3):
self.plot_list.append(
self.plot(
[(self.phi-i*120)*PI/180,
PI*(1-np.sign(np.cos((self.phi-i*120)*PI/180)))],
[self.v_max,
self.v_max*np.abs(np.cos((self.phi-i*120)*PI/180))],
ls = ':',
visible=self.parameters["projection"]
)[0]
)
self.arrow_list = [ self.arrow_list = [
self.arrow(0, 0, 0, self.v_max, self.arrow(0, 0,
0, self.v_max,
lw=2, head_width=0.05, head_length=self.v_max/15, lw=2, head_width=0.05, head_length=self.v_max/15,
color="C"+str(i), length_includes_head=True, color="C"+str(i), length_includes_head=True,
transform=( transform=(
@ -116,7 +132,26 @@ class TriPlot_VectAxe(PolarAxes):
+ self.transData + self.transData
) )
) )
for i in range(3)] for i in range(3)
] + [
self.arrow(0, 0,
0, self.v_max*np.abs(np.cos((self.phi-i*120)*PI/180)),
lw=1, head_width=0.05, head_length=self.v_max/15,
color="C"+str(i), length_includes_head=True,
transform=(
mpl.transforms.Affine2D().translate(
PI*(1-np.sign(
np.cos((self.phi-i*120)*PI/180)
)
)/2,
0
)
+ self.transData
),
visible=self.parameters["projection"]
)
for i in range(3)
]
return return
def refresh(self): def refresh(self):
@ -126,12 +161,32 @@ class TriPlot_VectAxe(PolarAxes):
) )
) )
for i, arrow in enumerate(self.arrow_list): for i, plot in enumerate(self.plot_list[1:4]):
arrow.set_data(dy=self.v_max) plot.set_visible(self.parameters.get("projection"))
arrow.set_transform( plot.set_xdata(
[(self.phi-i*120)*PI/180,
PI*(1-np.sign(np.cos((self.phi-i*120)*PI/180)))/2]
)
plot.set_ydata(
[self.v_max,
self.v_max*np.abs(np.cos((self.phi-i*120)*PI/180))]
)
for i in range(3):
self.arrow_list[i].set_data(dy=self.v_max)
self.arrow_list[i].set_transform(
mpl.transforms.Affine2D().translate(
(self.phi-i*120)*PI/180, 0)
+ self.transData
)
for i in range(3, 6):
self.arrow_list[i].set_visible(self.parameters["projection"])
self.arrow_list[i].set_data(
dy=self.v_max*np.abs(np.cos((self.phi-i*120)*PI/180))
)
self.arrow_list[i].set_transform(
mpl.transforms.Affine2D().translate( mpl.transforms.Affine2D().translate(
(self.phi-i*120)*PI/180, 0 PI*(1-np.sign(np.cos((self.phi-i*120)*PI/180)))/2, 0)
)
+ self.transData + self.transData
) )
return return
@ -145,6 +200,10 @@ class TriPlot_VectAxe(PolarAxes):
self.phi = phi self.phi = phi
return return
def set_parameters(self, p):
self.parameters["projection"] = p.get("projection", False)
return
class TriPlot: class TriPlot:
"""Classe de graphique MLI""" """Classe de graphique MLI"""
@ -155,37 +214,46 @@ class TriPlot:
def __init__(self): def __init__(self):
# Attributs scalaires # Attributs scalaires
self.v_eff = 100 self.v_eff = 220
self.v_max = np.sqrt(2)*self.v_eff self.v_max = np.sqrt(2)*self.v_eff
self.v_ref = np.zeros(self.phasor.shape) self.v_ref = np.zeros(self.phasor.shape)
self.phi = 30 self.phi = 30
# Attributs graphiques # Attributs graphiques
self.fig = plt.figure() self.fig = plt.figure()
self.ax = [ self.timeaxe = TriPlot_TimeAxe(self.v_max, self.phi,
TriPlot_TimeAxe(self.v_max, self.phi, self.fig, [0.1, 0.2, 0.4, 0.6]), 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]), self.vectaxe = TriPlot_VectAxe(self.v_max, self.phi,
plt.axes([0.01, 0.1, 0.03, 0.8]), self.fig, [0.5, 0.2, 0.5, 0.6])
plt.axes([0.1, 0.01, 0.8, 0.03])] self.axes = [self.timeaxe, self.vectaxe]
self.amp_slider = Slider( self.amp_slider = Slider(
ax=self.ax[2], ax=plt.axes([0.01, 0.1, 0.03, 0.8]),
label="Tension\nefficace", label="Tension\nefficace",
valmin=0, valmin=0,
valmax=2*self.v_eff, valmax=1.5*self.v_eff,
valinit=self.v_eff, valinit=self.v_eff,
orientation="vertical" orientation="vertical"
) )
self.phi_slider = Slider( self.phi_slider = Slider(
ax=self.ax[3], ax=plt.axes([0.1, 0.01, 0.8, 0.03]),
label="Phase [°]", label="Phase [°]",
valmin=0, valmin=0,
valmax=360, valmax=360,
valinit=self.phi, valinit=self.phi,
orientation="horizontal" orientation="horizontal"
) )
self.amp_slider self.reset_button = Button(
self.vectorgraph_plot = [] ax=plt.axes([0.95, 0.01, 0.03, 0.03]),
self.vectorgraph_arrow = [] label='Reset',
hovercolor='0.975'
)
self.parameters_check = CheckButtons(
ax=plt.axes([0.9, 0.8, 0.1, 0.2]),
labels=["Projection"]
)
self.sliders = [self.amp_slider, self.phi_slider]
self.parameters = {}
# Tracé du graphique # Tracé du graphique
self.setup() self.setup()
@ -194,42 +262,50 @@ class TriPlot:
return return
def setup(self): def setup(self):
self.fig.subplots_adjust(left=0.25) for axe in self.axes:
self.ax[0].setup() axe.setup()
self.ax[1].setup() for slider in self.sliders:
slider.on_changed(self.refresh)
self.amp_slider.on_changed(self.refresh) self.reset_button.on_clicked(self.reset)
self.phi_slider.on_changed(self.refresh) self.parameters_check.on_clicked(self.refresh)
return return
def refresh(self, val=None): def refresh(self, val=None):
self.set_veff(self.amp_slider.val) self.set_veff(self.amp_slider.val)
self.set_phi(self.phi_slider.val) self.set_phi(self.phi_slider.val)
self.ax[0].refresh() self.set_parameters(self.parameters_check.get_status())
self.ax[1].refresh() for axe in self.axes:
axe.refresh()
self.fig.canvas.draw()
return return
def reset(self, event=None): def reset(self, event=None):
return for slider in self.sliders:
slider.reset()
def set_veff(self, v_eff):
self.set_vmax(np.sqrt(2)*v_eff)
return return
def set_vmax(self, v_max): def set_vmax(self, v_max):
self.v_max = v_max self.v_max = v_max
self.v_eff = v_max/np.sqrt(2) self.v_eff = v_max/np.sqrt(2)
self.v_ref = self.v_max*np.cos(self.phasor) self.v_ref = self.v_max*np.cos(self.phasor)
for axe in self.axes:
axe.set_vmax(self.v_max)
return
self.ax[0].set_vmax(self.v_max) def set_veff(self, v_eff):
self.ax[1].set_vmax(self.v_max) self.set_vmax(np.sqrt(2)*v_eff)
return return
def set_phi(self, phi): def set_phi(self, phi):
self.phi = phi self.phi = phi
self.ax[0].set_phi(self.phi) for axe in self.axes:
self.ax[1].set_phi(self.phi) axe.set_phi(self.phi)
return
def set_parameters(self, p):
self.parameters["projection"] = p[0]
for axe in self.axes:
axe.set_parameters(self.parameters)
return return
if __name__ == '__main__': if __name__ == '__main__':

Loading…
Cancel
Save