How to manually define the center of a node in Tikz?

I would like to ask the following question.

How can I define the center of a node in Tikz?

In the following example, I would like to define the respective bullets to be the respective centers (such that it aligns graphically). Is there an easy way to do that? I would like to avoid defining $3$ or $4$ instead of one.

At the moment, they are not aligned and it looks like this:

%& /home/bernhard/.config/TikzEdtWForms/TikzEdtWForms/0.2.1.0/temp_header
\begin{document}
\usetikzlibrary{patterns,shapes,decorations.pathmorphing,decorations.pathreplacing,calc,arrows}
\usetikzlibrary{arrows}
\begin{tikzpicture}
\node (v2) at (-2,20) {$uvw=\bullet^{2}=xyz$};
\node (v6) at (2,20) {$\bullet^{6}$};
\node (v7) at (0,24) {$abc=\bullet^7=defgh$};
\draw [-open triangle 45] (v2) edge node[above] {}  (v7);
\draw [-open triangle 45] (v7) edge node[above] {}  (v6);
\draw [-open triangle 45] (v2) edge node[above] {}  (v6);
\end{tikzpicture}
\end{document}


This yields the following picture.

I would like to make the bullets of the respective vertices $2$, $6$ and $7$ being the centers of the / aligned with the red crosses (which are not part of the code, but drawn nevertheless).

Thank you very much for the help.

• why not put the bullets first as the corners of the triangle -- give each bullet a name -- then define nodes on left and right side of the bullets -- these nodes on the left and right will contain the additional text – js bibra May 16 at 16:50

It isn't that difficult to put the nodes on the desired spots, one only has to measure what comes before and after the bullet, and introduce the corresponding xshift. The bigger challenge is to draw the arrows in such a way that they point towards the bullets but stop at the node boundaries. This is a brute-force solution using intersections. (In a perfect world one could generalize the asymmetrical rectangle from the cd library in such a way that it also allows for horizontal shifts of the center. However, the shape defined there stores the shifts of the center in pgf keys, which apply to all of the shapes in a given scope. To use it here, one would have to allow for individual shifts of single nodes, and then do proper book keeping.) The intersections are computed in a pic to make things somewhat more user-friendly. The nodes are created via the center bullet style, which takes two arguments, the stuff before and after the bullet in the center.

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{arrows,intersections,shapes.misc}
\makeatletter
\tikzset{autosave background path/.code={
\ifcsname tikz@fig@name\endcsname
\tikzset{name path=bp\tikz@fig@name}%
\fi}}
\makeatother
\begin{document}
\begin{tikzpicture}[center bullet/.code 2 args={%
\pgfmathsetmacro{\mydw}{0.5*(width("${}\vphantom{\bullet}#2$")-width("$#1{}$"))}%
\tikzset{xshift=\mydw pt,yshift=0.5ex,text depth=0.25ex,text height=1em,
autosave background path,
execute at begin node={$#1\bullet#2$}}},
pics/connect/.style n args={4}{code={%
\path[name path=tmp] (#2) -- (#4);
\tikzset{name intersections={of=tmp and bp#1,by=tmp1},
name intersections={of=tmp and bp#3,by=tmp2}}
\draw[pic actions] (tmp1) -- (tmp2);
}}]
\path (-2,20) coordinate (v2) (2,20) coordinate (v6) (0,24) coordinate (v7);
\node[center bullet={uvw=}{^{2}=xyz}] (n2) at (v2) {};%{$uvw=\bullet^{2}=xyz$};
\node[center bullet={}{^{6}}] (n6) at (v6){};% {$\bullet^{6}$};
\node[center bullet={abc=}{^7=defgh}] (n7) at (v7){};% {$abc=\bullet^7=defgh$};
\path[-open triangle 45] pic{connect={n2}{v2}{n7}{v7}}
pic{connect={n2}{v2}{n6}{v6}} pic{connect={n7}{v7}{n6}{v6}};
% just for illustration that the bulltets sit at the right points
\path foreach \x in {2,6,7} {(v\x) node[red,draw,cross out]{}};
\end{tikzpicture}
\end{document}


The red crosses are only to confirm that it works. One can remove them, as well as the shapes.misc library.

• I have removed comments here. The core technical point was focussed on the behaviour of execute at begin node - the central point was that there may be issued with text inserted by this key due to where it is executed at a code level. – Joseph Wright May 17 at 9:13
• @JosephWright Thanks! I'd like to mention that there is no problem with this key in the above code, and the key is used precisely as it is described in the pgf manual. I am not saying that this key is foolproof under all circumstances, but in the above case it is one appropriate option, and I welcome constructive suggestions for alternatives, in particular when they also get added to the pgf manual. (node contents is, according to what I find, not always without issues.) – user242026 May 17 at 9:19
• Perhaps a separate question specifically about the semantics of execute at begin node (and related?) would be appropriate here? Sounds like it would be a useful supplement to the manual. – Joseph Wright May 17 at 9:26
• @JosephWright As far as I can tell this was not at all about the execute at begin node, which is used e.g. in the matrix library as \tikzset{matrix of math nodes/.style={% matrix of nodes, nodes={% execute at begin node=$,% execute at end node=$% }% }}%. It is a standard key. It was more a statement which had a very different purpose, similar in spirit to this comment. – user242026 May 17 at 15:41
\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{arrows}
\begin{document}
\begin{tikzpicture}
\node[circle,inner sep=0pt] (v2) at (-2,20) {\makebox[0pt][r]{$uvw={}$}$\bullet$\makebox[0pt][l]{$^{2}=xyz$}};
\node[circle,inner sep=0pt] (v6) at (2,20) {$\bullet$\makebox[0pt][l]{$^{6}$}};
\node[circle,inner sep=0pt] (v7) at (0,24) {\makebox[0pt][r]{$abc={}$}$\bullet$\makebox[0pt][l]{$^7=defgh$}};
\draw [-open triangle 45] (v2) edge node[above] {}  (v7);
\draw [-open triangle 45] (v7) edge node[above] {}  (v6);
\draw [-open triangle 45] (v2) edge node[above] {}  (v6);
\end{tikzpicture}
\end{document}


• For those who do not know: this is written by the maintainer of TikZ/pgf. – user242026 May 17 at 8:02
• Maybe you want to look at what happens when you put \draw (current bounding box.south west) rectangle (current bounding box.north east); before \end{tikzpicture}, and look at the vertical position of the lower two bullets. Please please do not write comments under other answers, especially if they are not to the point. And you may also look up execute at begin node and how it is used in the pgfmanual. – user242026 May 17 at 9:16

Since you propose to manually position the center of the node, I propose the following solution: The node with the text is positioned by trial and error with respect to the node where the arrows point.

There might be a solution with tikzmark but I didn't get there quickly.

PS: your code is not compilable!

\documentclass[border=10pt,tikz]{article}
\usepackage{tikz}
\usetikzlibrary{tikzmark}

\usetikzlibrary{patterns,shapes,decorations.pathmorphing,decorations.pathreplacing,calc,arrows}
\usetikzlibrary{arrows,positioning}
\begin{document}

\begin{tikzpicture}

\node[circle,draw,inner sep=0](v2) at (-2,20){};
\node[circle,draw,inner sep=0](v6) at (2,20){};
\node[circle,draw,inner sep=0](v7) at (0,24){};
\draw [-open triangle 45] (v2) edge node[above] {}  (v7);
\draw [-open triangle 45] (v7) edge node[above] {}  (v6);
\draw [-open triangle 45] (v2) edge node[above] {}  (v6);

\node (v2) at ($(v2.center)+(0.5mm,0)$) {$uvw=\bullet^{2}=xyz$};
\node (v6) at ($(v6.center)+(1mm,0)$)  {$\bullet^{6}$};
\node (v7) at ($(v7.center)+(3.2mm,0)$)  {$abc=\bullet^7=defgh$};

\end{tikzpicture}

\end{document}


Yet another version, using labels. Unfortunately it still requires some manual nudging.

\documentclass{amsart}

\usepackage{tikz}
\usetikzlibrary{arrows,calc,positioning}

\begin{document}

\begin{tikzpicture}
\node[label={[shift={(.25,-.02)}]left:$uvw={}$},label={[shift={(-.25,0)}]right:$^2=xyz$}]
(v2) at (-2,20) {$\bullet$};
\node[label={[shift={(-.25,0)}]right:$^6$}]
(v6) at (2,20) {$\bullet$};
\node[label={[shift={(.25,.01)}]left:$abc={}$},label={[shift={(-.25,0)}]right:$^7=defgh$}]
(v7) at (0,24) {$\bullet$};
\draw [-open triangle 45] (v2) -- (v7);
\draw [-open triangle 45] (v7) -- (v6);
\draw [-open triangle 45] ($(v2)+(4em,0)$) -- (v6);
\end{tikzpicture}

\end{document}