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)