"""Original 20-V RMS, 3+4j-ohm load: phase, instantaneous and mean power.""" from pathlib import Path import matplotlib.pyplot as plt import numpy as np def main(): potential = 20.0 impedance = 3 + 4j current = potential / impedance complex_power = potential * np.conjugate(current) assert np.isclose(current, 2.4 - 3.2j) assert np.isclose(complex_power, 48 + 64j) phase_lag = -np.angle(current) x = np.linspace(0, 2 * np.pi, 2049) v = np.sqrt(2) * potential * np.cos(x) i = np.sqrt(2) * abs(current) * np.cos(x - phase_lag) power = v * i assert np.allclose(power, 48 + 80 * np.cos(2 * x - phase_lag)) assert np.isclose(np.trapezoid(power, x) / (2 * np.pi), 48) fig, (signals, transfer) = plt.subplots(1, 2, figsize=(10, 4.2), dpi=100, layout="constrained") fig.set_facecolor("white") signals.plot(x, v / (np.sqrt(2) * potential), color="#246b96", label="v / peak v") signals.plot(x, i / (np.sqrt(2) * abs(current)), color="#b66d32", label="i / peak i") signals.set(ylabel="Normalized waveform", ylim=(-1.2, 1.42), title="Current lags by 53.13°; power factor = 0.6") signals.legend(loc="upper right", fontsize=9) transfer.plot(x, power, color="#246b96", label="Instantaneous power") transfer.fill_between(x, power, 0, where=power < 0, interpolate=True, color="#b66d32", alpha=0.35, label="Energy return") transfer.axhline(48, color="#333333", linestyle="--", linewidth=1.2, label="Cycle average = 48 W") transfer.set(ylabel="Power (W)", ylim=(-45, 180), title="Power ranges from −32 to 128 W") transfer.legend(loc="upper right", fontsize=8.5) for ax in [signals, transfer]: ax.set(xlim=(0, 2 * np.pi), xlabel="Phase ωt (radians)", xticks=np.arange(5) * np.pi / 2, xticklabels=["0", "π/2", "π", "3π/2", "2π"]) ax.axhline(0, color="#777777", linewidth=0.6) ax.grid(alpha=0.15) fig.savefig(Path(__file__).with_suffix(".png").name, facecolor="white") plt.close(fig) if __name__ == "__main__": main()