Latex labels for Graphviz (work in progress)

A year ago in Linear Algebra 1 lecture (I study Mathematics in my 60s) I created a big structure diagram with Graphviz.

Now I wanted to create a similar structure diagram for Elementary number theory lecture, but hesitated. Reason was that a year ago I had to lookup each and every Latex symbol, determine unicode and use that in Graphviz HTML label. I did not want to do that again.

So I played with Google Gemini (only today) and it had more problems with the code than for mathematical software or GPU code. But after many many iterations now a nice tool implementing the subject line is available:
https://gist.github.com/Hermann-SW/12c7644ac0c75b4eb019f76c3f023fe5

More details in the gist, below as teaser just the layout of current gist — I like it.
This is how easy Latex can be used for Graphviz labels (Latex cases environment does work!):

...
thm_3_47_label = latex_to_graphviz_html(
r"""\textbf{Thm 3.47 }For cyclic group G:\ G \cong \begin{cases}
\mathbb{Z} & \text{for }G\text{ infinite,}\
\Z /|G|\mathbb{Z} & \text{for }G\text{ finite.} \end{cases}"""
)

ex_3_48_label = latex_to_graphviz_html(
r"""\textbf{Ex 3.48 } (\Z/5\Z)^{\times} \cong \Z/4\Z\ \psi: \begin{cases}
\Z/4\Z &\to\ (\Z/5\Z)^{\times}\
a &\mapsto\ \bar{2}^a \end{cases}\lbr"""
)
...
    thm_3_47 [label={thm_3_47_label}];
    ex_3_48 [label={ex_3_48_label}];
...

Layout created:

I did search for similar projects and found some never completed and terminated decades ago.
Comments/wishes appreciated.

Cool!

Yes — I continued and completed adding (translated) sections 3.3 “prime residue classes and Fermat-Euler theorem” and 3.4 “cyclic groups” of (German language) lecture script sitting behind Heidelberg University VPN. From definition 3.13 until theorem 3.49.

If X is referred to in Y, solid edge X->Y is added.

For eg. propositions with no incoming edges I determined dotted edge where reference in script text is missing. For nodes having no outgoing edges, I added at most two dotted links, one to next example where applicable, and one for proposition/theorem/corollary if applicable.

Below is 10× scaled down screenshot, and created PDF.

In browser all labels look nice for me with 75% scaling. Searching for eg. “ord(” gives 7 hits, and clicking on one of them on left list moves view to corresponding node. Really useful for working with that graph! The gist from initial post was updated.

In above usecase an edge A->B meant that A was used in proof of B.

In two weeks from now I will give a seminar talk on “Elliptic curves and Fermat’s proof” (for n = 4 ). I decided to use and extend the above framework. But this time A->B means “implies” for a proof tree. Final code will be published later, just wanted to share what is possible right now (\left, \right, \frac, even in multi-line labels), I really like it. The most difficult part with Gemini was to get an exponent after “\right)” be at top right position. My favorite is the proof by contradiction of proposition 1.2 implying proposition 1.1 on an edge label.

Fermat_seminar.pdf (33.1 KB)

Not much more added, final version of proof diagram and Fermat_seminar.build_graph.py here:

There are quite some differences to “real LaTeX” in the labels, so I thought about a system where each node gets its own mini LaTeX doc, gets compiled automatically on change to image, then crop and that cropped image gets used in GraphViz node or edge label. Doable with Gemini, but on Monday next semester starts, will have to see when time permits to work on that project.

Wow, I couldn’t resist to make a small proof of concept.
I did put lemma 1.5 into separate file:

\documentclass[varwidth=true, border=5pt]{standalone}
\usepackage{amsmath, amssymb}

\begin{document}
% Remove automatic math spacing
\thinmuskip=0mu
\medmuskip=0mu
\thickmuskip=0mu

\textbf{Lem 1.5 }For distinct $a,b,c\in \mathbb{Q}$ define $B, \tilde{C}$ and C\\
...
\end{document}

Compiled normally with latexmk (I had to install texlive-luatex for standalone environment).

And then as proposed by Gemini:
pdftocairo -singlefile -png -r 150 x.pdf x

Finally the big lemma 1.5 in python file became
lem_1_5 [label="" shape=box image="x.png"]

In the background is the old “Latex labels for Graphviz” PDF at 50% size.
Left and bottom is the same new doc also at 50% size, for comparison.
I would say this tells me I should do that project when I will have the time!

.

P.S:
Or just use new “LaTeX-like Labels” when dot will support them like “HTML-like Labels” :wink:

P.P.S:
Wow — “comment” is attribute of nodes, edges and graph.
That is where LaTeX can be embedded, just one big .dot file and tool that

  • extracts each comment LaTeX
  • frames it with template
  • compiles it as described to the image named in “image” attribute

I tested with lemma 1.5, and dot has no problems processing that .dot file!

lem_1_5 [label="" shape=box image="x.png" comment="
\textbf{Lem 1.5 }For distinct $a,b,c\in \mathbb{Q}$ define $B, \tilde{C}$ and C\
$B={(u,v,w)\in \mathbb{Q}\times\mathbb{Q}\times\mathbb{Q}\vert u^2+a=v^2+b=w^2+c}$\
$\tilde{C}={(x,y)\in \mathbb{Q}\times\mathbb{Q}\vert y^2=(x-a)(x-b)(x-c)}$.\
$C={(x,y)\in \mathbb{Q}\times\mathbb{Q}\vert y^2=(x-a)(x-b)(x-c), y\neq 0}$.\
(1) $\exists$ mutually inverse maps $f:B\to C, g:C\to B$\
$f(u,v,w)=(u^2+a+uv+vw+wu, (u+v)(v+w)(w+u))$,\
$g(x,y)=(\tfrac{1}{2y}((x-a)^2-(b-a)(c-a))$,\
$\tfrac{1}{2y}((x-b)^2-(a-b)(c-b)), \tfrac{1}{2y}((x-c)^2-(a-c)(b-c)))$\
(2) $\exists$ map $h:B\to \tilde{C}, h(u,v,w)=(u^2+a,uvw)$
"]

The template needs to be adaptable, so just store it under graph “comment” attribute :wink:

digraph G {
layout=dot;
comment="
\documentclass[varwidth=true, border=5pt]{standalone}
\usepackage{amsmath, amssymb}

\begin{document}
% Remove automatic math spacing
\thinmuskip=0mu
\medmuskip=0mu
\thickmuskip=0mu

\end{document}
"
...

The tool could use filename “x.png.tex” for above example to store the framed extracted LaTeX from comment, but only if it changed. That would allow a simple makefile handle incremental compilations only when something changed …

Done!

After a less than 1h chat with Gemini Pro, new tool texdot.py does the job:

README.md has documentation, full workflow with single command, final .pdf will be opened in evince automatically. The tool creates a lot of output when doing the LaTeX work. But if no LaTeX label changed, its incremental compilation is cool:

hermann@8840hs:~/graphviz_latex_pipeline$ ./texdot.py demo.dot 
Extracted 3 LaTeX definitions (0 newly written/updated).
Running make...
dot -Tpdf demo_processed.dot -o demo.pdf
Successfully generated demo.pdf.
Opening demo.pdf in evince...
hermann@8840hs:~/graphviz_latex_pipeline$ 

“make clean” removes all temporary files including Makefile.

Gemini stated that edges have no “image” attribute normally, and made the tool generate HTML label as edge image workaround.

50% size evince screenshot of result:

I worked with Gemini to improve the tool further. Gemini added part of the doc as well:

In short, when a LaTeX label node or edge uses comment attribute, texdot.py errors if label or image are preset as well. The image filenames get created automatically from node IDs. In case such ID does not result in valid Linux filename, error message will telly you. Finally the needed image attributes and empty labels (to avoid overwrite of image) get injected into temporary preprocessed .dot file.

Today I finished porting biggest number_theory.dot from old to new system, with 37 LaTeX labels:

I increased fontsizes, and did print it today on Heidelberg University math library printer on A3 size paper, nice.
Here small central part: