Compare commits

...

5 commits

6 changed files with 173 additions and 134 deletions

View file

@ -9,12 +9,12 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
- name: Initialize virtual environment
run: /usr/bin/python -m venv .env
run: /usr/bin/python -m venv .venv
- name: Install dependencies
run: ./.env/bin/pip install mystmd jupyter jupyterlab_myst ipykernel altair pandas
run: ./.venv/bin/pip install -r requirements.txt
- name: Build static HTML
run: |
. .env/bin/activate
. .venv/bin/activate
myst build --execute --html
- name: Copy files
run: |

View file

@ -32,32 +32,26 @@ et un niveau **bas** ("Low").
:label: fig:sig-logique
```{code-cell} python
:tags: [remove-input]
import altair as alt
import matplotlib.pyplot as plt
from matplotlib import ticker
import numpy as np
import pandas as pd
rng = np.random.default_rng(25)
n = 16
t = np.arange(n+1)
s = rng.choice([0, 1], n+1)
s[-1] = s[-2]
data = pd.DataFrame({
"t": t,
"s": s,
})
alt.Chart(
data
).mark_line(
interpolate="step-after",
strokeWidth=3,
).encode(
alt.X("t:Q").axis(title="Temps (s)").scale(domain=(0,n)),
alt.Y("s:Q", axis=alt.Axis(title="Signal logique", values=[0, 1], format=".0f")).scale(domain=(0,1)),
).properties(
width="container",
height=100,
s = rng.choice([0, 1], n)
fig, ax = plt.subplots()
ax.stairs(s, t, lw=3, baseline=None)
ax.set(
xlim=(0, n),
ylim=(-.5, 1.5),
xlabel="Temps (s)",
ylabel="Signal logique",
)
ax.yaxis.set_major_locator(ticker.MultipleLocator(1))
ax.xaxis.set_major_locator(ticker.MultipleLocator(1))
```
Exemple de signal logique
````
@ -77,35 +71,37 @@ Un exemple de signal analogique est donné en @fig:sig-analogique.
:label: fig:sig-analogique
```{code-cell} python
:tags: [remove-input]
import altair as alt
import matplotlib.pyplot as plt
from matplotlib import ticker
import numpy as np
import pandas as pd
from scipy.interpolate import CubicSpline
from scipy.stats import qmc
rng = np.random.default_rng(25)
n = 20
t_max = 16
t = np.linspace(0, t_max, n)
t_base = np.linspace(0, t_max, n)
lhs = (qmc.LatinHypercube(d=n-2, rng=rng).random(1)[0] - .5) * t_max/n
t = t_base + np.concatenate(([0], lhs, [0]))
t = t_base
s = 5 * rng.random(n)
s[-1] = s[-2]
data = pd.DataFrame({
"t": t,
"s": s,
})
alt.Chart(
data
).mark_line(
interpolate="basis",
strokeWidth=3,
).encode(
alt.X("t:Q").axis(title="Temps (s)").scale(domain=(0,t_max)),
alt.Y("s:Q", axis=alt.Axis(title="Signal analogique")).scale(domain=(0,5)),
).properties(
width="container",
height=200,
t_interp = np.linspace(0, t_max, 1024)
s_interp = np.clip(CubicSpline(t, s)(t_interp), 0, 5)
fig, ax = plt.subplots()
ax.plot(t_interp, s_interp, lw=3)
ax.set(
xlim=(0, t_max),
ylim=(-.5, 5.5),
xlabel="Temps (s)",
ylabel="Signal analogique",
)
ax.yaxis.set_major_locator(ticker.MultipleLocator(1))
ax.xaxis.set_major_locator(ticker.MultipleLocator(1))
```
Exemple de signal analogique
````
@ -119,32 +115,26 @@ Un exemple de signal analogique est donné en @fig:sig-numerique.
:label: fig:sig-numerique
```{code-cell} python
:tags: [remove-input]
import altair as alt
import matplotlib.pyplot as plt
from matplotlib import ticker
import numpy as np
import pandas as pd
rng = np.random.default_rng(25)
n = 16
t = np.arange(n+1)
s = rng.integers(0, 16, n+1)
s[-1] = s[-2]
data = pd.DataFrame({
"t": t,
"s": s,
})
alt.Chart(
data
).mark_line(
interpolate="step-after",
strokeWidth=3,
).encode(
alt.X("t:Q").axis(title="Temps (s)").scale(domain=(0,n)),
alt.Y("s:Q", axis=alt.Axis(title="Signal numérique", values=np.arange(0, 16))).scale(domain=(0,15)),
).properties(
width="container",
height=200,
s = rng.integers(0, 16, n)
fig, ax = plt.subplots()
ax.stairs(s, t, lw=3, baseline=None)
ax.set(
xlim=(0, n),
ylim=(-.5, 16.5),
xlabel="Temps (s)",
ylabel="Signal numérique",
)
ax.yaxis.set_major_locator(ticker.MultipleLocator(1))
ax.xaxis.set_major_locator(ticker.MultipleLocator(1))
```
Exemple de signal numérique
````

View file

@ -37,69 +37,64 @@ La **caractéristique** du CAN est la courbe représentant la valeur numérique
:label: fig:exemple-can
```{code-cell} python
:tags: [remove-input]
import altair as alt
import matplotlib.pyplot as plt
from matplotlib import ticker
import numpy as np
import pandas as pd
from scipy import interpolate
from scipy.interpolate import CubicSpline
from scipy.stats import qmc
rng = np.random.default_rng(25)
rng = np.random.default_rng(50)
n = 20
t_max = 16
t_max = 8
n_interp = t_max * 100 + 1
T = np.linspace(0, t_max, 1601)
y = np.clip(
interpolate.BSpline(np.linspace(0, t_max, n), 5 * rng.random(n), 2)(T),
0,
5,
t_base = np.linspace(0, t_max, n)
lhs = (qmc.LatinHypercube(d=n-2, rng=rng).random(1)[0] - .5) * t_max/n
t = t_base + np.concatenate(([0], lhs, [0]))
t = t_base
s = 5 * rng.random(n)
t_interp = np.linspace(0, t_max, n_interp)
s_interp = np.clip(CubicSpline(t, s)(t_interp), 0, 5)
s_n = np.full_like(t_interp[::50], np.nan)
s_n = np.floor(s_interp[::50] * 8 / 5)
s_n[s_n == 8] = 7
fig, ax = plt.subplots()
ax2 = ax.twinx()
ax.plot(t_interp, s_interp, lw=3)
ax2.scatter(t_interp[::50], s_n, color="C1")
ax.grid(False, axis="y")
ax.grid(True, axis="x", which="both")
ax2.grid(True)
ax.set(
xlim=(0, t_max),
ylim=(-.5, 5.5),
xlabel="Temps (s)",
)
y_n = np.full([1601], np.nan)
y_n[::50] = np.floor(y[::50] * 8 / 5)
y_n[y_n == 8] = 7
data = pd.DataFrame({
"t": T,
"s": y,
"s_n": y_n,
})
base = alt.Chart(
data
).encode(
alt.X("t:Q").axis(title="Temps (s)").scale(domain=(0,t_max)),
ax.set_ylabel("Signal analogique (V)", color="C0")
ax2.set(
ylim=(-8/5*.5, 8/5*5.5),
)
ax2.set_ylabel("Signal numérique", color="C1")
ch = base.mark_line(
interpolate="basis",
strokeWidth=3,
color="#6666cc",
).encode(
alt.Y("s:Q", axis=alt.Axis(title="Signal analogique", titleColor="#6666cc")).scale(domain=(0,5)),
)
ax.yaxis.set_major_locator(ticker.MultipleLocator(1))
ax.xaxis.set_major_locator(ticker.MultipleLocator(1))
ax.xaxis.set_minor_locator(ticker.MultipleLocator(.5))
ax2.set_yticks(np.arange(9), np.concatenate((np.arange(8), [""])))
ch_n = base.mark_point(
filled=True,
color="#ff6600",
).encode(
alt.Y(
"s_n:Q",
axis=alt.Axis(
title="Signal numérisé",
titleColor="#ff6600",
values=np.arange(8),
)
).scale(domain=(0,8)),
)
alt.layer(ch_n, ch).resolve_scale(
y="independent",
).properties(
width="container",
height=200,
)
arr = ax2.annotate("", xy=(0, 0), xytext=(0.5, 0), arrowprops=dict(arrowstyle="<->"))
ax2.annotate("$T_e$", (0.5, 1), xycoords=arr, ha="center", va="bottom")
arr2 = ax2.annotate("", xy=(0.5, 0), xytext=(0.5, 1), arrowprops=dict(arrowstyle="<->"))
ax2.annotate("$q$", (1, 0.5), xycoords=arr2, ha="left", va="center")
arr3 = ax2.annotate("", xy=(1, 0), xytext=(1, 8), arrowprops=dict(arrowstyle="<->"))
ax2.annotate("$V_{pe}$", (1, 0.5), xycoords=arr3, ha="left", va="center")
```
Signal analogique et signal numérisé.
````
@ -108,34 +103,37 @@ Signal analogique et signal numérisé.
:label: fig:carac-can
```{code-cell} python
:tags: [remove-input]
import altair as alt
import matplotlib.pyplot as plt
from matplotlib import ticker
import numpy as np
import pandas as pd
from scipy import interpolate
N = 8
s_n = np.arange(N+1)
s_n[-1] = s_n[-2]
data = pd.DataFrame({
"s_n": s_n,
"s_a": np.linspace(0, 5, N+1),
})
s_n = np.arange(N)
s_a = np.linspace(0, 5, N+1)
alt.Chart(
data
).mark_line(
interpolate="step-after",
strokeWidth=3,
color="#ff6600",
).encode(
alt.X("s_a:Q").axis(title="Signal Analogique").scale(domain=(0,5)),
alt.Y("s_n:Q", axis=alt.Axis(title="Signal numérique", values=np.arange(N))).scale(domain=(0,N)),
).properties(
width=200,
height=200,
fig, ax = plt.subplots()
ax.stairs(s_n, s_a, color="C1", lw=3, baseline=None)
ax.set(
xlim=(0, 5),
ylim=(-1, N),
yticks=s_n,
xlabel="Signal analogique (V)",
ylabel="Signal numérique",
)
ax.set_xticks(s_a, [f"{v:.3f}" for v in s_a], rotation=45, ha="right", rotation_mode="anchor")
ax.set_aspect(5/8, 'box')
arr4 = ax.annotate(
"", xy=(s_a[0], 0), xytext=(s_a[1], 0), arrowprops=dict(arrowstyle="<->")
)
ax.annotate("$q$", (0.5, 1), xycoords=arr4, ha="center", va="bottom")
arr5 = ax.annotate(
"", xy=(s_a[0], 1.5), xytext=(s_a[-1], 1.5), arrowprops=dict(arrowstyle="<->")
)
ax.annotate("$V_{pe}$", (0.5, 1), xycoords=arr5, ha="center", va="bottom")
```
Caractéristique du CAN.
````

1
cours/SIN/matplotlibrc Symbolic link
View file

@ -0,0 +1 @@
../../matplotlibrc

43
matplotlibrc Normal file
View file

@ -0,0 +1,43 @@
lines.linewidth: 3
font.family: Fira Code
image.cmap: inferno
axes.linewidth: 1
axes.grid: True
axes.grid.which: major
axes.titlelocation: right
axes.titleweight: 700
axes.axisbelow: True
axes.prop_cycle: cycler(color=["#4269d0","#efb118","#ff725c","#6cc5b0","#3ca951","#ff8ab7","#a463f2","#97bbf5","#9c6b4e","#9498a0"])
axes.formatter.use_locale: True
grid.color: "#bebebe"
grid.linewidth: 1
grid.alpha: 1
hatch.linewidth: 8
hatch.color: "#00000013"
boxplot.showmeans: true
boxplot.meanprops.markeredgecolor: "k"
boxplot.meanprops.marker: "+"
boxplot.flierprops.markerfacecolor: C0
boxplot.medianprops.color: C0
figure.figsize: 8, 4.5
figure.dpi: 96
figure.constrained_layout.use: True
xtick.direction: in
xtick.major.size: 4
xtick.minor.size: 2
ytick.direction: in
ytick.major.size: 4
ytick.minor.size: 2
savefig.format: pdf

7
requirements.txt Normal file
View file

@ -0,0 +1,7 @@
mystmd
jupyter-server
ipykernel
matplotlib
numpy
pandas
scipy