0

Does exist a specific package to render string diagrams (CS' strings, not physics' strings) like the figure below?

string diagram

Alternatively, how would you create such figure? Can you provide a (very) minimal example?

6
  • 2
    Welcome. // There are several topics on this on ctan, which you can scan. However, it's probably easier and more straight forward to do it in Tikz, see tutorials in tikz.dev . Topics: ctan.org/topic/graphics , ctan.org/topic/maths , ctan.org/topic/pgf-tikz , ctan.org/topic/diagram .
    – MS-SPO
    Commented Jan 2 at 10:40
  • 1
    Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer.
    – Community Bot
    Commented Jan 2 at 11:19
  • What is your definition of string diagrams? I know the category-flavor but this seems quite different from what you have here. Tikz would allow you to draw anything, you can also create some macros to help you doing that more efficiently. You might also like tikz-cd that it made for category diagrams, or my package zx-calculus that build on tikz-cd for diagrammatic processes, but this seems quite far from what you are after. Maybe describing exactly what is a string diagram for you could help people to see what you need.
    – tobiasBora
    Commented Jan 2 at 11:25
  • 2
    arxiv.org/abs/2305.08768 download unzip there is a tikz folders with dozens of examples, but @MS-SPO answer is a good start to understand them. Read the paper to be honest and I think is a waste of life.
    – yannisl
    Commented Jan 2 at 13:44
  • 1
    @YiannisLazarides, wow, more than 374 tikz-files in the zip file ...
    – MS-SPO
    Commented Jan 2 at 13:47

1 Answer 1

6

Here's a way to do it with Tikz.

Basic ideas:

  • draw some lines
  • put some \nodes for the labels below
  • \draw some decorated paths above
  • remember relevant coordinates to support these actions
  • define /.styles as you go to both simplify code and make parameter changes in one place only
  • trying a balanced approach, which isn't too difficult to follow as a novice AND using some path-features for nicer code

result

Lines:

Let's digest the first one.

    \draw[bar] (0,0) coordinate (A) -- (1.5,0)  coordinate (B) node[a]{$a$};

Think of drawing a simple line, first in absolute coordinates:

    \draw (0,0) -- (1.5,0);

Because Tikz is about pathes, which are ended by a semicolon ;, we could add a node, while dropping the \ before the path ends. So this one puts a node with text (label) after having arrived at (1.5,0); it accepts text with some style a, i.e. in math mode $a$:

    \draw (0,0) -- (1.5,0) node[a]{$a$};

Put style information for the line infront, AND leave it to the style section at the beginning to specify in detail, what to draw here:

    \draw[bar] (0,0) -- (1.5,0) node[a]{$a$};

Finally add the \coordinate statement into the path, to remember certain locations, AND drop the \ because it's still in the same path to be drawn. There you are:

    \draw[bar] (0,0) coordinate (A) -- (1.5,0)  coordinate (B) node[a]{$a$};

The other pathes are made similar, using a mix of relative movements --++(1.5,0), absolute coordinates, and using knowledge about the minimum width of those nodes of having been defined here as 5mm. This can be done more systematically, for sure.

Labels below:

    % ~~~ labels below ~~~~~~~~~~
    \node[mth] at                (A) {$1$};
    \node[mth] at ([xshift=-2.5mm]C) {$f(i) + 1$};

This is pretty straight forward. The first line puts text $1$ at remembered position (A), using style mth, which happen to shift that text a bit downward in y-direction.

The second is very similar, besides some complication introduced by putting the node with $a$ the way I did. So one way to correct the position is to use (C) and shift it a bit backwards (half the minimum width):

([xshift=-2.5mm]C).

Overbrace:

    % ~~~ labels above ~~~~
    \draw[decorate,blue] ([ys]A) -- ([ys]B) node[alf]{$\alpha$};
    \draw[decorate,blue] ([ys]D) -- ([ys]E) node[alf]{$\alpha$};

It combines concepts from above, while using decorate, which is supplied by the tikz-library decorations.pathreplacing:

  • it draws a path above (A) to above (B)
  • replaces it by a brace
  • in blue
  • putting a node midway and a bit above for the $\alpha$.

Style-block:

 \begin{tikzpicture}[
    a/.style={anchor=west,minimum width=5mm},   % for the node containing "a"
    bar/.style={{Bar[]}-{Bar[]}},               % start- and end-tipps as Bars
    bar2/.style={-{Bar[]}},                     % only end-tipp as bar
    mth/.style={yshift=-5mm},                   % for placing the math-labels
    decoration=brace,                           % the overbrace
    alf/.style={midway,yshift=3mm},             % placing \alpha there
    ys/.style={yshift=5mm},                     % shortcut for these yshifts
 ]

At least for me this part develops as I go, e.g. like this:

  • recall the line part described above
  • put usefull style options directly for draw and node
  • are they too long? OR will I need them at least twice?
  • then move them here, with some useful naming
  • so later I could easily adjust all those label shifts etc. right here

Code:

\documentclass[10pt,border=3mm,tikz]{standalone}
\usetikzlibrary{arrows.meta}
\usetikzlibrary{decorations.pathreplacing}

\begin{document}
 \begin{tikzpicture}[
    a/.style={anchor=west,minimum width=5mm},   % for the node containing "a"
    bar/.style={{Bar[]}-{Bar[]}},               % start- and end-tipps as Bars
    bar2/.style={-{Bar[]}},                     % only end-tipp as bar
    mth/.style={yshift=-5mm},                   % for placing the math-labels
    decoration=brace,                           % the overbrace
    alf/.style={midway,yshift=3mm},             % placing \alpha there
    ys/.style={yshift=5mm},                     % shortcut for these yshifts
 ]
    % ~~~ lines ~~~~~~~~~~~~
    \draw[bar] (0,0) coordinate (A) -- (1.5,0)  coordinate (B) node[a]{$a$};
    \draw[bar] (2,0) coordinate (C) -- (3.5,0)  coordinate (D);
    \draw[bar2](3.5,0)              --++(1.5,0) coordinate (E) node[a]{$a$};
    \draw[bar] (5.5,0)              --++(1.5,0)                node[a]{$P$};
    
    % ~~~ labels below ~~~~~~~~~~
    \node[mth] at                (A) {$1$};
    \node[mth] at ([xshift=-2.5mm]C) {$f(i) + 1$};
    \node[mth] at                (D) {$i - f(i) + 1$};
    \node[mth] at ([xshift=+2.5mm]E) {$i + 1$};
    
    % ~~~ labels above ~~~~
    \draw[decorate,blue] ([ys]A) -- ([ys]B) node[alf]{$\alpha$};
    \draw[decorate,blue] ([ys]D) -- ([ys]E) node[alf]{$\alpha$};
    
 \end{tikzpicture}
\end{document}
5
  • 1
    I wasn't hoping for such an extensive example, thank you!
    – matteo_c
    Commented Jan 2 at 12:09
  • You're welcome. As you see it's both simple in its basic ideas, and if you leave out all those styles. And it's somewhat complex, as you'd benefit from some of the many Tikz-reatures. E.g. for learning purposes you can delete all those refinements one by one and have a look at the compiled results. This way you can follow backward so to say from complex (and nice) to simple (and less nice).
    – MS-SPO
    Commented Jan 2 at 12:25
  • 1
    Great answer! Although personally, I always start from path and then the rest. Now explain to me simply monoids please :)
    – yannisl
    Commented Jan 2 at 13:56
  • 1
    Thank you @YiannisLazarides :) Abt the monoids I could try if I knew what you mean …
    – MS-SPO
    Commented Jan 2 at 14:16
  • 1
    nice answer in detail explanation +1
    – js bibra
    Commented Jan 3 at 4:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .