Skip to content

Commit 0a485f8

Browse files
committed
[circuits] added switch
1 parent 6135f99 commit 0a485f8

File tree

1 file changed

+168
-8
lines changed

1 file changed

+168
-8
lines changed

src/plottools/circuits.py

+168-8
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
- `ground_u()`: draw ground upwards.
1515
- `opamp_l()`: draw an operational amplifier with inputs on the left.
1616
- `opamp_l()`: draw an operational amplifier with inputs on the right.
17+
- `switch_h()`: draw a horizontal switch.
18+
- `switch_v()`: draw a vertical switch.
1719
- `node()`: draw a node connecting lines.
1820
- `connect()`: draw lines directly connecting circuit elements.
1921
- `connect_straight()`: draw straight lines connecting circuit elements.
@@ -310,7 +312,7 @@ def resistance_v(ax, pos, label='', align='right', lw=None, color=None,
310312
label: string
311313
Optional label for the resistance.
312314
align: 'left', 'right', 'center'
313-
Position the label to th left, right or in the center of the resistance.
315+
Position the label to the left, right or in the center of the resistance.
314316
lw: float, int
315317
Linewidth for drawing the outline of the resistance.
316318
Defaults to `circuits.linewidth` rcParams settings.
@@ -1147,6 +1149,149 @@ def opamp_r(ax, pos, label='', align='above', lw=None, color=None,
11471149
return Pos(x + r, y - 0.2*a), Pos(x + r, y + 0.2*a), Pos(x - 2*r, y), Pos(x, y-1.2*r), Pos(x, y+1.2*r)
11481150

11491151

1152+
def switch_h(ax, pos, label='', align='above', lw=None, color=None,
1153+
zorder=None, **kwargs):
1154+
""" Draw a horizontal switch.
1155+
1156+
Parameters
1157+
----------
1158+
ax: matplotlib axes
1159+
Axes where to draw the switch.
1160+
pos: Pos or 2-tuple of floats
1161+
x and y-coordinate of position of the center of the switch.
1162+
label: string
1163+
Optional label for the switch.
1164+
align: 'above', 'below'
1165+
Position the label above or below the switch.
1166+
lw: float, int
1167+
Linewidth for drawing the wire of the switch.
1168+
Defaults to `circuits.connectwidth` rcParams settings.
1169+
color matplotlib color
1170+
Color for the wire of the switch.
1171+
Defaults to `circuits.color` rcParams settings.
1172+
zorder: int
1173+
zorder for the switch and the label.
1174+
Defaults to `circuits.zorder` rcParams settings.
1175+
kwargs: key-word arguments
1176+
Passed on to `ax.text()` used to print the label.
1177+
Defaults to `circuits.font` rcParams settings.
1178+
1179+
Returns
1180+
-------
1181+
posl: Pos
1182+
Coordinates of the left end of the switch.
1183+
posr: Pos
1184+
Coordinates of the right end of the switch.
1185+
1186+
Raises
1187+
------
1188+
ValueError:
1189+
Invalid value for `align`.
1190+
"""
1191+
if lw is None:
1192+
lw = mpl.rcParams['circuits.connectwidth']
1193+
if color is None:
1194+
color = mpl.rcParams['circuits.color']
1195+
if zorder is None:
1196+
zorder = mpl.rcParams['circuits.zorder']
1197+
for k in mpl.rcParams['circuits.font']:
1198+
if not k in kwargs:
1199+
kwargs[k] = mpl.rcParams['circuits.font'][k]
1200+
w = mpl.rcParams['circuits.scale']
1201+
h = 0.5*mpl.rcParams['circuits.scale']
1202+
x, y = pos
1203+
ax.plot([x - 0.3*w, x + 0.3*w], [y, y + 0.5*h],
1204+
color=color, lw=lw)
1205+
if label:
1206+
ha = 'center'
1207+
va = 'center'
1208+
if align == 'above' or align == 'top':
1209+
yy = 0.7*h
1210+
va = 'bottom'
1211+
elif align == 'below' or align == 'bottom':
1212+
yy = -0.3*h
1213+
va = 'top'
1214+
else:
1215+
raise ValueError('align must be "above" or "bottom"')
1216+
if not 'ha' in kwargs and not 'horizontalalignment' in kwargs:
1217+
kwargs['ha'] = ha
1218+
if not 'va' in kwargs and not 'verticalalignment' in kwargs:
1219+
kwargs['va'] = va
1220+
ax.text(x, y + yy, label, zorder=zorder+1, **kwargs)
1221+
return Pos(x - 0.3*w, y), Pos(x + 0.3*w, y)
1222+
1223+
1224+
def switch_v(ax, pos, label='', align='right', lw=None, color=None,
1225+
zorder=None, **kwargs):
1226+
""" Draw a vertical switch.
1227+
1228+
Parameters
1229+
----------
1230+
ax: matplotlib axes
1231+
Axes where to draw the switch.
1232+
pos: Pos or 2-tuple of floats
1233+
x and y-coordinate of position of the center of the switch.
1234+
label: string
1235+
Optional label for the switch.
1236+
align: 'left', 'right'
1237+
Position the label to the left or right of the switch.
1238+
lw: float, int
1239+
Linewidth for drawing the wire of the switch.
1240+
Defaults to `circuits.connectwidth` rcParams settings.
1241+
color matplotlib color
1242+
Color for the wire of the switch.
1243+
Defaults to `circuits.color` rcParams settings.
1244+
zorder: int
1245+
zorder for the switch and the label.
1246+
Defaults to `circuits.zorder` rcParams settings.
1247+
kwargs: key-word arguments
1248+
Passed on to `ax.text()` used to print the label.
1249+
Defaults to `circuits.font` rcParams settings.
1250+
1251+
Returns
1252+
-------
1253+
posb: Pos
1254+
Coordinates of the bottom end of the switch.
1255+
post: Pos
1256+
Coordinates of the top end of the switch.
1257+
1258+
Raises
1259+
------
1260+
ValueError:
1261+
Invalid value for `align`.
1262+
"""
1263+
if lw is None:
1264+
lw = mpl.rcParams['circuits.connectwidth']
1265+
if color is None:
1266+
color = mpl.rcParams['circuits.color']
1267+
if zorder is None:
1268+
zorder = mpl.rcParams['circuits.zorder']
1269+
for k in mpl.rcParams['circuits.font']:
1270+
if not k in kwargs:
1271+
kwargs[k] = mpl.rcParams['circuits.font'][k]
1272+
w = 0.5*mpl.rcParams['circuits.scale']
1273+
h = mpl.rcParams['circuits.scale']
1274+
x, y = pos
1275+
ax.plot([x, x + 0.5*w], [y + 0.3*h, y - 0.3*h], color=color, lw=lw)
1276+
if label:
1277+
ha = 'center'
1278+
va = 'center'
1279+
if align == 'right':
1280+
xx = 0.7*w
1281+
ha = 'left'
1282+
elif align == 'left':
1283+
xx = -0.3*w
1284+
ha = 'right'
1285+
else:
1286+
raise ValueError('align must be "left" or "right"')
1287+
if not 'ha' in kwargs and not 'horizontalalignment' in kwargs:
1288+
kwargs['ha'] = ha
1289+
if not 'va' in kwargs and not 'verticalalignment' in kwargs:
1290+
kwargs['va'] = va
1291+
ax.text(x + xx, y, label, zorder=zorder+1, **kwargs)
1292+
return Pos(x, y - 0.3*h), Pos(x, y + 0.3*h)
1293+
1294+
11501295
def node(ax, pos, label='', align='northeast', color=None,
11511296
zorder=None, **kwargs):
11521297
""" Draw a node connecting lines.
@@ -1225,7 +1370,7 @@ def connect(ax, nodes, lw=None, color=None, zorder=None):
12251370
counter-clockwise direction.
12261371
lw: float, int
12271372
Linewidth for drawing the connection lines.
1228-
Defaults to `circuits.linewidth` rcParams settings.
1373+
Defaults to `circuits.connectwidth` rcParams settings.
12291374
color matplotlib color
12301375
Color of the connection lines.
12311376
Defaults to `circuits.color` rcParams settings.
@@ -1392,6 +1537,10 @@ def install_circuits():
13921537
mpl.axes.Axes.opamp_l = opamp_l
13931538
if not hasattr(mpl.axes.Axes, 'opamp_r'):
13941539
mpl.axes.Axes.opamp_r = opamp_r
1540+
if not hasattr(mpl.axes.Axes, 'switch_h'):
1541+
mpl.axes.Axes.switch_h = switch_h
1542+
if not hasattr(mpl.axes.Axes, 'switch_v'):
1543+
mpl.axes.Axes.switch_v = switch_v
13951544
if not hasattr(mpl.axes.Axes, 'node'):
13961545
mpl.axes.Axes.node = node
13971546
if not hasattr(mpl.axes.Axes, 'connect'):
@@ -1449,6 +1598,10 @@ def uninstall_circuits():
14491598
delattr(mpl.axes.Axes, 'opamp_l')
14501599
if hasattr(mpl.axes.Axes, 'opamp_r'):
14511600
delattr(mpl.axes.Axes, 'opamp_r')
1601+
if hasattr(mpl.axes.Axes, 'switch_h'):
1602+
delattr(mpl.axes.Axes, 'switch_h')
1603+
if hasattr(mpl.axes.Axes, 'switch_v'):
1604+
delattr(mpl.axes.Axes, 'switch_v')
14521605
if hasattr(mpl.axes.Axes, 'node'):
14531606
delattr(mpl.axes.Axes, 'node')
14541607
if hasattr(mpl.axes.Axes, 'connect'):
@@ -1470,34 +1623,41 @@ def uninstall_circuits():
14701623

14711624
def demo():
14721625
fig, ax = plt.subplots()
1626+
14731627
e1b, e1t = ax.battery_v((0, 1), r'$E_1$')
14741628
r1b, r1t = ax.resistance_v((e1t[0], 3), r'$R_1$')
14751629
c1b, c1t = ax.capacitance_v((-2, 2), r'$C_1$')
14761630
ax.connect((e1t, r1b, None, r1t, r1t.ups(0.5), c1t, None,
14771631
c1b, e1b.downs(0.5), e1b))
1632+
14781633
e2l, e2r = ax.battery_h((0, -1), r'$E_2$', 'below')
14791634
r2l, r2r = ax.resistance_h((-2, e2l.y()), r'$R_2$', 'below')
14801635
c2l, c2r = ax.capacitance_h((-1, -3), r'$C_2$', 'below')
14811636
ax.connect((e2l, r2r, None, r2l, r2l.lefts(0.5), c2l, None,
14821637
c2r, e2r.rights(0.5), e2r))
1483-
op1n, op1p, op1o, op1g, op1pw = ax.opamp_l((4, 2), r'$OP1$')
1638+
1639+
op1n, op1p, op1o, op1g, op1pw = ax.opamp_l((5, 3), r'$OP1$')
1640+
s1b, s1t = ax.switch_v(op1g.downs(1), r'$S1$', 'left')
14841641
n1n = ax.node(op1n.lefts(2))
14851642
n1p = ax.node(op1p.lefts(2))
14861643
n1o = ax.node(op1o.rights(1))
1487-
gnd1 = ax.ground(op1g.downs(1), r'$GND_1$')
1644+
gnd1 = ax.ground(s1b.downs(1), r'$GND_1$')
14881645
ax.connect((op1n, n1n))
14891646
ax.connect((op1p, n1p))
14901647
ax.connect((op1o, n1o))
1491-
ax.connect((op1g, gnd1))
1492-
op2n, op2p, op2o, op2g, op2pw = ax.opamp_r((4, -2), r'$OP2$')
1648+
ax.connect((op1g, s1t, None, s1b, gnd1))
1649+
1650+
op2n, op2p, op2o, op2g, op2pw = ax.opamp_r((6, -2), r'$OP2$')
1651+
s2l, s2r = ax.switch_h(op2o.lefts(1), r'$S2$', 'below')
14931652
n2n = ax.node(op2n.rights(1))
14941653
n2p = ax.node(op2p.rights(1))
1495-
n2o = ax.node(op2o.lefts(2))
1654+
n2o = ax.node(s2l.lefts(1))
14961655
gnd2 = ax.ground(op2g.downs(1), r'$GND_2$', 'left')
14971656
ax.connect((op2n, n2n))
14981657
ax.connect((op2p, n2p))
1499-
ax.connect((op2o, n2o))
1658+
ax.connect((op2o, s2r, None, s2l, n2o))
15001659
ax.connect((op2g, gnd2))
1660+
15011661
ax.set_aspect('equal')
15021662
plt.show()
15031663

0 commit comments

Comments
 (0)