Here is start. Rather than using levels I would define a single pic
(see section 18.2 of the tikz manual), that draws one planar diagram and then you can stack them. The first argument of the pic
should give the number of dots on the bottom line and the second argument should be a comma separated list of x
/y
pairs for the strings. This way you can use:
\begin{tikzpicture}
\draw (0,0) pic{planar=[3]{1/1}};
\draw (3,0) pic{planar=[3]{1/2}};
\draw (6,0) pic{planar=[3]{1/3}};
\end{tikzpicture}
to draw the diagrams

To stack the diagrams you then put two pics on "top" of each other, so that
\begin{tikzpicture}
\draw(0,0) pic{planar=[3]{2/2}};
\draw(0,0.7) pic{planar=[3]{2/3}};
\end{tikzpicture}
produces:

Finally, here is an example with multiple strings and four dots: the code
\begin{tikzpicture}
\draw(0,0) pic{planar={4}{1/2, 3/1, 3/3}};
\end{tikzpicture}
produces (the non-planar diagram):

I haven't added a command for the labels, partly because I don't immediately see a good syntax for this and partly because when I draw such diagrams I never label the strings:)
Here is the full code:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows.meta}
\tikzset{pics/planar/.style 2 args = {
code = {
\draw[color=red] (0,0) rectangle (#1*0.3+0.3,0.7);
\foreach \dot in {1,...,#1}{ % draw the dots
\filldraw (0.3*\dot,0) circle [radius=1pt];
\filldraw (0.3*\dot,0.7) circle [radius=1pt];
}
% draw the lines
\foreach \x/\y in {#2}
\draw[->,>=stealth](0.3*\x,0) .. controls +(0,0.2) and +(0,-0.2) .. (0.3*\y,0.7);
}
}
}
\begin{document}
\begin{tikzpicture}
\draw (0,0) pic{planar={3}{1/1}};
\draw (2,0) pic{planar={3}{1/2}};
\draw (4,0) pic{planar={3}{1/3}};
\end{tikzpicture}
\begin{tikzpicture}
\draw(0,0) pic{planar={3}{2/2}};
\draw(0,0.7) pic{planar={3}{2/3}};
\end{tikzpicture}
\begin{tikzpicture}
\draw(0,0) pic{planar={4}{1/2, 3/1, 3/3}};
\end{tikzpicture}
\end{document}
As you see I have really just repackaged the code from the OP. Personally, I would replace 0.3
and 0.7
above with 0
and 1
and then rescale the whole environment as this is likely to make your life a little easier in the long run.
Edit
Here is a "fancier" \PlanarDiagram
macro that accepts a comma separated list of coma separated x
/y
-pairs to produce products of the corresponding diagrams. For example, the code
\PlanarDiagram(5){{1/2}} \quad
\PlanarDiagram{{1/2,2/2}, {2/3,3/1}} \quad
\PlanarDiagram(4){{1/2, 3/1, 3/3}, {1/1, 2/3, 3/3}}
produces the output

Notice that there is an optional argument, which is enclosed in (...)
, that gives the number of dots. This another optional argument that you can use to configure the underlying tikzpicture1
environment and the pic
. So, for example,
\PlanarDiagram[scale=0.5, draw=blue](4){{1/2, 3/1, 3/3}, {1/1, 2/3, 3/3}}
produces:

Here is the updated code:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows.meta}
\tikzset{pics/planar/.style 2 args = {
code = {
\draw[color=red] (0,0) rectangle (#1*0.3+0.3,0.7);
\foreach \dot in {1,...,#1}{ % draw the dots
\filldraw (0.3*\dot,0) circle [radius=1pt];
\filldraw (0.3*\dot,0.7) circle [radius=1pt];
}
% draw the lines
\foreach \x/\y in #2
\draw[->,>=stealth](0.3*\x,0) .. controls +(0,0.2) and +(0,-0.2) .. (0.3*\y,0.7);
}
}
}
\usepackage{xparse}
\NewDocumentCommand\PlanarDiagram{ O{} D(){3} m }{%
\begin{tikzpicture}[#1]
\foreach \diag [count=\c] in {#3} {
\draw(0,\c*0.7) pic[#1]{planar={#2}{\diag}};
}
\end{tikzpicture}%
}
\begin{document}
\PlanarDiagram(5){{1/2}} \quad
\PlanarDiagram{{1/2,2/2}, {2/3,3/1}} \quad
\PlanarDiagram(4){{1/2, 3/1, 3/3}, {1/1, 2/3, 3/3}}
\PlanarDiagram[scale=0.7, draw=blue](4){{1/2, 3/1, 3/3}, {1/1, 2/3, 3/3}}
\end{document}