import os os.environ.setdefault("MPLCONFIGDIR", "/tmp/matplotlib") import schemdraw import schemdraw.elements as elm from schemdraw.segments import SegmentText FONT_NAME = "LXGW WenKai" OUTPUT_FILE = "terminal_voltage_diagram.svg" def add_text( drawing, position, text, *, rotation=0, align=("center", "center"), fontsize=18, ): 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) with schemdraw.Drawing(show=False) as d: d.config( unit=1.0, fontsize=18, font=FONT_NAME, lw=2.0, margin=0.18, bgcolor="white", ) # ===== 几何参数 ===== left_x = 1.5 top_y = 6.3 bottom_y = 2.1 node_x = 6.1 term_x = 8.45 # 电池位置 battery_x = left_x battery_bottom_y = 3.55 battery_len = 1.55 # 电阻尺寸控制 top_res_start_x = 3.0 top_res_len = 2.2 vertical_res_len = 2.25 # 关键点 top_node = (node_x, top_y) bottom_node = (node_x, bottom_y) a_pos = (term_x, top_y) b_pos = (term_x, bottom_y) top_battery_end_y = battery_bottom_y + battery_len # ===== 左支路 + 电池 ===== # 下导线到电池 d.add( elm.Line() .at((battery_x, bottom_y)) .up(battery_bottom_y - bottom_y) .hold() ) # 电池 d.add( elm.BatteryCell() .at((battery_x, battery_bottom_y)) .up(battery_len) .hold() ) # 电池上端到顶端导线 d.add( elm.Line() .at((battery_x, top_battery_end_y)) .up(top_y - top_battery_end_y) .hold() ) # ===== 上支路 ===== d.add(elm.Line().at((battery_x, top_y)).right(top_res_start_x - battery_x).hold()) d.add(elm.ResistorIEC().at((top_res_start_x, top_y)).right(top_res_len).hold()) d.add( elm.Line() .at((top_res_start_x + top_res_len, top_y)) .right(node_x - (top_res_start_x + top_res_len)) .hold() ) # 上节点 d.add(elm.Dot(radius=0.085).at(top_node).hold()) # a 端 d.add(elm.Line().at(top_node).right(term_x - node_x).hold()) d.add(elm.Dot(open=True, radius=0.105).at(a_pos).hold()) # ===== 中间竖支路 ===== d.add(elm.ResistorIEC().at(top_node).down(vertical_res_len).hold()) d.add( elm.Line() .at((node_x, top_y - vertical_res_len)) .down((top_y - vertical_res_len) - bottom_y) .hold() ) # 下节点 d.add(elm.Dot(radius=0.085).at(bottom_node).hold()) # b 端 d.add(elm.Line().at(bottom_node).right(term_x - node_x).hold()) d.add(elm.Dot(open=True, radius=0.105).at(b_pos).hold()) # ===== 下支路闭合 ===== d.add(elm.Line().at((battery_x, bottom_y)).right(node_x - battery_x).hold()) # ===== 文本标注 ===== # 9V:竖排,放在电池右侧偏中间,更贴近教材风格 add_text( d, (battery_x + 0.92, battery_bottom_y + battery_len / 2), "10V", rotation=0, fontsize=16, ) # 1kΩ:水平,置于上方电阻正下方 add_text( d, (top_res_start_x + top_res_len / 2, top_y - 0.72), "1kΩ", rotation=0, fontsize=16, ) # 2kΩ:竖排,置于竖直电阻左侧,方向要注意 add_text( d, (node_x - 0.82, top_y - vertical_res_len / 2), "2kΩ", rotation=0, fontsize=16, ) # a / b 端标注 add_text( d, (a_pos[0] + 0.42, a_pos[1] - 0.02), "a", fontsize=19, ) add_text( d, (b_pos[0] + 0.42, b_pos[1] - 0.02), "b", fontsize=19, ) d.save(OUTPUT_FILE, transparent=False)