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

Loading…
Cancel
Save