5

I am trying to redefine the plus and minus signs in CircuiTikz voltage labels to have a user defined thickness. So far I have a solution that works, but it has a few quirks.

The main document:

\documentclass{standalone}

\usepackage{pgfplots}

\usepackage[american]{circuitikz}

\usepgfplotslibrary{external}
\tikzexternalize

\newcommand{\thickplusvm}{
    \begin{tikzpicture}[x=0.85ex, y=0.85ex, scale=0.5]
        \draw[line cap=round, line width=.95pt] (0,-1) -- (0,1);
        \draw[line cap=round, line width=.95pt] (1,0) -- (-1,0);
    \end{tikzpicture}
}

\newcommand{\thickminusvm}{
    \begin{tikzpicture}[x=0.85ex, y=0.85ex, scale=0.5]
        \draw[line cap=round, line width=.95pt, opacity=0] (0,-1) -- (0,1);
        \draw[line cap=round, line width=.95pt] (1,0) -- (-1,0);
    \end{tikzpicture}
}

\input{./voltagemarkers.tex}

\begin{document}

\tikzset{external/remake next}
\tikzsetnextfilename{MWE}
\begin{tikzpicture}
    \draw (0,0) to[L,v=$v$] ++(2,0);
    \draw (3,0) to[R, v^=$v$] ++(0,-2);
    \draw[very thin, color=red]
        (0,-0.2) -- ++(2,0)
        (3,0) -| ++(0.2015,-0.263)  ++(-.25,0) -- ++(.5,0)
        (3,-2) -| ++(0.265,0.263)  ++(-.25,0) -- ++(.5,0)
        (0.265,0.25) -- ++(0,-1)
        (1.8,0.25) -- ++(0,-1)
    ;
    \end{tikzpicture}
\end{document}

and voltagemarkers.tex:

\def\pgf@circ@drawvoltagegeneric{
    \pgfextra{
            \edef\pgf@temp{/tikz/circuitikz/bipoles/\pgfkeysvalueof{/tikz/circuitikz/bipole/kind}/voltage/straight label distance}
            \pgfkeysifdefined{\pgf@temp}
                {
                    \edef\partheight{\ctikzvalof{bipoles/\pgfkeysvalueof{/tikz/circuitikz/bipole/kind}/voltage/straight label distance}}
                    \edef\tmpdistfromline{(\partheight\pgf@circ@Rlen)}
                }
                {
                \pgfkeysifdefined{/tikz/circuitikz/bipoles/voltage/straight label distance}
                    {
                        \edef\partheight{\ctikzvalof{bipoles/voltage/straight label distance}}
                        \edef\tmpdistfromline{(\partheight\pgf@circ@Rlen)}
                    }
                    {%calculate default value from part height
                        \edef\pgf@temp{/tikz/circuitikz/bipoles/\pgfkeysvalueof{/tikz/circuitikz/bipole/kind}/height}
                        \pgfkeysifdefined{\pgf@temp}
                        {
                            \edef\partheight{0.5*\ctikzvalof{bipoles/\pgfkeysvalueof{/tikz/circuitikz/bipole/kind}/height}}
                            \edef\tmpdistfromline{(\partheight\pgf@circ@Rlen+0.2\pgf@circ@Rlen)}
                        }
                        {
                            \edef\tmpdistfromline{(.5\pgf@circ@Rlen)} %fallback to fixed value
                        }
                    }
                }
        \ifnum \ctikzvalof{mirror value}=-1
            \ifpgf@circuit@bipole@inverted
                \ifpgf@circuit@bipole@voltage@straight
                    \def\distfromline{\tmpdistfromline}
                \else
                    \def\distfromline{\ctikzvalof{voltage/distance from line}\pgf@circ@Rlen}
                \fi
            \else
                \ifpgf@circuit@bipole@voltage@straight
                    \def\distfromline{-\tmpdistfromline}
                \else
                    \def\distfromline{-\ctikzvalof{voltage/distance from line}\pgf@circ@Rlen}
                \fi
            \fi
        \else
            \ifpgf@circuit@bipole@inverted
                \ifpgf@circuit@bipole@voltage@straight
                    \def\distfromline{-\tmpdistfromline}
                \else
                    \def\distfromline{-\ctikzvalof{voltage/distance from line}\pgf@circ@Rlen}
                \fi
            \else
                \ifpgf@circuit@bipole@voltage@straight
                    \def\distfromline{\tmpdistfromline}
                \else
                    \def\distfromline{\ctikzvalof{voltage/distance from line}\pgf@circ@Rlen}
                \fi
            \fi
        \fi
        \ifpgf@circuit@bipole@voltage@below
            \def\pgf@circ@voltage@angle{90}
        \else
            \def\pgf@circ@voltage@angle{-90}
        \fi
        \edef\pgf@temp{/tikz/circuitikz/bipoles/\pgfkeysvalueof{/tikz/circuitikz/bipole/kind}/voltage/distance from node}
        \pgfkeysifdefined{\pgf@temp}
            { \edef\distacefromnode{\ctikzvalof{bipoles/\pgfkeysvalueof{/tikz/circuitikz/bipole/kind}/voltage/distance from node}} }
            { \edef\distacefromnode{\ctikzvalof{voltage/distance from node}} }
        \edef\pgf@temp{/tikz/circuitikz/bipoles/\pgfkeysvalueof{/tikz/circuitikz/bipole/kind}/voltage/bump b}
        \pgfkeysifdefined{\pgf@temp}
            { \edef\bumpb{\ctikzvalof{bipoles/\pgfkeysvalueof{/tikz/circuitikz/bipole/kind}/voltage/bump b}} }
            { \edef\bumpb{\ctikzvalof{voltage/bump b}} }
    }
    % %\pgf@circ@Rlen/16 is equal to the length of the currarrow
    coordinate (pgfcirc@midtmp) at ($(\tikztostart) ! \pgf@circ@Rlen/16 ! (anchorstartnode)$) %absolute move, minimum space is length of arrowhead
    coordinate (pgfcirc@midtmp) at ($(pgfcirc@midtmp) ! \distacefromnode ! (anchorstartnode)$)

    coordinate (pgfcirc@Vfrom) at ($(pgfcirc@midtmp) ! -\distfromline ! \pgf@circ@voltage@angle:(anchorstartnode)$)
    coordinate (pgfcirc@midtmp) at ($(\tikztotarget) ! \pgf@circ@Rlen/16 ! (anchorendnode)$)%absolute move, minimum space is length of arrowhead
    coordinate (pgfcirc@midtmp) at ($(pgfcirc@midtmp) ! \distacefromnode ! (anchorendnode)$)

    coordinate (pgfcirc@Vto) at ($(pgfcirc@midtmp) ! \distfromline ! \pgf@circ@voltage@angle : (anchorendnode)$)

    \ifpgf@circuit@bipole@voltage@below
        coordinate (pgfcirc@Vcont1) at ($(\ctikzvalof{bipole/name}.center) ! \bumpb ! (\ctikzvalof{bipole/name}.-110)$)
        coordinate (pgfcirc@Vcont2) at ($(\ctikzvalof{bipole/name}.center) ! \bumpb ! (\ctikzvalof{bipole/name}.-70)$)
    \else
        coordinate (pgfcirc@Vcont1) at ($(\ctikzvalof{bipole/name}.center) ! \bumpb ! (\ctikzvalof{bipole/name}.110)$)
        coordinate (pgfcirc@Vcont2) at ($(\ctikzvalof{bipole/name}.center) ! \bumpb ! (\ctikzvalof{bipole/name}.70)$)
    \fi

    \ifpgf@circuit@europeanvoltage
        \ifpgf@circuit@bipole@voltage@straight
            \ifpgf@circuit@bipole@voltage@backward
                (pgfcirc@Vto) --(pgfcirc@Vfrom) node[currarrow, sloped,  allow upside down, pos=1,anchor=tip] {}
            \else
                (pgfcirc@Vfrom) --(pgfcirc@Vto) node[currarrow, sloped,  allow upside down, pos=1,anchor=tip] {}
            \fi
        \else
            \ifpgf@circuit@bipole@voltage@backward
                (pgfcirc@Vto) .. controls (pgfcirc@Vcont2)  and (pgfcirc@Vcont1) ..
                    node[currarrow, sloped,  allow upside down, pos=1] {}
                (pgfcirc@Vfrom)
            \else
                (pgfcirc@Vfrom) .. controls (pgfcirc@Vcont1)  and (pgfcirc@Vcont2) ..
                    node[currarrow, sloped,  allow upside down, pos=1] {}
                (pgfcirc@Vto)
            \fi
        \fi
    \else
        \ifpgf@circuit@bipole@voltage@backward
            \ifpgf@circ@oldvoltagedirection
                (pgfcirc@Vfrom) node[inner sep=0, anchor=\pgf@circ@bipole@voltage@label@anchor]{\thickplusvm}
                (pgfcirc@Vto) node[inner sep=0, anchor=\pgf@circ@bipole@voltage@label@anchor]{\thickminusvm}
            \else
                (pgfcirc@Vfrom) node[inner sep=0, anchor=\pgf@circ@bipole@voltage@label@anchor]{\thickminusvm}
                (pgfcirc@Vto) node[inner sep=0, anchor=\pgf@circ@bipole@voltage@label@anchor]{\thickplusvm}
            \fi
        \else
            \ifpgf@circ@oldvoltagedirection
                (pgfcirc@Vfrom) node[inner sep=0, anchor=\pgf@circ@bipole@voltage@label@anchor]{\thickminusvm}
                (pgfcirc@Vto) node[inner sep=0, anchor=\pgf@circ@bipole@voltage@label@anchor]{\thickplusvm}
            \else
                (pgfcirc@Vfrom) node[inner sep=0, anchor=\pgf@circ@bipole@voltage@label@anchor]{\thickplusvm}
                (pgfcirc@Vto) node[inner sep=0, anchor=\pgf@circ@bipole@voltage@label@anchor]{\thickminusvm}
            \fi
        \fi
    \fi
}

voltagemarkers.tex is the same as the definition in the source code with $+$ and $-$ replaced by my macros from the main file.

There are two problems that I have with this solution. The first is that it requires externalization, and specifically it requires \usepgfplotslibrary{external} Either not externalizing or using \usetikzlibrary{external} instead both result in the new definitions being ignored. This is not necessarily a problem, but I would at least like to understand why this specific externalization is required.

The second problem is that I need to create an invisible vertical line in the minus symbol to keep the plus and minus inline. I tried using the text height and text depth tikz options described in the manual to keep them the same size, but this resulted in the minus sign being higher than the plus sign in the horizontal components. I also tried using the baseline option, but with it the vertical markers became misaligned.

Is there a better way to do this that does not require the phantom line in the minus sign or externalization? I know this is delving into the depths of CircuitTikz, but I would certainly appreciate any help you would be able to provide.

Edit:

Attempting to use saveboxes to prevent problems with nesting tikzpicture environments based on comments from @marmot.

\newsavebox{\thickplusbox}
\newsavebox{\thickminusbox}

\savebox\thickplusbox{
    \begin{tikzpicture}[x=0.85ex, y=0.85ex, scale=0.5]
        \draw[line cap=round, line width=.95pt] (0,-1) -- (0,1);
        \draw[line cap=round, line width=.95pt] (1,0) -- (-1,0);
    \end{tikzpicture}
}

\savebox\thickminusbox{
    \begin{tikzpicture}[x=0.85ex, y=0.85ex, scale=0.5]
        \draw[line cap=round, line width=.95pt, opacity=0] (0,-1) -- (0,1);
        \draw[line cap=round, line width=.95pt] (1,0) -- (-1,0);
    \end{tikzpicture}
}

Adding the above code to the preamble results in the following error message:

! Undefined control sequence.
\pgf@externalend ... \pgfexternal@originalshipout 
                                                  \box 0 \gdef \pgfexternal@...
l.36 }

If I move the savebox definitions into the document (Which I'd like to avoid if I can) and set \tikzset{/tikz/external/optimize=false} It will compile, but it moves the location of the symbols.

Original:

With SaveBoxes:

Any suggestions on how to keep the correct position while still using the saveboxes and keep the definitions in the preamble?

Edit 2:

Response to Marmot's answer:

Thanks again for your help with this Marmot! I've tried your answer and I think it's also experiencing the weird behavior that I mentioned in the original question regarding externalization.

This is the result of your code with no modifications (the same as you got):

However, this result is identical to the default CircuiTikz behavior:

If I switch the \usetikzlibrary{external} line to \usepgfplotslibrary{external} and include the pgfplots package I get the following error:

! Undefined control sequence.
<argument> \markwidth 

If we change the \markwidth to .95pt we get the following result:

So we can see now that the thickness is now set by the custom pgfplotmark, but the spacing is off. I'm still very confused as to why the defaults are used when using \usetikzlibrary{external}, but \usepgfplotslibrary{external} allows the customization to take effect.

  • I am actually wondering if there is a third problem: you are nesting TikZ pictures when you put the plus and minus signs in nodes. I'd recommend to try to avoid that, e.g. by using a scope in which you draw the respective symbols. Alternatively, you could put them into \saveboxes which, to the best of my knowledge, also avoids the potential problems that arise from nesting TikZ pictures. – user121799 Jun 11 '18 at 22:04
  • Hi @marmot! Do you mean replacing the tikzpicture environments in the command definitions with scope environments? I tried doing that and I got LaTeX Error: \begin{tikzpicture} on input line 30 ended by \end{scope}. – kgoodrick Jun 11 '18 at 22:27
  • You cannot put a scope in a node and you have to replace both the beginning and end, i.e. \begin{scope}.... \end{scope}. As I said, working with \saveboxes may also be a way to do it. – user121799 Jun 11 '18 at 22:32
  • Hi @marmot, I just updated the question with my attempt at saveboxes. I'll take a look at your answer after dinner, thanks again for your help! – kgoodrick Jun 12 '18 at 0:26
2

I forgot so say "Welcome to TeX.SE!" so I'm doing it here. This is certainly not a final answer since it does not fully address the question of placing the plus and minus. I am actually not too surprised that externalize does not work when you are nesting tikzpictures. So I replaced these nested pictures by something that I would consider more appropriate: plot marks. And miraculously tikz externalize works then (but I am not 100% sure that was the reason. The code with the plotmarks is

\documentclass[border=3.14mm]{standalone}
\usepackage[american]{circuitikz}

\usetikzlibrary{external}
\tikzexternalize

\pgfdeclareplotmark{fancyplus}
{%
  \pgfsetroundcap
  \pgfsetlinewidth{\markwidth}
  \pgfpathmoveto{\pgfqpoint{0pt}{-\pgfplotmarksize}}
  \pgfpathlineto{\pgfqpoint{0pt}{\pgfplotmarksize}}
  \pgfpathmoveto{\pgfqpoint{-\pgfplotmarksize}{0pt}}
  \pgfpathlineto{\pgfqpoint{\pgfplotmarksize}{0pt}}
  \pgfusepathqstroke
}

\pgfdeclareplotmark{fancyminus}
{%
  \pgfsetroundcap
  \pgfsetlinewidth{\markwidth}
  \pgfpathmoveto{\pgfqpoint{-\pgfplotmarksize}{0pt}}
  \pgfpathlineto{\pgfqpoint{\pgfplotmarksize}{0pt}}
  \pgfusepathqstroke
}




\input{./voltagemarkers.tex}

\begin{document}

\tikzset{external/remake next}
\tikzsetnextfilename{MWE}
\begin{tikzpicture}
    \draw (0,0) to[L,v=$v$] ++(2,0);
    \draw (3,0) to[R, v^=$v$] ++(0,-2);
    \draw[thin, color=red]
    (0,-0.2) -- ++(2,0)
    ;
    \draw[thin, color=red]
        (3,0) -| ++(0.25,-0.25)
        (3,-2) -| ++(0.25,0.25)
    ;
    \end{tikzpicture}
\end{document}

and they are used in

\def\pgf@circ@drawvoltagegeneric{
    \pgfextra{
            \edef\pgf@temp{/tikz/circuitikz/bipoles/\pgfkeysvalueof{/tikz/circuitikz/bipole/kind}/voltage/straight label distance}
            \pgfkeysifdefined{\pgf@temp}
                {
                    \edef\partheight{\ctikzvalof{bipoles/\pgfkeysvalueof{/tikz/circuitikz/bipole/kind}/voltage/straight label distance}}
                    \edef\tmpdistfromline{(\partheight\pgf@circ@Rlen)}
                }
                {
                \pgfkeysifdefined{/tikz/circuitikz/bipoles/voltage/straight label distance}
                    {
                        \edef\partheight{\ctikzvalof{bipoles/voltage/straight label distance}}
                        \edef\tmpdistfromline{(\partheight\pgf@circ@Rlen)}
                    }
                    {%calculate default value from part height
                        \edef\pgf@temp{/tikz/circuitikz/bipoles/\pgfkeysvalueof{/tikz/circuitikz/bipole/kind}/height}
                        \pgfkeysifdefined{\pgf@temp}
                        {
                            \edef\partheight{0.5*\ctikzvalof{bipoles/\pgfkeysvalueof{/tikz/circuitikz/bipole/kind}/height}}
                            \edef\tmpdistfromline{(\partheight\pgf@circ@Rlen+0.2\pgf@circ@Rlen)}
                        }
                        {
                            \edef\tmpdistfromline{(.5\pgf@circ@Rlen)} %fallback to fixed value
                        }
                    }
                }
        \ifnum \ctikzvalof{mirror value}=-1
            \ifpgf@circuit@bipole@inverted
                \ifpgf@circuit@bipole@voltage@straight
                    \def\distfromline{\tmpdistfromline}
                \else
                    \def\distfromline{\ctikzvalof{voltage/distance from line}\pgf@circ@Rlen}
                \fi
            \else
                \ifpgf@circuit@bipole@voltage@straight
                    \def\distfromline{-\tmpdistfromline}
                \else
                    \def\distfromline{-\ctikzvalof{voltage/distance from line}\pgf@circ@Rlen}
                \fi
            \fi
        \else
            \ifpgf@circuit@bipole@inverted
                \ifpgf@circuit@bipole@voltage@straight
                    \def\distfromline{-\tmpdistfromline}
                \else
                    \def\distfromline{-\ctikzvalof{voltage/distance from line}\pgf@circ@Rlen}
                \fi
            \else
                \ifpgf@circuit@bipole@voltage@straight
                    \def\distfromline{\tmpdistfromline}
                \else
                    \def\distfromline{\ctikzvalof{voltage/distance from line}\pgf@circ@Rlen}
                \fi
            \fi
        \fi
        \ifpgf@circuit@bipole@voltage@below
            \def\pgf@circ@voltage@angle{90}
        \else
            \def\pgf@circ@voltage@angle{-90}
        \fi
        \edef\pgf@temp{/tikz/circuitikz/bipoles/\pgfkeysvalueof{/tikz/circuitikz/bipole/kind}/voltage/distance from node}
        \pgfkeysifdefined{\pgf@temp}
            { \edef\distacefromnode{\ctikzvalof{bipoles/\pgfkeysvalueof{/tikz/circuitikz/bipole/kind}/voltage/distance from node}} }
            { \edef\distacefromnode{\ctikzvalof{voltage/distance from node}} }
        \edef\pgf@temp{/tikz/circuitikz/bipoles/\pgfkeysvalueof{/tikz/circuitikz/bipole/kind}/voltage/bump b}
        \pgfkeysifdefined{\pgf@temp}
            { \edef\bumpb{\ctikzvalof{bipoles/\pgfkeysvalueof{/tikz/circuitikz/bipole/kind}/voltage/bump b}} }
            { \edef\bumpb{\ctikzvalof{voltage/bump b}} }
    }
    % %\pgf@circ@Rlen/16 is equal to the length of the currarrow
    coordinate (pgfcirc@midtmp) at ($(\tikztostart) ! \pgf@circ@Rlen/16 ! (anchorstartnode)$) %absolute move, minimum space is length of arrowhead
    coordinate (pgfcirc@midtmp) at ($(pgfcirc@midtmp) ! \distacefromnode ! (anchorstartnode)$)

    coordinate (pgfcirc@Vfrom) at ($(pgfcirc@midtmp) ! -\distfromline ! \pgf@circ@voltage@angle:(anchorstartnode)$)
    coordinate (pgfcirc@midtmp) at ($(\tikztotarget) ! \pgf@circ@Rlen/16 ! (anchorendnode)$)%absolute move, minimum space is length of arrowhead
    coordinate (pgfcirc@midtmp) at ($(pgfcirc@midtmp) ! \distacefromnode ! (anchorendnode)$)

    coordinate (pgfcirc@Vto) at ($(pgfcirc@midtmp) ! \distfromline ! \pgf@circ@voltage@angle : (anchorendnode)$)

    \ifpgf@circuit@bipole@voltage@below
        coordinate (pgfcirc@Vcont1) at ($(\ctikzvalof{bipole/name}.center) ! \bumpb ! (\ctikzvalof{bipole/name}.-110)$)
        coordinate (pgfcirc@Vcont2) at ($(\ctikzvalof{bipole/name}.center) ! \bumpb ! (\ctikzvalof{bipole/name}.-70)$)
    \else
        coordinate (pgfcirc@Vcont1) at ($(\ctikzvalof{bipole/name}.center) ! \bumpb ! (\ctikzvalof{bipole/name}.110)$)
        coordinate (pgfcirc@Vcont2) at ($(\ctikzvalof{bipole/name}.center) ! \bumpb ! (\ctikzvalof{bipole/name}.70)$)
    \fi

    \ifpgf@circuit@europeanvoltage
        \ifpgf@circuit@bipole@voltage@straight
            \ifpgf@circuit@bipole@voltage@backward
                (pgfcirc@Vto) --(pgfcirc@Vfrom) node[currarrow, sloped,  allow upside down, pos=1,anchor=tip] {}
            \else
                (pgfcirc@Vfrom) --(pgfcirc@Vto) node[currarrow, sloped,  allow upside down, pos=1,anchor=tip] {}
            \fi
        \else
            \ifpgf@circuit@bipole@voltage@backward
                (pgfcirc@Vto) .. controls (pgfcirc@Vcont2)  and (pgfcirc@Vcont1) ..
                    node[currarrow, sloped,  allow upside down, pos=1] {}
                (pgfcirc@Vfrom)
            \else
                (pgfcirc@Vfrom) .. controls (pgfcirc@Vcont1)  and (pgfcirc@Vcont2) ..
                    node[currarrow, sloped,  allow upside down, pos=1] {}
                (pgfcirc@Vto)
            \fi
        \fi
    \else
        \ifpgf@circuit@bipole@voltage@backward
            \ifpgf@circ@oldvoltagedirection
                (pgfcirc@Vfrom) node[inner sep=0, anchor=\pgf@circ@bipole@voltage@label@anchor]{\pgfuseplotmark{fancyplus}}
                (pgfcirc@Vto) node[inner sep=0, anchor=\pgf@circ@bipole@voltage@label@anchor]{\pgfuseplotmark{fancyminus}}
            \else
                (pgfcirc@Vfrom) node[inner sep=0, anchor=\pgf@circ@bipole@voltage@label@anchor]{\pgfuseplotmark{fancyminus}}
                (pgfcirc@Vto) node[inner sep=0, anchor=\pgf@circ@bipole@voltage@label@anchor]{\pgfuseplotmark{fancyplus}}
            \fi
        \else
            \ifpgf@circ@oldvoltagedirection
                (pgfcirc@Vfrom) node[inner sep=0, anchor=\pgf@circ@bipole@voltage@label@anchor]{\pgfuseplotmark{fancyminus}}
                (pgfcirc@Vto) node[inner sep=0, anchor=\pgf@circ@bipole@voltage@label@anchor]{\pgfuseplotmark{fancyplus}}
            \else
                (pgfcirc@Vfrom) node[inner sep=0, anchor=\pgf@circ@bipole@voltage@label@anchor]{\pgfuseplotmark{fancyplus}}
                (pgfcirc@Vto) node[inner sep=0, anchor=\pgf@circ@bipole@voltage@label@anchor]{\pgfuseplotmark{fancyminus}}
            \fi
        \fi
    \fi
}

This yields

enter image description here

Probably you won't be 100% happy with the placement of the minus signs, that's why I think this not a full answer. But I also made no effort in trying to understand how the coordinates for the plus and minus signs are computed, so maybe this has to be adjusted.

However, I should also mention that if I replace

\documentclass[border=3.14mm]{standalone}0

by

\documentclass[border=3.14mm,tikz]{standalone}

the thing again stops to work. I am hardly ever using externalize so I have no idea who the culprit is, perhaps it is my code or circuitikz or standalone or some interplay.

  • Hi @marmot! I've updated the question with a response to this answer. I think it's also seeing the weird externalization problem that I mentioned originally. – kgoodrick Jun 12 '18 at 15:44
  • @kgoodrick You could change \pgfsetlinewidth{\markwidth} to \pgfsetlinewidth{0.95pt}, i.e. the same hard-coded value as in your proposal to avoid one of the problems. – user121799 Jun 12 '18 at 15:52
  • Yep, that's exactly what I did to generate the last picture (Though I do really like the idea of using a non-hard-coded thickness). It still has the weird externalization behavior and alignment though. – kgoodrick Jun 12 '18 at 16:07
  • I've just added an answer that I think fixes all the problems I had and that you brought up. Let me know if you see anything with it that could be improved. – kgoodrick Jul 5 '18 at 17:10
1

I've found an answer that I think resolves all the issues I mentioned in the original question as well as some of the concerns brought up in the comments.

Instead of using a tikzpicture environment to store the plus and minus signs, I am using the tikz pic feature. This fixes the issue with using a tikz picture inside of a node that was brought up in the comments. It also no longer requires the phantom vertical line in the minus sign to keep the two symbols inline. Though, that might be because I removed the anchor from the symbol placement.

I was also able to fix the issue with externalization by adding \makeatletter to the beginning of voltagemarkers.tex and \makeatother to the end.

This method does not place the symbols exactly where they were in the original solution, but it can be easily adjusted to taste with \ctikzset{voltage/distance from line/.initial=XXX}.

MWE

\documentclass{standalone}

\usepackage[american]{circuitikz}

\tikzset{
    thickplus/.pic={
        \draw[line cap=round, line width=.95pt, x=0.85ex, y=0.85ex, scale=0.5]
        (0,-1) -- (0,1)
        (1,0) -- (-1,0);
    }
}

\tikzset{
    thickminus/.pic={
        \draw[line cap=round, line width=.95pt, x=0.85ex, y=0.85ex, scale=0.5]
        (1,0) -- (-1,0);
    }
}

\input{./voltagemarkers.tex}

\begin{document}

\begin{tikzpicture}
    \draw (0,0) to[L,v=$v$] ++(2,0);
    \draw (3,0) to[R, v^=$v$] ++(0,-2);

    \draw[thin, color=red]
    (0,-0.2) -- ++(2,0)
    (0,-0.11) -- ++(2,0)
    ;
    \draw[thin, color=red]
        (3,0) -| ++(0.2015,-0.263)  ++(-.25,0) -- ++(.5,0)
        (3,-2) -| ++(0.265,0.263)  ++(-.25,0) -- ++(.5,0)
        (0.265,0.25) -- ++(0,-1)
        (1.8,0.25) -- ++(0,-1)
    ;
\end{tikzpicture}

\end{document}

and voltagemarkers.tex:

\makeatletter
\def\pgf@circ@drawvoltagegeneric{
    \pgfextra{
            \edef\pgf@temp{/tikz/circuitikz/bipoles/\pgfkeysvalueof{/tikz/circuitikz/bipole/kind}/voltage/straight label distance}
            \pgfkeysifdefined{\pgf@temp}
                {
                    \edef\partheight{\ctikzvalof{bipoles/\pgfkeysvalueof{/tikz/circuitikz/bipole/kind}/voltage/straight label distance}}
                    \edef\tmpdistfromline{(\partheight\pgf@circ@Rlen)}
                }
                {
                \pgfkeysifdefined{/tikz/circuitikz/bipoles/voltage/straight label distance}
                    {
                        \edef\partheight{\ctikzvalof{bipoles/voltage/straight label distance}}
                        \edef\tmpdistfromline{(\partheight\pgf@circ@Rlen)}
                    }
                    {%calculate default value from part height
                        \edef\pgf@temp{/tikz/circuitikz/bipoles/\pgfkeysvalueof{/tikz/circuitikz/bipole/kind}/height}
                        \pgfkeysifdefined{\pgf@temp}
                        {
                            \edef\partheight{0.5*\ctikzvalof{bipoles/\pgfkeysvalueof{/tikz/circuitikz/bipole/kind}/height}}
                            \edef\tmpdistfromline{(\partheight\pgf@circ@Rlen+0.2\pgf@circ@Rlen)}
                        }
                        {
                            \edef\tmpdistfromline{(.5\pgf@circ@Rlen)} %fallback to fixed value
                        }
                    }
                }
        \ifnum \ctikzvalof{mirror value}=-1
            \ifpgf@circuit@bipole@inverted
                \ifpgf@circuit@bipole@voltage@straight
                    \def\distfromline{\tmpdistfromline}
                \else
                    \def\distfromline{\ctikzvalof{voltage/distance from line}\pgf@circ@Rlen}
                \fi
            \else
                \ifpgf@circuit@bipole@voltage@straight
                    \def\distfromline{-\tmpdistfromline}
                \else
                    \def\distfromline{-\ctikzvalof{voltage/distance from line}\pgf@circ@Rlen}
                \fi
            \fi
        \else
            \ifpgf@circuit@bipole@inverted
                \ifpgf@circuit@bipole@voltage@straight
                    \def\distfromline{-\tmpdistfromline}
                \else
                    \def\distfromline{-\ctikzvalof{voltage/distance from line}\pgf@circ@Rlen}
                \fi
            \else
                \ifpgf@circuit@bipole@voltage@straight
                    \def\distfromline{\tmpdistfromline}
                \else
                    \def\distfromline{\ctikzvalof{voltage/distance from line}\pgf@circ@Rlen}
                \fi
            \fi
        \fi
        \ifpgf@circuit@bipole@voltage@below
            \def\pgf@circ@voltage@angle{90}
        \else
            \def\pgf@circ@voltage@angle{-90}
        \fi
        \edef\pgf@temp{/tikz/circuitikz/bipoles/\pgfkeysvalueof{/tikz/circuitikz/bipole/kind}/voltage/distance from node}
        \pgfkeysifdefined{\pgf@temp}
            { \edef\distacefromnode{\ctikzvalof{bipoles/\pgfkeysvalueof{/tikz/circuitikz/bipole/kind}/voltage/distance from node}} }
            { \edef\distacefromnode{\ctikzvalof{voltage/distance from node}} }
        \edef\pgf@temp{/tikz/circuitikz/bipoles/\pgfkeysvalueof{/tikz/circuitikz/bipole/kind}/voltage/bump b}
        \pgfkeysifdefined{\pgf@temp}
            { \edef\bumpb{\ctikzvalof{bipoles/\pgfkeysvalueof{/tikz/circuitikz/bipole/kind}/voltage/bump b}} }
            { \edef\bumpb{\ctikzvalof{voltage/bump b}} }
    }
    % %\pgf@circ@Rlen/16 is equal to the length of the currarrow
    coordinate (pgfcirc@midtmp) at ($(\tikztostart) ! \pgf@circ@Rlen/16 ! (anchorstartnode)$) %absolute move, minimum space is length of arrowhead
    coordinate (pgfcirc@midtmp) at ($(pgfcirc@midtmp) ! \distacefromnode ! (anchorstartnode)$)

    coordinate (pgfcirc@Vfrom) at ($(pgfcirc@midtmp) ! -\distfromline ! \pgf@circ@voltage@angle:(anchorstartnode)$)
    coordinate (pgfcirc@midtmp) at ($(\tikztotarget) ! \pgf@circ@Rlen/16 ! (anchorendnode)$)%absolute move, minimum space is length of arrowhead
    coordinate (pgfcirc@midtmp) at ($(pgfcirc@midtmp) ! \distacefromnode ! (anchorendnode)$)

    coordinate (pgfcirc@Vto) at ($(pgfcirc@midtmp) ! \distfromline ! \pgf@circ@voltage@angle : (anchorendnode)$)

    \ifpgf@circuit@bipole@voltage@below
        coordinate (pgfcirc@Vcont1) at ($(\ctikzvalof{bipole/name}.center) ! \bumpb ! (\ctikzvalof{bipole/name}.-110)$)
        coordinate (pgfcirc@Vcont2) at ($(\ctikzvalof{bipole/name}.center) ! \bumpb ! (\ctikzvalof{bipole/name}.-70)$)
    \else
        coordinate (pgfcirc@Vcont1) at ($(\ctikzvalof{bipole/name}.center) ! \bumpb ! (\ctikzvalof{bipole/name}.110)$)
        coordinate (pgfcirc@Vcont2) at ($(\ctikzvalof{bipole/name}.center) ! \bumpb ! (\ctikzvalof{bipole/name}.70)$)
    \fi

    \ifpgf@circuit@europeanvoltage
        \ifpgf@circuit@bipole@voltage@straight
            \ifpgf@circuit@bipole@voltage@backward
                (pgfcirc@Vto) --(pgfcirc@Vfrom) node[currarrow, sloped,  allow upside down, pos=1,anchor=tip] {}
            \else
                (pgfcirc@Vfrom) --(pgfcirc@Vto) node[currarrow, sloped,  allow upside down, pos=1,anchor=tip] {}
            \fi
        \else
            \ifpgf@circuit@bipole@voltage@backward
                (pgfcirc@Vto) .. controls (pgfcirc@Vcont2)  and (pgfcirc@Vcont1) ..
                    node[currarrow, sloped,  allow upside down, pos=1] {}
                (pgfcirc@Vfrom)
            \else
                (pgfcirc@Vfrom) .. controls (pgfcirc@Vcont1)  and (pgfcirc@Vcont2) ..
                    node[currarrow, sloped,  allow upside down, pos=1] {}
                (pgfcirc@Vto)
            \fi
        \fi
    \else
        \ifpgf@circuit@bipole@voltage@backward
            \ifpgf@circ@oldvoltagedirection
                (pgfcirc@Vfrom) pic[]{thickplus}
                (pgfcirc@Vto) pic[]{thickminus}
            \else
                (pgfcirc@Vto) pic[]{thickminus}
                (pgfcirc@Vfrom) pic[]{thickplus}
            \fi
        \else
            \ifpgf@circ@oldvoltagedirection
                (pgfcirc@Vto) pic[]{thickminus}
                (pgfcirc@Vfrom) pic[]{thickplus}
            \else
                (pgfcirc@Vfrom) pic[]{thickplus}
                (pgfcirc@Vto) pic[]{thickminus}
            \fi
        \fi
    \fi
}
\makeatother

Result:

After adding \ctikzset{voltage/distance from line/.initial=.1432}:

I'm not sure if there will be any ill affects from removing the anchor setting from the sign placement, but for now at least I'm happy with this result.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.