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)