technischeDoku/plot.py

75 lines
3.0 KiB
Python

"""
plot.py -- erzeugt aus messwerte.csv:
* plot.pdf Bode-Diagramm (Betrag und Phase)
* tabelle.tex LaTeX-Tabelle (mit siunitx S-Spalten)
* werte.tex LaTeX-Makros mit Rohzahlen (1.59 statt 1{,}59)
Aenderung gegenueber Stufe 2:
siunitx (\\SI{...}{...}) im paper.tex formatiert die Zahlen jetzt
selber -- wir geben hier nur Rohzahlen mit Punkt aus. Das macht
plot.py einfacher (kein "Komma-Bastel" mehr).
"""
import numpy as np
import matplotlib.pyplot as plt
# 1) CSV einlesen ------------------------------------------------------
daten = np.loadtxt("messwerte.csv", delimiter=",", skiprows=1)
omega = daten[:, 0] # Kreisfrequenz in rad/s
betrag = daten[:, 1] # Amplitudengang in dB
phase = daten[:, 2] # Phasengang in Grad
# 2) Theoretische Knickfrequenz (aus Identifikation der Strecke) -------
omega_K_theor = 56 # PT2-Modell, omega_n
K_s_dB = betrag[0] # DC-Verstaerkung (tiefste Frequenz)
# 3) Gemessene Knickfrequenz: dort wo der Betrag um 3 dB faellt --------
ziel_dB = K_s_dB - 3
omega_K_mess = np.interp(ziel_dB, np.flip(betrag), np.flip(omega))
abweichung = abs(omega_K_mess - omega_K_theor) / omega_K_theor * 100
# 4) Bode-Diagramm zeichnen --------------------------------------------
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(5, 4), sharex=True)
ax1.semilogx(omega, betrag, "o-")
ax1.axhline(ziel_dB, linestyle=":", color="gray",
label=f"$K_s - 3$ dB = {ziel_dB:.2f} dB")
ax1.axvline(omega_K_theor, linestyle="--", color="gray",
label=f"$\\omega_K$ theor. = {omega_K_theor} rad/s")
ax1.set_ylabel("Betrag in dB")
ax1.legend(loc="lower left", fontsize=8)
ax1.grid(True, which="both", alpha=0.3)
ax2.semilogx(omega, phase, "o-")
ax2.set_xlabel("Kreisfrequenz $\\omega$ in rad/s")
ax2.set_ylabel("Phase in Grad")
ax2.grid(True, which="both", alpha=0.3)
fig.tight_layout()
fig.savefig("plot.pdf")
# 5) Tabelle (S-Spalten -- siunitx richtet am Komma aus) ---------------
zeilen = [
r"\begin{tabular}{S[table-format=4.1] S[table-format=-2.2] S[table-format=-3.1]}",
r"\toprule",
r"{$\omega$ (rad/s)} & {Betrag (dB)} & {Phase ($^\circ$)} \\",
r"\midrule",
]
for i in range(len(omega)):
zeilen.append(f"{omega[i]:g} & {betrag[i]:.2f} & {phase[i]:.1f} \\\\")
zeilen.append(r"\bottomrule")
zeilen.append(r"\end{tabular}")
with open("tabelle.tex", "w", encoding="utf-8") as datei:
datei.write("\n".join(zeilen) + "\n")
# 6) Werte als LaTeX-Makros (Rohzahlen -- siunitx formatiert deutsch) --
with open("werte.tex", "w", encoding="utf-8") as datei:
datei.write(f"\\newcommand{{\\omegaKtheorie}}{{{omega_K_theor}}}\n")
datei.write(f"\\newcommand{{\\omegaKmess}}{{{omega_K_mess:.1f}}}\n")
datei.write(f"\\newcommand{{\\abweichung}}{{{abweichung:.1f}}}\n")
print("Fertig: plot.pdf, tabelle.tex, werte.tex")
print(f" theoretisch: omega_K = {omega_K_theor} rad/s")
print(f" gemessen: omega_K = {omega_K_mess:.2f} rad/s")
print(f" Abweichung: {abweichung:.1f} %")