回路図、Python で書けるのか? — 現場の電子屋が schemdraw / skidl / PySpice を本気で試した
- python
- 電子回路
- spice
- schemdraw
- ものづくり
回路図を描くの、正直だるくないですか
回路図を一枚起こすたびに、GUI を立ち上げて、部品ライブラリを探して、シンボルを並べて、配線して、番号を振って……という儀式を、私は 20 年やってきました。
ずっと思っていたことがあります。「これ、テキストで書けたら git で差分が取れるのに」。回路図のレビューって、結局は「どこが変わったか」を目で追う作業です。それがコードだったら diff 一発なのに、と。
最近、Python で回路を書けるという話をいくつか見かけました。日本語の情報は驚くほど薄い。なら自分で全部動かして、現場の電子屋の目で「実用に耐えるか」を確かめよう、と思って週末の朝に手を動かしました。3 つとも目的が違う別物でした。
「回路を Python で」は、実は 3 種類の別作業
ここを混同している記事が多いのですが、整理するとこうです。
| やりたいこと | ライブラリ | 出てくるもの |
|---|---|---|
| 図を描く(人に見せる) | schemdraw |
教科書みたいな回路図 PNG/SVG |
| ネットリストを組む(回路を構造として持つ) | skidl |
ネットリスト / KiCad 連携 |
| シミュレーションする(動かして確かめる) | PySpice |
SPICE 解析(要 ngspice) |
「回路を Python で書く」と一言で言っても、ドキュメント目的・設計データ目的・検証目的でまったく道具が変わる。ここを分けずに語ると話が噛み合いません。3 つとも WSL + venv に入れて、実際に動かしました(schemdraw 0.22 / skidl 2.2.3 / PySpice 1.5)。
20 年、ネットリストの差分を目で追ってきた話
私はハードウェア寄りの開発現場に長くいました。回路図とネットリストに費やした時間は、たぶん数え切れません。
手描き、ドロー系ツール、専用 CAD と道具は変わっても、本質的にしんどかったのは 「変更点を人間が目で照合する」 ところでした。レビュー会で、旧ネットリストと新ネットリストを並べて、どのノードの結線が変わったかを指でなぞる。あの作業を何百回やったか分かりません。当時から「回路がプレーンテキストで、バージョン管理できて、差分がレビューできれば、この苦行の大半は消えるのに」と思っていました。
ただ、当時はそれを実現する現実的な道具がなかった。だから今回 Python の選択肢を試すのは、私にとっては 20 年越しの宿題の答え合わせでもあります。期待と疑いを半分ずつ持って動かしました。
実際に動かして分かった「使える/使えない」
schemdraw — 即戦力。文句なし
20 行ちょっとで、教科書品質の反転増幅回路が出ました。
import matplotlib
matplotlib.use("Agg")
import schemdraw
import schemdraw.elements as elm
with schemdraw.Drawing(file="inverting_amp.png", show=False) as d:
V1 = d.add(elm.SourceSin().up().label("Vin\n1kHz"))
d.add(elm.Line().right().length(1))
d.add(elm.Resistor().right().label("Rin 10k"))
opamp = d.add(elm.Opamp(leads=True).anchor("in1"))
d.add(elm.Line().at(opamp.in2).left().length(0.6))
d.add(elm.Ground())
d.add(elm.Line().up().at(opamp.in1).length(1.6))
d.add(elm.Resistor().right().label("Rf 100k").tox(opamp.out))
d.add(elm.Line().down().toy(opamp.out))
d.add(elm.Line().right().at(opamp.out).length(0.8).label("Vout"))
出てきた図がこれです(ゲイン −Rf/Rin = −10 の素直な反転増幅器)。

正直、これは即戦力です。記事・教材・設計メモに貼る図なら、もう手描きツールに戻る理由がない。コードなので git で差分が取れるし、パラメータを変えれば図が変わる。私が 20 年欲しかったものの一つは、これでした。注意点があるとすれば、複雑な実回路をこれで「設計」しようとすると配置の試行錯誤が地獄になること。用途はあくまでドキュメントと割り切れば最高です。
skidl — ネットリストは書ける。ただし KiCad の影がちらつく
skidl は「回路を Python で配線して、ネットリストを吐く」道具です。SPICE サブセット(skidl.pyspice)で RC ローパスを書いてみます。
from skidl.pyspice import R, C, V, gnd, generate_netlist, u_V, u_kOhm, u_uF
vs = V(ref="1", dc_value=5 @ u_V)
r1 = R(value=1 @ u_kOhm)
c1 = C(value=1 @ u_uF)
vs["p"] & r1 & c1 & gnd # vin --[R]-- vout --[C]-- gnd
vs["n"] & gnd # 出力 vout は R と C の接続点(下のネットリストの N_2)
print(generate_netlist())
実際に出たネットリストがこれです。
.title
V1 N_1 0 DC 5V
R1 N_1 N_2 1kOhm
C1 N_2 0 1uF
& 演算子で結線が書けるのは気持ちいい。回路をプログラムとして組み立てられるので、「抵抗値を振って 100 通りのバリエーションを自動生成」みたいなパラメトリックな使い方が刺さります。
ただし現場目線の注意点。素の skidl を import した瞬間、こういう警告がぞろぞろ出ます。
WARNING: KICAD9_SYMBOL_DIR environment variable is missing ...
WARNING: fp-lib-table file was not found. Component footprints are not available.
skidl の本来の主な使いどころは KiCad 連携(シンボル→フットプリント→基板)です。そこを使いこなすには結局 KiCad の世界を抱えることになる。「Python だけで完結」と思って入ると、この影につまずきます。SPICE サブセットでネットリスト生成までなら KiCad なしで完結するので、用途を絞れば実用です。
PySpice — 強力。でも「ngspice の壁」は正直に書いておく
PySpice は回路を Python オブジェクトとして定義します。ネットリスト生成まではあっさり動きました。
from PySpice.Spice.Netlist import Circuit
from PySpice.Unit import u_V, u_kOhm, u_uF
circuit = Circuit("RC low-pass filter")
circuit.V("input", "vin", circuit.gnd, 1 @ u_V)
circuit.R(1, "vin", "vout", 1 @ u_kOhm)
circuit.C(1, "vout", circuit.gnd, 1 @ u_uF)
print(str(circuit))
.title RC low-pass filter
Vinput vin 0 1V
R1 vin vout 1kOhm
C1 vout 0 1uF
ここまでは気持ちいい。ところが、いざシミュレーション(AC 解析)を走らせるとこうなります。
OSError: cannot load library 'libngspice.so': libngspice.so:
cannot open shared object file: No such file or directory.
これが現場の壁です。 PySpice は「ライブラリ」であって「シミュレータ」ではない。実体の計算は ngspice という別物(システムの共有ライブラリ)が必要で、pip install だけでは完結しません。私の今回の環境は管理者権限がなく ngspice をシステムに入れられなかったので、シミュレーション実行はここで止まりました。
これを「動かなかった」とだけ書く記事が多いのですが、現場の判断としては逆です。ネットリスト生成と検証ロジックは Python 側で完全に書けて、計算エンジンだけ差し替え可能、という設計だと分かったのが収穫でした。しかも PySpice の解析結果は NumPy 配列で返る設計なので、ngspice さえ通れば測定データを matplotlib や統計処理へそのまま流せる——一気に本気の解析環境になる。次回、そこを通します。
現場の電子屋としての結論(使い分け表)
| 道具 | 一言 | 使うなら |
|---|---|---|
| schemdraw | 図がコードになる。即戦力 | 記事 / 教材 / 設計メモの回路図 |
| skidl | 回路を構造として書ける | パラメトリック生成、ネットリスト再利用 |
| PySpice | 本気の解析。ただし ngspice 必須 | 腰を据えた回路シミュレーション |
罠は 2 つ。skidl の KiCad 依存と、PySpice の ngspice 依存。どちらも「Python だけで完結する」という幻想を持って入ると足を取られます。逆に、目的を 1 つに絞れば 3 つとも実用でした。
結論 — 回路が「テキスト」になる意味
20 年越しの宿題の答え合わせとしては、合格点です。回路図はもう手描きに戻らなくていい(schemdraw)。回路の構造はコードで持てる(skidl)。検証も Python の世界に引き込める(PySpice、ただし ngspice 同伴=別途必須)。
そして一番の収穫は別のところにありました。回路がテキストとコードになると、AI と回路設計を会話できる。実はこの記事のサンプルコードは、AI 伴走(Claude Code)で書いています。「反転増幅器を schemdraw で」と頼めば叩き台が出て、私は設計判断に集中できる。回路がコードになった瞬間、レビューも差分も自動生成も AI も、全部こちら側に来る。20 年前に欲しかったのは、たぶんこれです。
次回は、この lab-circuit-python に ngspice を通して、PySpice で実際に Bode 線図を出すところまでやります。最終的には STM32 や FPGA と同じターミナルで観測できる統合ラボ(Atelier Lab)に育てていく予定です。コードは MIT で公開します。
この記事は Zenn に初出したものを加筆・補足したものです ── Zenn の元記事を見る