# Placing the middle of a predefined picture at a certain node

I am trying to create the following reaction network cycle.

Here's my output so far.

My MWE is

\documentclass[11pt]{standalone}
\renewcommand*{\familydefault}{\sfdefault}
\usepackage{sfmath}
\usepackage{tikz}
\usetikzlibrary{decorations,arrows.meta,positioning,quotes}
\usepackage{color}
\usepackage[version=4]{mhchem}
\usepackage{chemfig}
\renewcommand*\printatom[1]{\small\ensuremath{\mathsf{#1}}}
\setatomsep{2em}
\setdoublesep{.6ex}
\setangleincrement{60}
\newcommand{\clap}[1]% #1 = multiline text to be centered in zero width field
{\bgroup
\sbox0{\begin{tabular}{@{}c@{}}#1\end{tabular}}%
\hspace{-0.5\wd0}\usebox0\hspace{-0.5\wd0}%
\egroup}
\pgfdeclaredecoration{ddbond}{initial}{
\state{initial}[width=5pt]{
\pgfpathlineto{\pgfpoint{4pt}{0pt}}
\pgfpathmoveto{\pgfpoint{2pt}{2pt}}
\pgfpathlineto{\pgfpoint{4pt}{2pt}}
\pgfpathmoveto{\pgfpoint{4pt}{0pt}}
}
\state{final}{
\pgfpathlineto{\pgfpointdecoratedpathlast}
}
}
\tikzset{lddbond/.style={decorate, decoration=ddbond}}
\tikzset{rddbond/.style={decorate, decoration={ddbond, mirror}}}
\makeatletter
\newdimen\mystartshorten
\newdimen\myendshorten
\mystartshorten0pt
\myendshorten0pt
\pgfdeclaredecoration{sdbond}{initial}{
\state{initial}[width=\pgfdecoratedremainingdistance,next state=final]
{
{
\pgftransformyshift{\CF@double@sep}
\pgfpathmoveto{\pgfqpoint{\mystartshorten}{0pt}}
{
\pgftransformxshift{\pgfdecoratedremainingdistance}
\pgfpathlineto{\pgfqpoint{-\myendshorten}{0pt}}
}
}
\pgfpathmoveto{\pgfpointorigin}
\pgfpathlineto{\pgfqpoint{\pgfdecoratedremainingdistance}{0pt}}
}
\state{final}
{}
}
\tikzset{
lsdbond/.code 2 args={%
\tikzset{decorate, decoration=sdbond}%
\pgfmathsetlength\mystartshorten{\CF@double@sep*cot((#1)/2)}%
\pgfmathsetlength\myendshorten{\CF@double@sep*cot((#2)/2}%
},
rsdbond/.code 2 args={%
\tikzset{decorate, decoration={sdbond, mirror}}%
\pgfmathsetlength\mystartshorten{\CF@double@sep*cot((#1)/2)}%
\pgfmathsetlength\myendshorten{\CF@double@sep*cot((#2)/2}%
}
}
\makeatother
\begin{document}
\begin{tikzpicture}[every node/.style={transform shape,font=\footnotesize},every path/.style={semithick},scale=1]
\tikzset{methylationup/.pic={
\node (methyl){\ce{CH3+}};
\node[right of = methyl] (macid) {\ce{H+}};
\draw[->] ([shift={(-0.1,0)}]methyl.north) to[bend left=60] node[midway,circle,fill=red,minimum size=2pt,inner sep=0] {} ([shift={(-0.1,0)}]macid.north);
}
}
\tikzset{methylationdown/.pic={
\node (macid){\ce{H+}};
\node[right of = macid] (methyl) {\ce{CH3+}};
\draw[->] ([shift={(-0.1,0)}]methyl.south) to[bend left=60] node[midway,circle,fill=red,minimum size=2pt,inner sep=0] {} ([shift={(-0.1,0)}]macid.south)  ;
}
}
\tikzset{formylationup/.pic={
\node[red] (formyl){\ce{CH2OH+}};
\node[left of= formyl,red,xshift=-5pt] (facid) {\ce{H3O+}};
\draw[->] ([shift={(-0.1,0)}]formyl.north) to[bend right=60] node[midway,circle,fill=red,minimum size=2pt,inner sep=0] {} ([shift={(-0.1,0)}]facid.north);
}
}
\tikzset{formylationdown/.pic={
\node[red] (formyl){\ce{CH2OH+}};
\node[right of= formyl,red,xshift=5pt] (facid) {\ce{H3O+}};
\draw[->] ([shift={(0,0)}]formyl.south) to[bend right=60] node[midway,circle,fill=red,minimum size=2pt,inner sep=0] {} ([shift={(0,0)}]facid.south);
}
}
\foreach \a in {1,2,...,17}{
\draw (\a*360/17: 3cm) node (a\a) [white]{angle \a};}
\node[align=center](po) at (a6) {polyunsaturated\\olefins};
\node (2mbu) at (a1) {\chemfig{-[1](-[2,,,,,lddbond,red])-[,,,,lddbond={+}]-[1,,,,,rddbond,red]}};
\node (butene) at (a15) {\chemfig{-[-1,,,,,rddbond,red]-[,,,,lddbond={+}]-[-1,,,,,rddbond,red]}};
\node (propene) at (a12) {\chemfig{-[,,,,rsdbond={90}{120}]-[-1]}};
%
\draw[->] (propene.east) to[bend right=20] node[midway,outer sep=0,inner sep=0,fill=blue,minimum size=3pt,circle] (ptob){} ([shift={(-0.3,0)}]butene.south);
\draw[->] ([shift={(0.5,0)}]butene.north) to[bend right=15] node[midway,outer sep=0,inner sep=0,fill=blue,minimum size=3pt,circle] (bto2mbu){} ([shift={(0.2,0)}]2mbu.south);
\draw[->] (2mbu.north) to[bend right=30] node[midway,outer sep=0,inner sep=0,fill=blue,minimum size=3pt,circle] (2mbutopo){} ([shift={(0,0.2)}]po.east);
\draw[->] (po.south) to[bend right=10] node[right,pos=0.5,text=gray,outer sep=0.5em]{$\beta$-scission} (propene.north);
\draw[->] ([shift={(0.5,0)}]po.south) to (butene.north west);
\node[yshift=-1.5cm,align=center,font=\bfseries] at (a13){olefins-based\\catalytic cycle};
%
\pic[shift={(-0.36,-0.53)},rotate=5] at (ptob) {methylationup};
\pic[shift={(-0.58,0.42)},rotate=10] at (ptob) {formylationdown};
%
\pic[rotate=85,shift={(-0.41,-0.50)}] at (bto2mbu) {methylationup};
\pic[rotate=-10] at ([shift={(-0.55,0.62)}]a3)  {methylationdown};
\node[below right of = a15,text=gray,rotate=45,yshift=-0.2cm] {\ce{C1} homologation};
%
\pic[rotate=-10] at ([shift={(0.2,-0.185)}]a2.west) {formylationup};

\pic[rotate=87] at ([shift={(-0.055,-1.01)}]a17.south west) {formylationdown};
\end{tikzpicture}
\end{document}

The problem I have is that I am trying to manually position the 'methylation' and 'formylation' pics at the middle of the paths connecting different nodes on the reaction network cycle. Is there a more elegant way of positioning a predefined picture at the middle of a path? The red and blue nodes I have placed in the middle of various paths is just to aid in proper positioning of the pics.

Also, is it possible to reduce the size of the atoms so that the diagram does not look cluttered and is more readable. I have tried using the following command \renewcommand*\printatom[1]{\small\ensuremath{\mathsf{#1}}} and replaced \small with other font sizes but it doesn't seem to change anything.

• For the pics: If you want to overlay two pics, it makes sense to define them from the point where they overlap. That way you can place them exactly at the same point. To me it looks like you defined the drawing in respect to the label, not the other way around. The manual states that while you cannot reference the pic itself, you can reference nodes inside it. However I think you can only use the nodes the draw new lines, not move the pic. Maybe you try rewriting your pic so that its origin is where it is to be intersected. – Huang_d Jun 15 '17 at 20:28
• That's a neat suggestion! I did try and implement it and instead of defining methylation and formylation up separately, I combined the two pics and made them intersect at one common point but the thing I missed was to make them intersect at the internal origin (0,0) of the pic so that when I place it somewhere else, it will give me the desired result---something which @Torbjørn T. used in his answer. – scorpionwars Jun 16 '17 at 0:06

The anchor of the pic is (0,0) in the internal coordinate system of the pic, so if you just draw the arced arrow in a way such that the midpoint of the arrow is at (0,0), then you don't have to do any shifting at all, just place the pic at the correct point. (And now, having just written this answer, I see this is precisely what Huang_d suggested. Sorry about that.)

\documentclass[11pt]{standalone}
\renewcommand*{\familydefault}{\sfdefault}
\usepackage{sfmath}
\usepackage{tikz}
\usetikzlibrary{decorations,arrows.meta,positioning,quotes}
\usepackage[version=4]{mhchem}
\usepackage{chemfig}
\renewcommand*\printatom[1]{\small\ensuremath{\mathsf{#1}}}
\setatomsep{2em}
\setdoublesep{.6ex}
\setangleincrement{60}
\newcommand{\clap}[1]% #1 = multiline text to be centered in zero width field
{\bgroup
\sbox0{\begin{tabular}{@{}c@{}}#1\end{tabular}}%
\hspace{-0.5\wd0}\usebox0\hspace{-0.5\wd0}%
\egroup}
\pgfdeclaredecoration{ddbond}{initial}{
\state{initial}[width=5pt]{
\pgfpathlineto{\pgfpoint{4pt}{0pt}}
\pgfpathmoveto{\pgfpoint{2pt}{2pt}}
\pgfpathlineto{\pgfpoint{4pt}{2pt}}
\pgfpathmoveto{\pgfpoint{4pt}{0pt}}
}
\state{final}{
\pgfpathlineto{\pgfpointdecoratedpathlast}
}
}
\tikzset{lddbond/.style={decorate, decoration=ddbond}}
\tikzset{rddbond/.style={decorate, decoration={ddbond, mirror}}}
\makeatletter
\newdimen\mystartshorten
\newdimen\myendshorten
\mystartshorten0pt
\myendshorten0pt
\pgfdeclaredecoration{sdbond}{initial}{
\state{initial}[width=\pgfdecoratedremainingdistance,next state=final]
{
{
\pgftransformyshift{\CF@double@sep}
\pgfpathmoveto{\pgfqpoint{\mystartshorten}{0pt}}
{
\pgftransformxshift{\pgfdecoratedremainingdistance}
\pgfpathlineto{\pgfqpoint{-\myendshorten}{0pt}}
}
}
\pgfpathmoveto{\pgfpointorigin}
\pgfpathlineto{\pgfqpoint{\pgfdecoratedremainingdistance}{0pt}}
}
\state{final}
{}
}
\tikzset{
lsdbond/.code 2 args={%
\tikzset{decorate, decoration=sdbond}%
\pgfmathsetlength\mystartshorten{\CF@double@sep*cot((#1)/2)}%
\pgfmathsetlength\myendshorten{\CF@double@sep*cot((#2)/2}%
},
rsdbond/.code 2 args={%
\tikzset{decorate, decoration={sdbond, mirror}}%
\pgfmathsetlength\mystartshorten{\CF@double@sep*cot((#1)/2)}%
\pgfmathsetlength\myendshorten{\CF@double@sep*cot((#2)/2}%
}
}
\makeatother
\begin{document}
\begin{tikzpicture}[every node/.style={transform shape,font=\footnotesize},every path/.style={semithick},scale=1]
\tikzset{methylationup/.pic={
\draw[->] (0.6,0.4)
node[above=-1pt](methyl){\ce{CH3+}}
to[out=260,in=0] (0,0) to[out=180,in=-80] (-0.6,0.4)
node[above=-1pt](macid) {\ce{H+}};
},
methylationdown/.pic={
\draw[->] (0.6,-0.4)
node[below=-1pt](methyl){\ce{CH3+}}
to[out=100,in=0] (0,0) to[out=180,in=80] (-0.6,-0.4)
node[below=-1pt](macid) {\ce{H+}};
},
formylationup/.pic={
\draw[->] (0.6,0.4)
node[above=-1pt,red](methyl){\ce{CH2OH+}}
to[out=260,in=0] (0,0) to[out=180,in=-80] (-0.6,0.4)
node[above=-1pt,red](macid) {\ce{H3O+}};
},
formylationdown/.pic={
\draw[->] (0.6,-0.4)
node[below=-1pt,red](methyl){\ce{CH2OH+}}
to[out=100,in=0] (0,0) to[out=180,in=80] (-0.6,-0.4)
node[below=-1pt,red](macid) {\ce{H3O+}};
},
}

\foreach \a in {1,2,...,17}{
\draw (\a*360/17: 3cm) node (a\a) [white]{angle \a};}
\node[align=center](po) at (a6) {polyunsaturated\\olefins};
\node (2mbu) at (a1) {\chemfig{-[1](-[2,,,,,lddbond,red])-[,,,,lddbond={+}]-[1,,,,,rddbond,red]}};
\node (butene) at (a15) {\chemfig{-[-1,,,,,rddbond,red]-[,,,,lddbond={+}]-[-1,,,,,rddbond,red]}};
\node (propene) at (a12) {\chemfig{-[,,,,rsdbond={90}{120}]-[-1]}};
%
\draw[->] (propene.east) to[bend right=20] node[midway,outer sep=0,inner sep=0,fill=blue,minimum size=3pt,circle] (ptob){} ([shift={(-0.3,0)}]butene.south);
\draw[->] ([shift={(0.5,0)}]butene.north) to[bend right=15] node[midway,outer sep=0,inner sep=0,fill=blue,minimum size=3pt,circle] (bto2mbu){} ([shift={(0.2,0)}]2mbu.south);
\draw[->] (2mbu.north) to[bend right=30] node[midway,outer sep=0,inner sep=0,fill=blue,minimum size=3pt,circle] (2mbutopo){} ([shift={(0,0.2)}]po.east);
\draw[->] (po.south) to[bend right=10] node[right,pos=0.5,text=gray,outer sep=0.5em]{$\beta$-scission} (propene.north);
\draw[->] ([shift={(0.5,0)}]po.south) to (butene.north west);
\node[yshift=-1.5cm,align=center,font=\bfseries] at (a13){olefins-based\\catalytic cycle};
%
\pic at (ptob) {methylationup};
\pic at (ptob) {formylationdown};
%
\pic[rotate=85] at (bto2mbu) {formylationup};
\pic[rotate=90] at (bto2mbu)  {methylationdown};

\node[below right of = a15,text=gray,rotate=45,yshift=-0.2cm] {\ce{C1} homologation};
%
\pic[rotate=-10] at (2mbutopo) {methylationup};
\pic[rotate=-10] at (2mbutopo) {formylationdown};
\end{tikzpicture}
\end{document}
• This is very useful to know and something I should have noticed but thanks for pointing out the role of internal origin as the anchor of the pic placement elsewhere. – scorpionwars Jun 16 '17 at 0:08