codexwheatstone-bridge-circuit-and-thevenin-equivalent.py
wheatstone-bridge-circuit-and-thevenin-equivalent.py
"""Draw the DC bridge and its detector-port equivalent; Python 3.14/matplotlib 3.10.7."""
from pathlib import Path
import matplotlib.pyplot as plt
from matplotlib.patches import Circle, Rectangle
WIRE = "#263442"
BLUE = "#1767a6"
RED = "#b64629"
def wire(ax, xs, ys):
ax.plot(xs, ys, color=WIRE, lw=2, solid_capstyle="round")
def resistor(ax, x, y, label, color=BLUE, vertical=True):
if vertical:
rect = Rectangle((x - 0.17, y - 0.44), 0.34, 0.88)
ax.text(x + 0.34, y, label, va="center", fontsize=12, color=color)
else:
rect = Rectangle((x - 0.48, y - 0.16), 0.96, 0.32)
ax.text(x, y + 0.35, label, ha="center", fontsize=12, color=color)
rect.set(facecolor="white", edgecolor=color, linewidth=2, zorder=3)
ax.add_patch(rect)
def node(ax, x, y, label, dy=0.21):
ax.plot(x, y, "o", color=WIRE, ms=5)
ax.text(x, y + dy, label, ha="center", fontsize=12, fontweight="bold")
def main():
plt.rcParams.update({"font.family": "DejaVu Sans", "font.size": 11})
fig, (left, right) = plt.subplots(1, 2, figsize=(12, 6.3), dpi=110)
fig.patch.set_facecolor("white")
for ax in (left, right):
ax.set_xlim(-0.3, 7.4)
ax.set_ylim(-0.8, 6.4)
ax.set_aspect("equal")
ax.axis("off")
left.set_title("Four-arm DC bridge", fontsize=15, pad=15)
wire(left, [1.0, 1.0, 6.0, 6.0, 1.0], [0.4, 5.4, 5.4, 0.4, 0.4])
# The ideal supply interrupts the outer left wire.
left.add_patch(Circle((1.0, 2.9), 0.43, facecolor="white", edgecolor=WIRE, lw=2, zorder=3))
left.text(1.0, 3.10, "+", ha="center", va="center", fontsize=14)
left.text(1.0, 2.69, "−", ha="center", va="center", fontsize=14)
left.text(0.28, 2.9, "$V_s$", ha="center", va="center", fontsize=14)
wire(left, [2.8, 2.8], [0.4, 5.4])
resistor(left, 2.8, 4.16, "$R_1$")
resistor(left, 2.8, 1.64, "$R_2$")
resistor(left, 6.0, 4.16, "$R_3$\nadjustable")
resistor(left, 6.0, 1.64, "$R_x$\nunknown", color=RED)
left.annotate("", xy=(6.24, 4.62), xytext=(5.74, 3.74),
arrowprops={"arrowstyle": "->", "lw": 1.5, "color": BLUE}, zorder=4)
wire(left, [2.8, 6.0], [2.9, 2.9])
resistor(left, 4.4, 2.9, "$R_d$", color=RED, vertical=False)
left.text(3.66, 2.6, "+", color=RED, fontsize=13)
left.text(4.97, 2.6, "−", color=RED, fontsize=13)
left.text(4.4, 2.23, "null detector", ha="center", color=RED)
node(left, 4.4, 5.4, "$A: V_s$")
node(left, 4.4, 0.4, "$D: 0$", dy=-0.4)
node(left, 2.8, 2.9, "$B$", dy=0.24)
node(left, 6.0, 2.9, "$C$", dy=0.24)
left.text(4.4, -0.48, "$V_d=V_B-V_C$", ha="center", fontsize=13)
right.set_title("Equivalent seen between B and C", fontsize=15, pad=15)
wire(right, [1.0, 1.0, 5.8], [1.2, 4.2, 4.2])
wire(right, [1.0, 5.8], [1.2, 1.2])
right.add_patch(Circle((1.0, 2.7), 0.43, facecolor="white", edgecolor=WIRE, lw=2, zorder=3))
right.text(1.0, 2.91, "+", ha="center", va="center", fontsize=14)
right.text(1.0, 2.49, "−", ha="center", va="center", fontsize=14)
right.text(0.4, 2.7, "$V_{oc}$", ha="right", va="center", fontsize=13)
resistor(right, 3.4, 4.2, "$R_{th}$", vertical=False)
wire(right, [5.8, 5.8], [1.2, 4.2])
resistor(right, 5.8, 2.7, "$R_d$", color=RED)
node(right, 5.8, 4.2, "$B$", dy=0.25)
node(right, 5.8, 1.2, "$C$", dy=-0.4)
right.text(6.28, 3.49, "+", color=RED, fontsize=13)
right.text(6.28, 1.89, "−", color=RED, fontsize=13)
right.text(3.4, 5.25, "Ideal supply set to zero when finding $R_{th}$", ha="center", fontsize=10)
right.text(3.5, 0.25, "$R_{th}=(R_1\\parallel R_2)+(R_3\\parallel R_x)$", ha="center", fontsize=13)
right.text(3.5, -0.35, "$V_d=V_{oc}R_d/(R_{th}+R_d)$", ha="center", fontsize=13)
fig.tight_layout(pad=2)
fig.savefig(Path.cwd() / (Path(__file__).stem + ".png"), facecolor="white")
plt.close(fig)
if __name__ == "__main__":
main()