Initial commit
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
os.environ.setdefault("MPLCONFIGDIR", "/tmp/matplotlib")
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
FONT_NAME = "STIXGeneral"
|
||||
BG_COLOR = "white"
|
||||
LINE_COLOR = "#111111"
|
||||
DEFAULT_OUTPUT = (
|
||||
Path(__file__).resolve().parent.parent / "image" / "exp0" / "ro_measure_diagram.svg"
|
||||
)
|
||||
|
||||
|
||||
def draw_diagram(save_path=DEFAULT_OUTPUT):
|
||||
save_path = Path(save_path)
|
||||
save_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
plt.rcParams["font.family"] = FONT_NAME
|
||||
plt.rcParams["axes.unicode_minus"] = False
|
||||
|
||||
fig, ax = plt.subplots(figsize=(5.2, 5.5), dpi=160)
|
||||
fig.patch.set_facecolor(BG_COLOR)
|
||||
ax.set_facecolor(BG_COLOR)
|
||||
|
||||
# 坐标范围
|
||||
ax.set_xlim(-0.6, 9.8)
|
||||
ax.set_ylim(-0.45, 9.85)
|
||||
ax.axis("off")
|
||||
|
||||
# 关键点
|
||||
origin = (0.0, 0.0)
|
||||
u_oc = (0.0, 8.8)
|
||||
i_sc = (8.3, 0.0)
|
||||
a_pt = (2.6, 6.05)
|
||||
b_pt = (5.5, 2.95)
|
||||
|
||||
# 坐标轴
|
||||
ax.annotate(
|
||||
"",
|
||||
xy=(9.35, 0.0),
|
||||
xytext=origin,
|
||||
arrowprops=dict(arrowstyle="-|>", lw=1.9, color=LINE_COLOR),
|
||||
)
|
||||
ax.annotate(
|
||||
"",
|
||||
xy=(0.0, 9.65),
|
||||
xytext=origin,
|
||||
arrowprops=dict(arrowstyle="-|>", lw=1.9, color=LINE_COLOR),
|
||||
)
|
||||
|
||||
# 主特性直线
|
||||
ax.plot([u_oc[0], i_sc[0]], [u_oc[1], i_sc[1]], color=LINE_COLOR, lw=2.2)
|
||||
|
||||
# A/B 点
|
||||
ax.text(a_pt[0] + 0.18, a_pt[1] + 0.22, "A", fontsize=14)
|
||||
ax.text(b_pt[0] + 0.18, b_pt[1] - 0.1, "B", fontsize=14)
|
||||
|
||||
# ΔU / ΔI 虚线框
|
||||
x_left = a_pt[0]
|
||||
x_right = b_pt[0]
|
||||
y_top = a_pt[1]
|
||||
y_bottom = b_pt[1]
|
||||
dash = (0, (6, 4))
|
||||
|
||||
ax.plot([x_left, x_left], [0, y_top], color=LINE_COLOR, lw=1.3, ls=dash)
|
||||
ax.plot([x_right, x_right], [0, y_bottom], color=LINE_COLOR, lw=1.3, ls=dash)
|
||||
ax.plot([0, x_left], [y_top, y_top], color=LINE_COLOR, lw=1.3, ls=dash)
|
||||
ax.plot([0, x_right], [y_bottom, y_bottom], color=LINE_COLOR, lw=1.3, ls=dash)
|
||||
|
||||
# ΔU 竖向双箭头
|
||||
x_du = 1.45
|
||||
ax.annotate(
|
||||
"",
|
||||
xy=(x_du, y_top),
|
||||
xytext=(x_du, y_bottom),
|
||||
arrowprops=dict(arrowstyle="<|-|>", lw=1.4, color=LINE_COLOR),
|
||||
)
|
||||
ax.text(x_du - 0.55, (y_top + y_bottom) / 2 - 0.15, r"$\Delta U$", fontsize=14)
|
||||
|
||||
# ΔI 横向双箭头
|
||||
y_di = 1.05
|
||||
ax.annotate(
|
||||
"",
|
||||
xy=(x_right, y_di),
|
||||
xytext=(x_left, y_di),
|
||||
arrowprops=dict(arrowstyle="<|-|>", lw=1.4, color=LINE_COLOR),
|
||||
)
|
||||
ax.text((x_left + x_right) / 2 - 0.35, y_di - 0.72, r"$\Delta I$", fontsize=14)
|
||||
|
||||
# 角度 phi
|
||||
ax.text(4.32, 2.3, r"$\varphi$", fontsize=16)
|
||||
|
||||
# 轴与截距标注
|
||||
ax.text(9.05, -0.48, r"$I$", fontsize=18)
|
||||
ax.text(0.25, 9.35, r"$U$", fontsize=18)
|
||||
ax.text(-0.18, -0.35, "0", fontsize=13)
|
||||
ax.text(0.22, 8.9, r"$U_{oc}$", fontsize=14)
|
||||
ax.text(8.06, -0.62, r"$I_{sc}$", fontsize=14)
|
||||
|
||||
fig.tight_layout(pad=0.2)
|
||||
fig.savefig(save_path, bbox_inches="tight")
|
||||
plt.close(fig)
|
||||
print(f"saved to: {save_path}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
output_path = sys.argv[1] if len(sys.argv) > 1 else DEFAULT_OUTPUT
|
||||
draw_diagram(output_path)
|
||||
@@ -0,0 +1,121 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
os.environ.setdefault("MPLCONFIGDIR", "/tmp/matplotlib")
|
||||
|
||||
import schemdraw
|
||||
import schemdraw.elements as elm
|
||||
from schemdraw.segments import SegmentText
|
||||
|
||||
FONT_NAME = "STIXGeneral"
|
||||
BG_COLOR = "white"
|
||||
DEFAULT_OUTPUT = Path(__file__).resolve().parent.parent / "image" / "target_circuit.svg"
|
||||
|
||||
|
||||
def add_text(
|
||||
drawing,
|
||||
position,
|
||||
text,
|
||||
*,
|
||||
fontsize=18,
|
||||
rotation=0,
|
||||
align=("center", "center"),
|
||||
):
|
||||
element = elm.Element().at(position).anchor("center").hold()
|
||||
element.anchors["center"] = (0, 0)
|
||||
element.segments.append(
|
||||
SegmentText(
|
||||
(0, 0),
|
||||
text,
|
||||
rotation=rotation,
|
||||
align=align,
|
||||
fontsize=fontsize,
|
||||
font=FONT_NAME,
|
||||
)
|
||||
)
|
||||
drawing.add(element)
|
||||
|
||||
|
||||
def draw_circuit(save_path=DEFAULT_OUTPUT):
|
||||
save_path = Path(save_path)
|
||||
save_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
with schemdraw.Drawing(show=False) as d:
|
||||
d.config(
|
||||
unit=1.0,
|
||||
fontsize=18,
|
||||
font=FONT_NAME,
|
||||
lw=2.2,
|
||||
margin=0.2,
|
||||
bgcolor=BG_COLOR,
|
||||
)
|
||||
|
||||
# 关键节点,整体布局按参考图重排。
|
||||
a_node = (1.4, 4.0)
|
||||
top_node = (5.2, 6.6)
|
||||
bottom_node = (5.2, 1.9)
|
||||
right_node = (9.3, 4.0)
|
||||
bottom_left = (1.4, 0.8)
|
||||
top_term = (10.9, 4.0)
|
||||
bottom_term = (10.9, 1.9)
|
||||
|
||||
source_start = (4.8, 0.8)
|
||||
source_len = 1.6
|
||||
source_end = (source_start[0] + source_len, source_start[1])
|
||||
|
||||
# 主电路元件
|
||||
d.add(elm.ResistorIEC().at(a_node).to(top_node).hold())
|
||||
d.add(elm.ResistorIEC().at(a_node).to(bottom_node).hold())
|
||||
d.add(elm.ResistorIEC().at(top_node).to(right_node).hold())
|
||||
d.add(elm.Source().at(bottom_node).up(top_node[1] - bottom_node[1]).hold())
|
||||
d.add(elm.ResistorIEC().at(bottom_left).up(a_node[1] - bottom_left[1]).hold())
|
||||
|
||||
# 下方电压源支路
|
||||
d.add(elm.Line().at(bottom_left).right(source_start[0] - bottom_left[0]).hold())
|
||||
d.add(elm.Source().at(source_start).right(source_len).hold())
|
||||
d.add(elm.Line().at(source_end).right(right_node[0] - source_end[0]).hold())
|
||||
|
||||
# 右侧导线与端子
|
||||
d.add(elm.Line().at(right_node).right(top_term[0] - right_node[0]).hold())
|
||||
d.add(elm.Line().at(right_node).down(right_node[1] - source_start[1]).hold())
|
||||
d.add(elm.Line().at(bottom_node).right(bottom_term[0] - bottom_node[0]).hold())
|
||||
|
||||
# 电流源符号细节:空心圆、内部横线、外部向上箭头。
|
||||
source_center_y = (top_node[1] + bottom_node[1]) / 2
|
||||
d.add(elm.Line().at((4.74, source_center_y)).right(0.92).hold())
|
||||
d.add(elm.Arrow().at((5.2, 4.9)).up(1.0).hold())
|
||||
|
||||
# 电压源符号细节:圆内水平线。
|
||||
d.add(elm.Line().at(source_start).right(source_len).hold())
|
||||
|
||||
# 节点和开口端子
|
||||
for point in [a_node, top_node, bottom_node, right_node]:
|
||||
d.add(elm.Dot(radius=0.085).at(point).hold())
|
||||
|
||||
d.add(elm.Dot(open=True, radius=0.1).at(top_term).hold())
|
||||
d.add(elm.Dot(open=True, radius=0.1).at(bottom_term).hold())
|
||||
|
||||
# 文本标注
|
||||
add_text(d, (2.35, 5.18), r"$R_1$", fontsize=19)
|
||||
|
||||
add_text(d, (8.78, 5.12), r"$R_3$", fontsize=19)
|
||||
|
||||
add_text(d, (2.42, 2.62), r"$R_2$", fontsize=19)
|
||||
|
||||
add_text(d, (0.55, 1.28), r"$R_4$", fontsize=19)
|
||||
|
||||
add_text(d, (6.42, 4.82), r"$I_S$", fontsize=19)
|
||||
|
||||
add_text(d, (4.3, 0.36), "-", fontsize=21)
|
||||
add_text(d, (6.98, 0.36), "+", fontsize=21)
|
||||
add_text(d, (4.78, -0.05), r"$U_S$", fontsize=19)
|
||||
|
||||
d.save(str(save_path), transparent=False)
|
||||
|
||||
print(f"saved to: {save_path}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
output_path = sys.argv[1] if len(sys.argv) > 1 else DEFAULT_OUTPUT
|
||||
draw_circuit(output_path)
|
||||
@@ -0,0 +1,129 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
os.environ.setdefault("MPLCONFIGDIR", "/tmp/matplotlib")
|
||||
|
||||
import schemdraw
|
||||
import schemdraw.elements as elm
|
||||
from schemdraw.segments import SegmentText
|
||||
|
||||
FONT_NAME = "STIXGeneral"
|
||||
BG_COLOR = "white"
|
||||
DEFAULT_OUTPUT = Path(__file__).resolve().parent.parent / "image" / "target_circuit_measure.svg"
|
||||
|
||||
|
||||
def add_text(
|
||||
drawing,
|
||||
position,
|
||||
text,
|
||||
*,
|
||||
fontsize=18,
|
||||
rotation=0,
|
||||
align=("center", "center"),
|
||||
):
|
||||
element = elm.Element().at(position).anchor("center").hold()
|
||||
element.anchors["center"] = (0, 0)
|
||||
element.segments.append(
|
||||
SegmentText(
|
||||
(0, 0),
|
||||
text,
|
||||
rotation=rotation,
|
||||
align=align,
|
||||
fontsize=fontsize,
|
||||
font=FONT_NAME,
|
||||
)
|
||||
)
|
||||
drawing.add(element)
|
||||
|
||||
|
||||
def draw_circuit(save_path=DEFAULT_OUTPUT):
|
||||
save_path = Path(save_path)
|
||||
save_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
with schemdraw.Drawing(show=False) as d:
|
||||
d.config(
|
||||
unit=1.0,
|
||||
fontsize=18,
|
||||
font=FONT_NAME,
|
||||
lw=2.2,
|
||||
margin=0.2,
|
||||
bgcolor=BG_COLOR,
|
||||
)
|
||||
|
||||
# 左侧原电路
|
||||
left_node = (1.4, 4.0)
|
||||
top_node = (5.2, 6.6)
|
||||
bottom_node = (5.2, 1.9)
|
||||
right_node = (9.3, 4.0)
|
||||
bottom_left = (1.4, 0.8)
|
||||
|
||||
source_start = (4.8, 0.8)
|
||||
source_len = 1.6
|
||||
source_end = (source_start[0] + source_len, source_start[1])
|
||||
|
||||
d.add(elm.ResistorIEC().at(left_node).to(top_node).hold())
|
||||
d.add(elm.ResistorIEC().at(left_node).to(bottom_node).hold())
|
||||
d.add(elm.ResistorIEC().at(top_node).to(right_node).hold())
|
||||
d.add(elm.Source().at(bottom_node).up(top_node[1] - bottom_node[1]).hold())
|
||||
d.add(elm.ResistorIEC().at(bottom_left).up(left_node[1] - bottom_left[1]).hold())
|
||||
|
||||
d.add(elm.Line().at(bottom_left).right(source_start[0] - bottom_left[0]).hold())
|
||||
d.add(elm.Source().at(source_start).right(source_len).hold())
|
||||
d.add(elm.Line().at(source_end).right(right_node[0] - source_end[0]).hold())
|
||||
|
||||
d.add(elm.Line().at(right_node).down(right_node[1] - source_start[1]).hold())
|
||||
|
||||
# 左侧源符号细节
|
||||
source_center_y = (top_node[1] + bottom_node[1]) / 2
|
||||
d.add(elm.Line().at((4.74, source_center_y)).right(0.92).hold())
|
||||
d.add(elm.Arrow().at((5.2, 4.9)).up(1.0).hold())
|
||||
d.add(elm.Line().at(source_start).right(source_len).hold())
|
||||
|
||||
# 右侧测量电路,尽量使用 schemdraw 自带电表与可变电阻元件。
|
||||
meter_top = (10.75, 4.0)
|
||||
meter_bottom_y = bottom_node[1]
|
||||
b_node = (14.2, bottom_node[1])
|
||||
a_left = (12.15, meter_top[1])
|
||||
a_node = (14.2, meter_top[1])
|
||||
load_x = 15.8
|
||||
|
||||
d.add(elm.Line().at(right_node).right(meter_top[0] - right_node[0]).hold())
|
||||
d.add(elm.MeterV().at(meter_top).down(meter_top[1] - meter_bottom_y).hold())
|
||||
d.add(elm.Line().at(bottom_node).right(b_node[0] - bottom_node[0]).hold())
|
||||
|
||||
d.add(elm.MeterA().at(meter_top).right(a_left[0] - meter_top[0]).hold())
|
||||
d.add(elm.Line().at(a_left).right(a_node[0] - a_left[0]).hold())
|
||||
|
||||
d.add(elm.Dot(open=True, radius=0.1).at(a_node).hold())
|
||||
d.add(elm.Dot(open=True, radius=0.1).at(b_node).hold())
|
||||
|
||||
d.add(elm.Line().at(a_node).right(load_x - a_node[0]).hold())
|
||||
d.add(elm.Line().at(b_node).right(load_x - b_node[0]).hold())
|
||||
d.add(elm.ResistorVarIEC().at((load_x, b_node[1])).up(a_node[1] - b_node[1]).hold())
|
||||
|
||||
# 关键节点
|
||||
for point in [left_node, top_node, bottom_node, right_node, (right_node[0], bottom_node[1])]:
|
||||
d.add(elm.Dot(radius=0.085).at(point).hold())
|
||||
|
||||
# 文本标注
|
||||
add_text(d, (2.35, 5.18), r"$R_1$", fontsize=19)
|
||||
add_text(d, (8.78, 5.12), r"$R_3$", fontsize=19)
|
||||
add_text(d, (2.42, 2.62), r"$R_2$", fontsize=19)
|
||||
add_text(d, (0.55, 1.28), r"$R_4$", fontsize=19)
|
||||
add_text(d, (6.42, 4.82), r"$I_S$", fontsize=19)
|
||||
|
||||
add_text(d, (4.3, 0.36), "-", fontsize=21)
|
||||
add_text(d, (6.98, 0.36), "+", fontsize=21)
|
||||
add_text(d, (4.78, -0.05), r"$U_S$", fontsize=19)
|
||||
|
||||
add_text(d, (13.35, 1.35), "B", fontsize=16)
|
||||
add_text(d, (16.55, 3.0), r"$R_L$", fontsize=19)
|
||||
d.save(str(save_path), transparent=False)
|
||||
|
||||
print(f"saved to: {save_path}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
output_path = sys.argv[1] if len(sys.argv) > 1 else DEFAULT_OUTPUT
|
||||
draw_circuit(output_path)
|
||||
@@ -0,0 +1,84 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
os.environ.setdefault("MPLCONFIGDIR", "/tmp/matplotlib")
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from matplotlib.ticker import AutoMinorLocator
|
||||
|
||||
FONT_NAME = "LXGW WenKai"
|
||||
BG_COLOR = "white"
|
||||
GRID_MAJOR = "#111111"
|
||||
GRID_MINOR = "#8a8a8a"
|
||||
LINE_COLOR = "#111111"
|
||||
POINT_COLOR = "#111111"
|
||||
|
||||
CURRENT_MA = np.array([11.20, 12.10, 13.00, 14.80, 16.36], dtype=float)
|
||||
VOLTAGE_V = np.array([11.25, 10.75, 10.25, 9.25, 8.75], dtype=float)
|
||||
|
||||
DEFAULT_OUTPUT = (
|
||||
Path(__file__).resolve().parent.parent / "image" / "exp2" / "vi_characteristic_curve.svg"
|
||||
)
|
||||
|
||||
|
||||
def draw_curve(save_path=DEFAULT_OUTPUT):
|
||||
save_path = Path(save_path)
|
||||
save_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
plt.rcParams["font.family"] = FONT_NAME
|
||||
plt.rcParams["axes.unicode_minus"] = False
|
||||
|
||||
slope, intercept = np.polyfit(CURRENT_MA, VOLTAGE_V, 1)
|
||||
fit_x = np.linspace(CURRENT_MA.min() - 0.4, CURRENT_MA.max() + 0.4, 200)
|
||||
fit_y = slope * fit_x + intercept
|
||||
|
||||
fig, ax = plt.subplots(figsize=(8.2, 6.0), dpi=160)
|
||||
fig.patch.set_facecolor(BG_COLOR)
|
||||
ax.set_facecolor(BG_COLOR)
|
||||
|
||||
ax.plot(
|
||||
fit_x,
|
||||
fit_y,
|
||||
color=LINE_COLOR,
|
||||
linewidth=2.2,
|
||||
zorder=2,
|
||||
)
|
||||
ax.scatter(
|
||||
CURRENT_MA,
|
||||
VOLTAGE_V,
|
||||
s=60,
|
||||
color=POINT_COLOR,
|
||||
edgecolors="white",
|
||||
linewidths=0.8,
|
||||
zorder=3,
|
||||
)
|
||||
|
||||
ax.set_xlabel("端口电流 I / mA", fontsize=13)
|
||||
ax.set_ylabel("端口电压 U / V", fontsize=13)
|
||||
|
||||
ax.set_xlim(11.0, 16.5)
|
||||
ax.set_ylim(8.5, 11.5)
|
||||
ax.set_xticks(np.arange(11, 17, 1))
|
||||
ax.set_yticks(np.arange(8.5, 11.6, 0.5))
|
||||
ax.xaxis.set_minor_locator(AutoMinorLocator(2))
|
||||
ax.yaxis.set_minor_locator(AutoMinorLocator(2))
|
||||
ax.set_box_aspect(6 / 5)
|
||||
|
||||
ax.grid(True, which="major", color=GRID_MAJOR, linewidth=0.95, alpha=0.9)
|
||||
ax.grid(True, which="minor", color=GRID_MINOR, linewidth=0.55, alpha=0.8)
|
||||
|
||||
for spine in ax.spines.values():
|
||||
spine.set_linewidth(1.0)
|
||||
spine.set_color("#111111")
|
||||
|
||||
fig.tight_layout()
|
||||
fig.savefig(save_path, bbox_inches="tight")
|
||||
plt.close(fig)
|
||||
print(f"saved to: {save_path}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
output_path = sys.argv[1] if len(sys.argv) > 1 else DEFAULT_OUTPUT
|
||||
draw_curve(output_path)
|
||||
@@ -0,0 +1,87 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
os.environ.setdefault("MPLCONFIGDIR", "/tmp/matplotlib")
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from matplotlib.ticker import AutoMinorLocator
|
||||
|
||||
FONT_NAME = "LXGW WenKai"
|
||||
BG_COLOR = "white"
|
||||
GRID_MAJOR = "#111111"
|
||||
GRID_MINOR = "#8a8a8a"
|
||||
LINE_COLOR = "#111111"
|
||||
POINT_COLOR = "#111111"
|
||||
|
||||
CURRENT_MA = np.array([10.63, 11.54, 12.71, 13.62, 14.76], dtype=float)
|
||||
VOLTAGE_V = np.array([10.82, 10.17, 9.57, 8.91, 8.21], dtype=float)
|
||||
|
||||
DEFAULT_OUTPUT = (
|
||||
Path(__file__).resolve().parent.parent
|
||||
/ "image"
|
||||
/ "exp3"
|
||||
/ "vi_characteristic_curve_table4.svg"
|
||||
)
|
||||
|
||||
|
||||
def draw_curve(save_path=DEFAULT_OUTPUT):
|
||||
save_path = Path(save_path)
|
||||
save_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
plt.rcParams["font.family"] = FONT_NAME
|
||||
plt.rcParams["axes.unicode_minus"] = False
|
||||
|
||||
slope, intercept = np.polyfit(CURRENT_MA, VOLTAGE_V, 1)
|
||||
fit_x = np.linspace(CURRENT_MA.min() - 0.4, CURRENT_MA.max() + 0.4, 200)
|
||||
fit_y = slope * fit_x + intercept
|
||||
|
||||
fig, ax = plt.subplots(figsize=(8.2, 6.0), dpi=160)
|
||||
fig.patch.set_facecolor(BG_COLOR)
|
||||
ax.set_facecolor(BG_COLOR)
|
||||
|
||||
ax.plot(
|
||||
fit_x,
|
||||
fit_y,
|
||||
color=LINE_COLOR,
|
||||
linewidth=2.2,
|
||||
zorder=2,
|
||||
)
|
||||
ax.scatter(
|
||||
CURRENT_MA,
|
||||
VOLTAGE_V,
|
||||
s=60,
|
||||
color=POINT_COLOR,
|
||||
edgecolors="white",
|
||||
linewidths=0.8,
|
||||
zorder=3,
|
||||
)
|
||||
|
||||
ax.set_xlabel("端口电流 I / mA", fontsize=13)
|
||||
ax.set_ylabel("端口电压 U / V", fontsize=13)
|
||||
|
||||
ax.set_xlim(10.5, 14.9)
|
||||
ax.set_ylim(8.0, 11.0)
|
||||
ax.set_xticks(np.arange(11, 15, 1))
|
||||
ax.set_yticks(np.arange(8.0, 11.1, 0.5))
|
||||
ax.xaxis.set_minor_locator(AutoMinorLocator(2))
|
||||
ax.yaxis.set_minor_locator(AutoMinorLocator(2))
|
||||
ax.set_box_aspect(6 / 5)
|
||||
|
||||
ax.grid(True, which="major", color=GRID_MAJOR, linewidth=0.95, alpha=0.9)
|
||||
ax.grid(True, which="minor", color=GRID_MINOR, linewidth=0.55, alpha=0.8)
|
||||
|
||||
for spine in ax.spines.values():
|
||||
spine.set_linewidth(1.0)
|
||||
spine.set_color("#111111")
|
||||
|
||||
fig.tight_layout()
|
||||
fig.savefig(save_path, bbox_inches="tight")
|
||||
plt.close(fig)
|
||||
print(f"saved to: {save_path}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
output_path = sys.argv[1] if len(sys.argv) > 1 else DEFAULT_OUTPUT
|
||||
draw_curve(output_path)
|
||||
@@ -0,0 +1,136 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
os.environ.setdefault("MPLCONFIGDIR", "/tmp/matplotlib")
|
||||
|
||||
import schemdraw
|
||||
import schemdraw.elements as elm
|
||||
from schemdraw.segments import Segment, SegmentCircle, SegmentText
|
||||
|
||||
FONT_NAME = "STIXGeneral"
|
||||
BG_COLOR = "white"
|
||||
DEFAULT_OUTPUT = Path(__file__).resolve().parent.parent / "image" / "thevenin_equiv.svg"
|
||||
|
||||
|
||||
def add_text(
|
||||
drawing,
|
||||
position,
|
||||
text,
|
||||
*,
|
||||
fontsize=18,
|
||||
rotation=0,
|
||||
align=("center", "center"),
|
||||
color="black",
|
||||
):
|
||||
element = elm.Element().at(position).anchor("center").hold()
|
||||
element.anchors["center"] = (0, 0)
|
||||
element.segments.append(
|
||||
SegmentText(
|
||||
(0, 0),
|
||||
text,
|
||||
rotation=rotation,
|
||||
align=align,
|
||||
fontsize=fontsize,
|
||||
font=FONT_NAME,
|
||||
color=color,
|
||||
)
|
||||
)
|
||||
drawing.add(element)
|
||||
|
||||
|
||||
def add_circle_symbol(
|
||||
drawing,
|
||||
center,
|
||||
*,
|
||||
radius=0.42,
|
||||
text=None,
|
||||
fontsize=16,
|
||||
horizontal_line=False,
|
||||
):
|
||||
element = elm.Element().at(center).anchor("center").hold()
|
||||
element.anchors["center"] = (0, 0)
|
||||
element.segments.append(SegmentCircle((0, 0), radius))
|
||||
if horizontal_line:
|
||||
element.segments.append(Segment([(-radius, 0), (radius, 0)]))
|
||||
if text:
|
||||
element.segments.append(
|
||||
SegmentText((0, 0), text, fontsize=fontsize, font=FONT_NAME)
|
||||
)
|
||||
drawing.add(element)
|
||||
|
||||
def draw_circuit(save_path=DEFAULT_OUTPUT):
|
||||
save_path = Path(save_path)
|
||||
save_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
with schemdraw.Drawing(show=False) as d:
|
||||
d.config(
|
||||
unit=1.0,
|
||||
fontsize=18,
|
||||
font=FONT_NAME,
|
||||
lw=2.0,
|
||||
margin=0.2,
|
||||
bgcolor=BG_COLOR,
|
||||
)
|
||||
|
||||
# 总线节点
|
||||
top_y = 5.8
|
||||
bottom_y = 1.4
|
||||
left_bus_x = 3.0
|
||||
meter_x = 6.45
|
||||
ammeter_x = 8.05
|
||||
load_x = 10.2
|
||||
circle_r = 0.48
|
||||
|
||||
# 左侧戴维南等效支路
|
||||
branch_x = 2.1
|
||||
source_top_y = 4.95
|
||||
source_bottom_y = 3.75
|
||||
resistor_top_y = 3.05
|
||||
resistor_bottom_y = 1.95
|
||||
|
||||
d.add(elm.Line().at((left_bus_x, top_y)).to((branch_x, top_y)).hold())
|
||||
source_center_y = (source_top_y + source_bottom_y) / 2
|
||||
d.add(elm.Line().at((branch_x, top_y)).down(top_y - (source_center_y + circle_r)).hold())
|
||||
add_circle_symbol(d, (branch_x, source_center_y), radius=circle_r, horizontal_line=True)
|
||||
d.add(elm.Line().at((branch_x, source_center_y - circle_r)).down((source_center_y - circle_r) - resistor_top_y).hold())
|
||||
d.add(elm.ResistorIEC().at((branch_x, resistor_top_y)).to((branch_x, resistor_bottom_y)).hold())
|
||||
d.add(elm.Line().at((branch_x, resistor_bottom_y)).down(resistor_bottom_y - bottom_y).hold())
|
||||
d.add(elm.Line().at((branch_x, bottom_y)).to((left_bus_x, bottom_y)).hold())
|
||||
|
||||
# 中间电压表和右侧负载支路
|
||||
d.add(elm.Line().at((left_bus_x, top_y)).right((ammeter_x - circle_r) - left_bus_x).hold())
|
||||
d.add(elm.Line().at((left_bus_x, bottom_y)).right(load_x - left_bus_x).hold())
|
||||
|
||||
add_circle_symbol(d, (ammeter_x, top_y), radius=circle_r, text="A", fontsize=15)
|
||||
d.add(elm.Line().at((ammeter_x + circle_r, top_y)).right(load_x - (ammeter_x + circle_r)).hold())
|
||||
|
||||
d.add(elm.Line().at((meter_x, top_y)).down(top_y - (3.6 + circle_r)).hold())
|
||||
add_circle_symbol(d, (meter_x, 3.6), radius=circle_r, text="V", fontsize=15)
|
||||
d.add(elm.Line().at((meter_x, 3.6 - circle_r)).down((3.6 - circle_r) - bottom_y).hold())
|
||||
|
||||
d.add(elm.ResistorVarIEC().at((load_x, bottom_y + 0.7)).up(2.0).hold())
|
||||
|
||||
# 右侧支路收口
|
||||
d.add(elm.Line().at((load_x, top_y)).down(top_y - (bottom_y + 2.7)).hold())
|
||||
d.add(elm.Line().at((load_x, bottom_y + 0.7)).down(0.7).hold())
|
||||
|
||||
# 关键节点
|
||||
d.add(elm.Dot(radius=0.075).at((left_bus_x, top_y)).hold())
|
||||
d.add(elm.Dot(radius=0.075).at((left_bus_x, bottom_y)).hold())
|
||||
|
||||
# 标注
|
||||
add_text(d, (3.2, 4.32), r"$U_{oc}$", fontsize=21)
|
||||
add_text(d, (3.0, 2.72), r"$R_0$", fontsize=21)
|
||||
|
||||
# 负载标注
|
||||
add_text(d, (10.95, 3.02), r"$R_L$", fontsize=21)
|
||||
|
||||
d.save(str(save_path), transparent=False)
|
||||
|
||||
print(f"saved to: {save_path}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
output_path = sys.argv[1] if len(sys.argv) > 1 else DEFAULT_OUTPUT
|
||||
draw_circuit(output_path)
|
||||
@@ -0,0 +1,148 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
os.environ.setdefault("MPLCONFIGDIR", "/tmp/matplotlib")
|
||||
|
||||
import schemdraw
|
||||
import schemdraw.elements as elm
|
||||
from schemdraw.segments import Segment, SegmentCircle, SegmentText
|
||||
|
||||
FONT_NAME = "STIXGeneral"
|
||||
BG_COLOR = "white"
|
||||
DEFAULT_OUTPUT = (
|
||||
Path(__file__).resolve().parent.parent / "image" / "exp4" / "norton_equiv.svg"
|
||||
)
|
||||
|
||||
|
||||
def add_text(
|
||||
drawing,
|
||||
position,
|
||||
text,
|
||||
*,
|
||||
fontsize=18,
|
||||
rotation=0,
|
||||
align=("center", "center"),
|
||||
color="black",
|
||||
):
|
||||
element = elm.Element().at(position).anchor("center").hold()
|
||||
element.anchors["center"] = (0, 0)
|
||||
element.segments.append(
|
||||
SegmentText(
|
||||
(0, 0),
|
||||
text,
|
||||
rotation=rotation,
|
||||
align=align,
|
||||
fontsize=fontsize,
|
||||
font=FONT_NAME,
|
||||
color=color,
|
||||
)
|
||||
)
|
||||
drawing.add(element)
|
||||
|
||||
|
||||
def add_circle_outline(drawing, center, *, radius=0.48, vertical_line=False):
|
||||
element = elm.Element().at(center).anchor("center").hold()
|
||||
element.anchors["center"] = (0, 0)
|
||||
element.segments.append(SegmentCircle((0, 0), radius))
|
||||
if vertical_line:
|
||||
element.segments.append(Segment([(0, -radius), (0, radius)]))
|
||||
drawing.add(element)
|
||||
|
||||
|
||||
def draw_circuit(save_path=DEFAULT_OUTPUT):
|
||||
save_path = Path(save_path)
|
||||
save_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
with schemdraw.Drawing(show=False) as d:
|
||||
d.config(
|
||||
unit=1.0,
|
||||
fontsize=18,
|
||||
font=FONT_NAME,
|
||||
lw=2.0,
|
||||
margin=0.2,
|
||||
bgcolor=BG_COLOR,
|
||||
)
|
||||
|
||||
top_y = 5.8
|
||||
bottom_y = 1.4
|
||||
|
||||
source_x = 2.0
|
||||
resistor_x = 3.45
|
||||
node_x = 4.35
|
||||
meter_x = 6.15
|
||||
ammeter_x = 7.95
|
||||
load_x = 10.1
|
||||
circle_r = 0.48
|
||||
|
||||
source_center_y = 3.6
|
||||
resistor_top_y = 4.9
|
||||
resistor_bottom_y = 2.3
|
||||
|
||||
# 诺顿等效支路:电流源与电阻并联
|
||||
d.add(elm.Line().at((source_x, top_y)).to((node_x, top_y)).hold())
|
||||
d.add(elm.Line().at((source_x, bottom_y)).to((node_x, bottom_y)).hold())
|
||||
|
||||
d.add(
|
||||
elm.Line()
|
||||
.at((source_x, top_y))
|
||||
.down(top_y - (source_center_y + circle_r))
|
||||
.hold()
|
||||
)
|
||||
add_circle_outline(
|
||||
d,
|
||||
(source_x, source_center_y),
|
||||
radius=circle_r,
|
||||
vertical_line=True,
|
||||
)
|
||||
d.add(
|
||||
elm.Line()
|
||||
.at((source_x, source_center_y - circle_r))
|
||||
.down((source_center_y - circle_r) - bottom_y)
|
||||
.hold()
|
||||
)
|
||||
|
||||
d.add(elm.ResistorIEC().at((resistor_x, resistor_top_y)).to((resistor_x, resistor_bottom_y)).hold())
|
||||
d.add(elm.Line().at((resistor_x, top_y)).down(top_y - resistor_top_y).hold())
|
||||
d.add(elm.Line().at((resistor_x, resistor_bottom_y)).down(resistor_bottom_y - bottom_y).hold())
|
||||
|
||||
# 右侧测量与负载
|
||||
d.add(elm.Line().at((node_x, top_y)).right((ammeter_x - circle_r) - node_x).hold())
|
||||
d.add(elm.Line().at((node_x, bottom_y)).right(load_x - node_x).hold())
|
||||
|
||||
element_a = elm.Element().at((ammeter_x, top_y)).anchor("center").hold()
|
||||
element_a.anchors["center"] = (0, 0)
|
||||
element_a.segments.append(SegmentCircle((0, 0), circle_r))
|
||||
element_a.segments.append(SegmentText((0, 0), "A", fontsize=15, font=FONT_NAME))
|
||||
d.add(element_a)
|
||||
d.add(elm.Line().at((ammeter_x + circle_r, top_y)).right(load_x - (ammeter_x + circle_r)).hold())
|
||||
|
||||
d.add(elm.Line().at((meter_x, top_y)).down(top_y - (3.6 + circle_r)).hold())
|
||||
element_v = elm.Element().at((meter_x, 3.6)).anchor("center").hold()
|
||||
element_v.anchors["center"] = (0, 0)
|
||||
element_v.segments.append(SegmentCircle((0, 0), circle_r))
|
||||
element_v.segments.append(SegmentText((0, 0), "V", fontsize=15, font=FONT_NAME))
|
||||
d.add(element_v)
|
||||
d.add(elm.Line().at((meter_x, 3.6 - circle_r)).down((3.6 - circle_r) - bottom_y).hold())
|
||||
|
||||
d.add(elm.ResistorVarIEC().at((load_x, bottom_y + 0.7)).up(2.0).hold())
|
||||
d.add(elm.Line().at((load_x, top_y)).down(top_y - (bottom_y + 2.7)).hold())
|
||||
d.add(elm.Line().at((load_x, bottom_y + 0.7)).down(0.7).hold())
|
||||
|
||||
# 节点
|
||||
d.add(elm.Dot(radius=0.075).at((node_x, top_y)).hold())
|
||||
d.add(elm.Dot(radius=0.075).at((node_x, bottom_y)).hold())
|
||||
|
||||
# 标注
|
||||
add_text(d, (1.2, 3.42), r"$I_{sc}$", fontsize=21, align=("right", "center"))
|
||||
add_text(d, (4.15, 3.55), r"$R_0$", fontsize=21)
|
||||
add_text(d, (10.85, 3.02), r"$R_L$", fontsize=21)
|
||||
|
||||
d.save(str(save_path), transparent=False)
|
||||
|
||||
print(f"saved to: {save_path}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
output_path = sys.argv[1] if len(sys.argv) > 1 else DEFAULT_OUTPUT
|
||||
draw_circuit(output_path)
|
||||
@@ -0,0 +1,87 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
os.environ.setdefault("MPLCONFIGDIR", "/tmp/matplotlib")
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from matplotlib.ticker import AutoMinorLocator
|
||||
|
||||
FONT_NAME = "LXGW WenKai"
|
||||
BG_COLOR = "white"
|
||||
GRID_MAJOR = "#111111"
|
||||
GRID_MINOR = "#8a8a8a"
|
||||
LINE_COLOR = "#111111"
|
||||
POINT_COLOR = "#111111"
|
||||
|
||||
CURRENT_MA = np.array([11.30, 12.71, 13.82, 15.47, 16.66], dtype=float)
|
||||
VOLTAGE_V = np.array([11.39, 10.69, 9.97, 9.21, 8.58], dtype=float)
|
||||
|
||||
DEFAULT_OUTPUT = (
|
||||
Path(__file__).resolve().parent.parent
|
||||
/ "image"
|
||||
/ "exp4"
|
||||
/ "vi_characteristic_curve_exp4.svg"
|
||||
)
|
||||
|
||||
|
||||
def draw_curve(save_path=DEFAULT_OUTPUT):
|
||||
save_path = Path(save_path)
|
||||
save_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
plt.rcParams["font.family"] = FONT_NAME
|
||||
plt.rcParams["axes.unicode_minus"] = False
|
||||
|
||||
slope, intercept = np.polyfit(CURRENT_MA, VOLTAGE_V, 1)
|
||||
fit_x = np.linspace(CURRENT_MA.min() - 0.4, CURRENT_MA.max() + 0.4, 200)
|
||||
fit_y = slope * fit_x + intercept
|
||||
|
||||
fig, ax = plt.subplots(figsize=(8.2, 6.0), dpi=160)
|
||||
fig.patch.set_facecolor(BG_COLOR)
|
||||
ax.set_facecolor(BG_COLOR)
|
||||
|
||||
ax.plot(
|
||||
fit_x,
|
||||
fit_y,
|
||||
color=LINE_COLOR,
|
||||
linewidth=2.2,
|
||||
zorder=2,
|
||||
)
|
||||
ax.scatter(
|
||||
CURRENT_MA,
|
||||
VOLTAGE_V,
|
||||
s=60,
|
||||
color=POINT_COLOR,
|
||||
edgecolors="white",
|
||||
linewidths=0.8,
|
||||
zorder=3,
|
||||
)
|
||||
|
||||
ax.set_xlabel("端口电流 I / mA", fontsize=13)
|
||||
ax.set_ylabel("端口电压 U / V", fontsize=13)
|
||||
|
||||
ax.set_xlim(11.0, 17.1)
|
||||
ax.set_ylim(8.5, 11.5)
|
||||
ax.set_xticks(np.arange(11, 18, 1))
|
||||
ax.set_yticks(np.arange(8.5, 11.6, 0.5))
|
||||
ax.xaxis.set_minor_locator(AutoMinorLocator(2))
|
||||
ax.yaxis.set_minor_locator(AutoMinorLocator(2))
|
||||
ax.set_box_aspect(6 / 5)
|
||||
|
||||
ax.grid(True, which="major", color=GRID_MAJOR, linewidth=0.95, alpha=0.9)
|
||||
ax.grid(True, which="minor", color=GRID_MINOR, linewidth=0.55, alpha=0.8)
|
||||
|
||||
for spine in ax.spines.values():
|
||||
spine.set_linewidth(1.0)
|
||||
spine.set_color("#111111")
|
||||
|
||||
fig.tight_layout()
|
||||
fig.savefig(save_path, bbox_inches="tight")
|
||||
plt.close(fig)
|
||||
print(f"saved to: {save_path}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
output_path = sys.argv[1] if len(sys.argv) > 1 else DEFAULT_OUTPUT
|
||||
draw_curve(output_path)
|
||||
@@ -0,0 +1,90 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
os.environ.setdefault("MPLCONFIGDIR", "/tmp/matplotlib")
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from matplotlib.ticker import AutoMinorLocator
|
||||
|
||||
FONT_NAME = "LXGW WenKai"
|
||||
BG_COLOR = "white"
|
||||
GRID_MAJOR = "#111111"
|
||||
GRID_MINOR = "#8a8a8a"
|
||||
LINE_COLOR = "#111111"
|
||||
POINT_COLOR = "#111111"
|
||||
|
||||
LOAD_RESISTANCE_OHM = np.array(
|
||||
[888.43, 788.46, 625.00, 534.84, 468.16, 494.69, 439.93, 415.40],
|
||||
dtype=float,
|
||||
)
|
||||
POWER_MW = np.array(
|
||||
[130.07, 133.25, 136.90, 143.15, 142.23, 142.29, 142.22, 141.25],
|
||||
dtype=float,
|
||||
)
|
||||
|
||||
DEFAULT_OUTPUT = (
|
||||
Path(__file__).resolve().parent.parent / "image" / "exp5" / "power_load_curve.svg"
|
||||
)
|
||||
|
||||
|
||||
def draw_curve(save_path=DEFAULT_OUTPUT):
|
||||
save_path = Path(save_path)
|
||||
save_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
plt.rcParams["font.family"] = FONT_NAME
|
||||
plt.rcParams["axes.unicode_minus"] = False
|
||||
|
||||
order = np.argsort(LOAD_RESISTANCE_OHM)
|
||||
x = LOAD_RESISTANCE_OHM[order]
|
||||
y = POWER_MW[order]
|
||||
|
||||
fig, ax = plt.subplots(figsize=(8.2, 6.0), dpi=160)
|
||||
fig.patch.set_facecolor(BG_COLOR)
|
||||
ax.set_facecolor(BG_COLOR)
|
||||
|
||||
ax.plot(
|
||||
x,
|
||||
y,
|
||||
color=LINE_COLOR,
|
||||
linewidth=2.2,
|
||||
zorder=2,
|
||||
)
|
||||
ax.scatter(
|
||||
x,
|
||||
y,
|
||||
s=55,
|
||||
color=POINT_COLOR,
|
||||
edgecolors="white",
|
||||
linewidths=0.8,
|
||||
zorder=3,
|
||||
)
|
||||
|
||||
ax.set_xlabel("负载电阻 R_L / Ω", fontsize=13)
|
||||
ax.set_ylabel("负载功率 P / mW", fontsize=13)
|
||||
|
||||
ax.set_xlim(400, 900)
|
||||
ax.set_ylim(129, 144)
|
||||
ax.set_xticks(np.arange(400, 901, 100))
|
||||
ax.set_yticks(np.arange(130, 145, 2))
|
||||
ax.xaxis.set_minor_locator(AutoMinorLocator(2))
|
||||
ax.yaxis.set_minor_locator(AutoMinorLocator(2))
|
||||
ax.set_box_aspect(6 / 5)
|
||||
|
||||
ax.grid(True, which="major", color=GRID_MAJOR, linewidth=0.95, alpha=0.9)
|
||||
ax.grid(True, which="minor", color=GRID_MINOR, linewidth=0.55, alpha=0.8)
|
||||
|
||||
for spine in ax.spines.values():
|
||||
spine.set_linewidth(1.0)
|
||||
spine.set_color("#111111")
|
||||
|
||||
fig.tight_layout()
|
||||
fig.savefig(save_path, bbox_inches="tight")
|
||||
plt.close(fig)
|
||||
print(f"saved to: {save_path}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
output_path = sys.argv[1] if len(sys.argv) > 1 else DEFAULT_OUTPUT
|
||||
draw_curve(output_path)
|
||||
Reference in New Issue
Block a user