3

I am drawing a figure which has many nodes and many lines connecting the nodes. I want every line connecting two nodes to start from "north" and to end to "south". So, essentially, my code is something like

\begin{tikzpicture}
 \node (a) at (0,0) {};
 \node (b) at (0,1) {};
 \draw (a.north) -- (b.south);
\end{tikzpicture}

with many nodes definitions and many draws. I want to define once and for all that all line should start from "north" and end to "south", so I tried something like

 every path/.style={parent anchor=north, child anchor=south}

but it doesn't work. The question is: is there a way to specify in the template that any line should start from "north" and end to "south" so avoiding the need to write this in every draw?

  • Why not using \draw (a) -- (b);? – percusse Nov 3 '17 at 13:11
  • You could use a loop to draw the lines, \foreach \i/\j in {a/b, c/d, e/f} {\draw (\i.north) -- (\j.south);}, is that an option? – Torbjørn T. Nov 3 '17 at 13:20
  • @percusse If the nodes aren't at the same x-coordinate, that won't work. (I assumed that's the case here, even if the example doesn't show it.) – Torbjørn T. Nov 3 '17 at 13:22
  • @percusse: I chose a bad example, my mistake: I have many nodes and they are not one on top of the other. Please read: \node (a) at (0,0) and \node (b) at (1,1) – brad Nov 3 '17 at 13:26
  • @Torbiorn: that is a nice suggestion, thank you. The only problem is that I want to add colors to some of the nodes. – brad Nov 3 '17 at 13:29
4

You can use a custom to path

\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}[ns/.style={
    to path={(\tikztostart.north) -- (\tikztotarget.south)\tikztonodes (\tikztotarget)}
}]
 \node[draw] (a) at (0,0) {};
 \node[draw] (b) at (1,1) {};
 \node[draw] (c) at (2,-1){};
 \draw (a) to [ns] (b) to[ns] (c) to[ns] (a);
\end{tikzpicture}
\end{document}

enter image description here

  • This answer is closer to my original question. All in all, in my original code was enough to substitute \draw (a.north) -- (b.south); with \draw (a.north) to (b.south); to have the style every path/.style={parent anchor=north, child anchor=south} performing what I meant. Yet, I do not understand the difference. – brad Nov 3 '17 at 14:10
  • @brad For that you should better use every to – percusse Nov 3 '17 at 14:11
4

You could use macros. I should add that using one letter macro names is a bad idea. Also, I'm surprised I didn't have to use \pgfextra.

\documentclass{standalone}
\usepackage{tikz}

\newcommand{\n}[1]{(#1.north)}
\newcommand{\s}[1]{(#1.south)}

\begin{document}

\begin{tikzpicture}
 \node (a) at (0,0) {};
 \node (b) at (0,1) {};
 \draw \n{a} -- \s{b};
\end{tikzpicture}

\end{document}
  • When the parser is not looking for something particular, say ( or [, it will expand things as it walks on the code. Otherwise you have to pause the parser with \pgfextra – percusse Nov 3 '17 at 14:09
3

You could use a loop to draw the lines. To specify different colours for the lines, you can have a third loop variable, and leave that empty where you want the default colour (black, unless you say otherwise).

output of code

\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
 \node (a) at (0,0) {};
 \node (b) at (0,1) {};
 \node (c) at (0.2,0) {};
 \node (d) at (0.2,1) {};
 \node (e) at (0.4,0) {};
 \node (f) at (0.4,1) {};

\foreach \i/\j/\clr in {
   a/b/,
   c/d/red,
   e/f/}
  \draw [\clr] (\i.north) -- (\j.south);
\end{tikzpicture}
\end{document}
  • I upvoted your answer, even if eventually I accepted the other one, because anyway this one is a nice workaround which can be useful in other occasions. – brad Nov 3 '17 at 14:13

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.