# Tikz set label position using pgfkey

I'm trying to define a tikz style for nodes that (among other things) includes a label. Since the label position relative to the main node needs to be manually controllable I want to set the position in some way, but the position should be an "optional property". Does any tikz magician out there have a nice solution, or can at least explain why my attempts are failing?

Things I've tried so far and why they aren't really a nice solution:

1) Using a two argument style

mystyle/.style 2 args={label=#2:#1},
mystyle/.default={Defalut text}{60}


With this I can create a style which give me the output I want, but using it is very inconvenient. For the position to be optional I need to either add a second set or braces, or tripple (!) enclose the text argument. The default position does not work either, since the defaults are only used if none of the arguments are supplied.

2) Using a second key to store a value

mypos/.store in=\mypos,
mypos=60,
mystyle/.style={label=\mypos:#1}


It seems like the \mypos macro is not expanded correctly, since setting the mypos key in the node options will not change the position. Setting the key manually with \pgfkeys does however work. This method works if used for other things, like inner sep, but not for labels...

3) Using the label position key

mypos/.forward to={/tikz/label position},
mypos=60,
mystyle/.style={label=#1}


Again, setting the position in the node options does not change anything.

Full MWE:

\documentclass{minimal}
\usepackage{tikz}

\begin{document}

Using \verb+/.style 2 args+

\begin{tikzpicture}[
mystyle/.style 2 args={label=#2:#1},
mystyle/.default={Defalut text}{60}
]

\node [mystyle={{{Label A}}}] {Text A};  % This really needs tripple braces...
\node at (2,0) [mystyle={Label B}{}] {Text B};
\node at (5,0) [mystyle={Label C}{120}] {Text C};
\node at (7,0) [mystyle] {Text D};
\end{tikzpicture}

Using \verb+/.store in+

\begin{tikzpicture}[
mypos/.store in=\mypos,
mypos=60,
mystyle/.style={label=\mypos:#1}
]
\node [mystyle=Label A] {Text A};
\node at (2,0) [mystyle=Label B, mypos=120] {Text B};
\pgfkeys{tikz/mypos=120}
\node at (6,0) [mystyle=Label C, mypos=180] {Text C};
\end{tikzpicture}

Using \verb+label position+

\begin{tikzpicture}[
mypos/.forward to={/tikz/label position},
mypos=60,
mystyle/.style={label=#1}
]
\node [mystyle=Label A] {Text A};
\node at (2,0) [mystyle=Label B, mypos=120] {Text B};
\node at (4,0) [mystyle=Label C, label position=120] {Text C};
\end{tikzpicture}
\end{document}


Does this help? The complete label expression (with options, position and text) is considered as a unique parameter. This way you can decide what you need in each node.

\documentclass[border=2mm,tikz]{standalone}
\usetikzlibrary{positioning}

\begin{document}
\begin{tikzpicture}[
mystyle/.style={
draw=red,
label={#1}  %<-- Don't delete these braces
}
]

\node[draw, label=30:A] (A) {AAAA};

\node[mystyle=0:B, right=of A] (B) {BBBB};

\node[mystyle={[draw=blue, minimum size=1cm]C}, right=of B] (C) {CCCC};
\end{tikzpicture}
\end{document}


• That definitely helps. Still interested to know why my attempts didn't work though. – Carl Sep 23 '19 at 7:38