電気回路(circuitikz)

circuitikz は、2007 年にひとりの大学教員が抱えた「演習問題と試験を作る」という現場の問題から生まれた LaTeX パッケージです。当時ミラノ工科大学の研究助手だった Massimo Redaelli が、授業で配る回路図を組むための道具として書き始めました。使い方は驚くほど素直で、配線を一本のパスとして書き、その途中に to[R, l=$R_1$] と差し込めば抵抗が 1 個置かれます。ところが、このページで最も紙幅を割くのはその文法ではありません。抵抗の記号は国によって違う——ジグザグか長方形か——という事実と、circuitikz の既定値がおそらくあなたの期待とは違う、という話です。

\usepackage{circuitikz} を書くと何が読み込まれるか

\usepackage{circuitikz} の一行で TikZ が自動的に読み込まれ、さらに TikZ ライブラリの calcarrows.metabendingfpu が付いてきます。つまり circuitikz は TikZ の代替ではなく、TikZ に 電気記号の語彙 を足したものです。線や座標の考え方そのものは TikZ のページに譲るとして、ここで押さえておくべきは「circuitikz のコマンドは、結局ぜんぶ TikZ のコマンドである」という一点です。pdfLaTeX・LuaLaTeX・XeLaTeX ならそのまま動き、pLaTeX・upLaTeX のように DVI を経由するときだけ、TikZ と同じくクラスオプションでドライバ(通常 dvipdfmx)を指定します。

document.tex
\documentclass{article}   % one schematic only: \documentclass[border=3pt]{standalone}
\usepackage{circuitikz}
\begin{document}
\begin{circuitikz}
  \draw (0,0) to[R, l=$R_1$] (2,0);
\end{circuitikz}
\end{document}

「TikZ と同じである」はここでは比喩ではありません。circuitikz.sty の中で circuitikz 環境は文字どおり一行、\newenvironment{circuitikz}{\begin{tikzpicture}}{\end{tikzpicture}} と定義されています。中身は空っぽの別名なのです。だから \tikz \draw (0,0) to[R=$R_1$] (2,0); のように tikzpicture 側で書いても同じ絵が出ます。そしてこの事実は、実務でちゃんと噛みついてきます——TikZ の \tikzexternalize(各図を PDF にキャッシュする仕組み)は「すべての図は \end{tikzpicture} で終わること」を前提にしているため、circuitikz 環境を使っているとコンパイルが ! Emergency stop. で止まります。マニュアルの回答は身も蓋もなく、「circuitikz を全部 tikzpicture に置き換えなさい、実質同じものだから」。回路図を 1 枚だけ画像として書き出したいなら standalone クラスが手軽です。

to[R, l=$R_1$] の読み方——配線の途中に部品を落とす

circuitikz の全体像は、この一つのイディオムでほぼ説明がつきます。TikZ のパス操作 to の角括弧に部品キーを書くと、2 点を結ぶ配線の 途中にその部品が 1 個 挿入されます。\draw (0,0) to[R, l=$R_1$] (2,0); は「(0,0) から (2,0) へ、抵抗 R₁ を経由して進め」と読みます。l= はラベルのキーですが、to[R=$R_1$] と書いても同じで、これは to[R, l=$R_1$] の略記です。二つの書き方を見比べて混乱する人は多いのですが、まったく同じものです。長い形のほうが後で i=v= を足しやすいので、慣れたら to[R, l=…] を既定にすると楽になります。

latex
\begin{circuitikz}
  \draw (0,0) to[R, l=$R_1$] (2,0)   % long form
              to[C=$C_1$] (2,-2)     % shorthand for the same thing
              to[short, -*] (0,-2);  % bare wire, connection dot at the end
\end{circuitikz}

出来上がるのはコの字型の配線です。部品を置かずに導線だけを引きたいところには to[short] を使います——これは「何もない二端子部品」で、配線を to の連鎖として書き続けられるようにするための道具です。末尾の -* は TikZ の矢尻記法の応用で、パスの終点に接続点(黒丸)を打ちます。両端に打つなら *-*。座標は TikZ そのままなので、絶対座標 (2,0)(既定の単位はセンチメートル)でも、相対座標 ++(2,0)(現在位置から右に 2 cm)でも構いません。配線を直角に折るときは (a -| b)——a の x 座標と b の y 座標が交わる点——や、パス演算子 -| が効きます。部品の向きはパスの進行方向に自動で合うので、縦に引けば記号も縦になります。

部品キーを打ち間違えたときのエラーは、初見だと circuitikz と結びつかない形で出ます。たとえば to[resistorX] と書くと ! Package pgfkeys Error: I do not know the key '/tikz/resistorX' and I am going to ignore it.。部品キーの正体は TikZ のキーなので、未知のキーとして pgfkeys が文句を言うわけです。エラーメッセージの中に自分が打ったキー名がそのまま入っているので、そこを手がかりに綴りを確認します。

二端子部品の部品キー——R C L D から電源まで

to[…] に置けるのは端子を 2 つもつ部品、すなわち バイポール(bipole) です。部品キーは頭文字を取った短いもの(抵抗 R、コンデンサ C、インダクタ L、ダイオード D)が中心で、電源のように種類が多いものには vsourceisource のような綴り出し形の別名も用意されています。短い形は打鍵が速く、長い形はコードを読み返したときに親切です——チームで書くなら綴り出し形に寄せておくと後で困りません。

部品キー部品書き方
R抵抗to[R, l=$R_1$]
Cコンデンサto[C, l=$C_1$]
Lインダクタ(コイル)to[L, l=$L_1$]
Dダイオード。leD(LED)、zD(ツェナー)なども同系統to[D]
V / vsource汎用の電圧源to[V, l=$U_q$]
I / isource汎用の電流源to[I, l=$I_0$]
sV正弦波電圧源(交流)to[sV, l=$v_s$]
battery1 / battery電池(単セル/複数セル)to[battery1]
short / openただの導線/開放(両端の間に何もない)to[short]
closing switch / opening switchスイッチ。閉じる向きと開く向きで記号が異なるto[closing switch]

電源だけは少し考えて選ぶ価値があります。V は丸の中に記号が入る汎用の電圧源、sV は正弦波が入った交流電源、battery1 は「長短の 2 本線」という電池固有の記号です。直流電源に丸を使うか電池記号を使うかは分野の慣習の問題なので、周囲の教科書に合わせるのが無難です。スイッチが closing switchopening switch に分かれているのも同じ理由で、記号は「いま開いているか閉じているか」ではなく「どちらへ動く種類のスイッチか」を表しています。

americaneuropean——抵抗はジグザグか長方形か

抵抗は、米国式ではジグザグ、IEC(ヨーロッパ式)では中身の空いた長方形で描きます。同じ部品、同じ回路、違う絵です。circuitikz はこの違いを パッケージオプション として表に出していて、\usepackage[american]{circuitikz}\usepackage[european]{circuitikz} で系統ごと切り替わります——抵抗だけでなく、インダクタ、論理ゲート、電圧・電流の矢印まで一括で。読者が読み慣れた記号でないと回路図は読みづらくなるので、これは書き始める前に一度決めておくべき設定です。

ここからが本題です。何も指定しないときの既定値は、どちらか一方ではなく混合です。 circuitikz.sty の既定オプション一覧を読むと、抵抗と論理ゲートは米国式(americanresistorsamericanports)、電圧と電流の矢印はヨーロッパ式(europeanvoltageseuropeancurrents)、インダクタは第三の流儀 cuteinductors になっています。結果として、素で書いた回路図は アメリカの読者にもヨーロッパの読者にも「自分の教科書とは少し違う」 ものになります。しかも違いは目立ちます——電圧をヨーロッパ式で描くと部品をまたぐ曲がった矢印、米国式にすると両端に置かれた + の記号で、見た目がまったく別物です。

設定する場所は 3 か所あり、ここに小さな罠があります。パッケージオプションはスペースなし\usepackage[europeanresistors]{circuitikz})、環境オプションと \ctikzset はスペースあり\begin{circuitikz}[european resistors])で、名前が微妙に違うのです。粒度を細かく指定したいときは \ctikzset{resistor=european}\ctikzset{voltage=american} のようにキーで書けます。文書全体を一つの流儀に統一するならプリアンブルで [european][american] を一度、図ごとに例外を作るなら環境オプション、という使い分けが素直です。

document.tex
% whole document in IEC style (note: no space in package options)
\usepackage[european]{circuitikz}

% ... but this one figure keeps the American zigzag
\begin{circuitikz}[american resistors]
  \draw (0,0) to[R, l=$R_1$] (2,0);
\end{circuitikz}

ラベル l=、電圧 v=、電流 i=、注記 a=

部品に文字を添えるキーは 4 つで、役割がきれいに分かれています。l= は名前(R₁ など)、a= は注記で、名前の反対側にもう一段の情報(実際の値など)を置きます。v= は部品にかかる電圧、i= は流れる電流を、それぞれ向きを示す矢印つきで描きます。どのキーも末尾に下線を付けると反対側・逆向きになり、l_= はラベルを線の反対側へ、i_=v_= は電流・電圧の矢印を逆向きにします。上付き記号の l^= も同様です。配線が縦か横かで「上/下」の意味が変わるので、ll_ は最後に見た目で決めるものだと思っておくと気が楽です。

latex
\begin{circuitikz}
  \draw (0,0) to[V, l=$U_q$] (0,2)
              to[short] (2,2)
              to[R, l=$R_1$, a=$4.7\,\mathrm{k}\Omega$, i=$i_1$, v=$u_1$] (2,0)
              to[short] (0,0);
\end{circuitikz}

出来上がるのは一巡の閉回路です。左辺に電圧源 Uq、上辺と下辺は to[short] のただの導線、右辺の抵抗には名前 R₁ と実際の値 4.7 kΩ が線の両側に分かれて付き、さらに電流 i₁ と電圧 u₁ の矢印が添えられます。ここで前節が効いてきます——v=$u_1$ がどう描かれるかは、いま american voltageseuropean voltages かで決まります。何も指定しなければ既定はヨーロッパ式なので、部品をまたぐ曲がった矢印になります。

値を単位付きで書きたいなら、\usepackage[siunitx]{circuitikz} と読み込みます。すると l=5<\ohm>a=3<\micro\farad> のような 数値<\単位> という circuitikz 独自の記法が使えるようになり、siunitx が「5 Ω」「3 µF」と正しく組んでくれます。数値と単位のあいだの空きや、µ の字形の面倒を自分で見なくて済むので、値を並べる回路図では最初から入れておく価値があります。

トランジスタ・オペアンプ・接地は \node[…] で置く

端子が 3 つ以上ある部品は to[…] には入りません。to は「2 点のあいだ」を埋める操作なので、3 本目の足を出す場所がないからです。トランジスタ、オペアンプ、接地といった部品は TikZ の ノード として \node[部品名] (名前) at (座標) {}; の形で置きます。中身が空でも 波括弧 {} は必須 で、これを忘れるのは初学者の定番の詰まりどころです。置いたノードは端子ごとに アンカー を持ち、(oa.out) のように ノード名.端子名 で参照して配線をつなぎます。

  • 接地\node[ground] at (0,0) {};。電源レールには vcc(正側)と vee(負側)の記号があります。
  • MOSFET\node[nmos] (q1) {};\node[pmos] {};。バイポーラトランジスタは npnpnp。端子は q1.gateq1.drainq1.source などで参照します。
  • オペアンプ\node[op amp] (oa) {};。端子は oa.+(非反転入力)、oa.-(反転入力)、oa.out(出力)。
  • パスの途中に置く — 座標のすぐ後ろに node[ground]{} と書けば、配線を切らずにノードを差し込めます。
latex
\begin{circuitikz}
  \draw (0,0) node[op amp] (oa) {};
  \draw (oa.-) to[R, l=$R_f$] ++(0,2) -| (oa.out);  % feedback around the amp
  \draw (oa.+) to[short] ++(-1,0) node[ground] {};
\end{circuitikz}

これがアンカーの真価が出る場面です。オペアンプを 1 個置いたら、反転入力 oa.- から上へ帰還抵抗 R_f を引き、-| で右へ折って出力 oa.out に落とす——これだけで帰還ループが閉じます。座標を一つも数えていないことに注目してください。オペアンプの寸法が変わっても、アンカーで書いてある限り配線はついてきます。非反転入力 oa.+ は左へ少し引いて接地しています。

\ctikzset で図全体をそろえる、TikZ と混ぜる

回路図全体の見た目をまとめて決めるのが \ctikzset{…} です。TikZ の \tikzset に対応する circuitikz 側の設定命令で、プリアンブルにも図の途中にも書けます。実務でいちばん効くのは \ctikzset{bipoles/length=1cm}——すべての二端子部品の長さをそろえる指定です。既定のままだと部品ごとに描画長がわずかに違い、配線の間隔が不揃いに見えることがあるので、長さを固定するだけで図が急に整います。前節の resistor=americanvoltage=european も同じ \ctikzset の一族です。

最後に、circuitikz は TikZ の上に乗っているという最初の話に戻ります。座標計算の calc、相対配置の positioning、ラベル用のただの \node、色・線種・スタイル定義——TikZ でできることはそのまま使えます。複雑な回路ほど、レイアウトは TikZ の流儀で組み立て、部品だけ circuitikz に任せる という分担がうまくいきます。図が増えてコンパイルが重くなったら TikZ と同じく external ライブラリでキャッシュできますが、そのときは前述のとおり circuitikz 環境を tikzpicture に書き換えるのを忘れずに。