TikZ : Externalisez vos figures pour gagner en temps de compilation

J’avais déjà donné dans un précédent billet une méthode pour sortir les figures TikZ dans des fichiers distincts, pour d’éventuelles utilisation standalone. On va voir dans ce billet une autre façon d’externaliser les figures avec en plus la chance d’utiliser ces sorties pour éviter de reconstruire toutes les figures à chaque compilation, d’où un gain de temps non négligeable lors de la compilation.

Quiconque fait du TikZ sait que le temps de compilation des figures est parfois loin d’être négligeable (c’est d’ailleurs un des reproches fait à TikZ par rapport à pstrick…). Et bien sûr cette tendance se fait grandement sentir sur les gros documents. Mais si on y réfléchis, c’est un peu con de recalculer toutes figures et autres graphs à chaque compilation, juste parce qu’on a changé une virgule en un point virgule dans la conclusion.

On va donc voir comment dire à \LaTeX de sortir ces fameuses figures, pour les réutiliser au lieu de les recalculer.

Fichier source

Voici un exemple minimal, illustrant la syntaxe à utiliser :

\documentclass[12pt]{article}
\usepackage{tikz}
\usetikzlibrary{external}
  \tikzexternalize
\usepackage{pgfplots}
 
\begin{document}
\begin{figure}
	\centering
	\tikzsetnextfilename{figureexternalisee} % Nom du fichier de sortie de la figure
	\input{figuretikz.tex} % Source TikZ dans un fichier annexe, pour la lisibilité
\end{figure}
\end{document}

À la première compilation, on va donc créer plusieurs pdf (je parle ici de la compilation avec pdflatex, adapter au besoin) : le document maître, comme d’habitude, et autant d’autres pdf que de figures TikZ, portant chacun les noms que vous aurez pris le soin de choisir avec la commande \tikzsetnextfilename.

On voit donc déjà un avantage de cette méthode par rapport à celle que j’avais développé dans l’ancien billet : en une compilation, on sort toutes les figures. Aux compilations suivantes, TikZ va voir qu’il existe déjà des fichiers de sortie dans le dossier de travail, et va donc se contenter d’inclure ces figures dans le document. Si on veut modifier une figure (donc la recompiler), il suffit de supprimer le pdf correspondant. [EDIT] Encore plus pratique, il suffit d’ajouter la commande :

\tikzset{external/remake next}

juste avant « \tikzsetnextfilename » pour indiquer à TikZ de refaire la figure. Il faut alors penser à commenter cette ligne pour ne pas recompiler la figure. [/EDIT]

Compilation

C’est là que réside la feinte : si on tente brutalement un pdflatex source.tex alors, pdflatex va s’arrêter parce qu’il se trompe de jobname (dû à une commande pour l’externalisation). La commande à utiliser est donc la suivante :

pdflatex -shell-escape source.tex

L’option shell-escape autorise \LaTeX à lancer des commandes externes. En vrai, cette commande n’est nécessaire qu’à la première compilation. Si tous les fichiers de sortie sont présents, on peut se contenter de pdflatex.

Temps de compilation

Le but est je l’ai dit de gagner en temps de compilation, on va donc faire le test pour voir si c’est efficace : avec le fichier source présenté plus haut et une grosse figure bien lourde, telle que présentée ici, le temps nécessaire à la première compilation (sur mon Athlon X4 640) est de 2,02s. À la deuxième compilation, il passe à… 0,31s ! CQFD.

Erreur « I can’t find file `tikzlibraryexternal.code.tex’  »

Si le compilateur vous sort ce genre d’erreur, c’est que votre version de pgf n’est pas à jour. Vous trouverez ici la dernière version et ici comme l’installer.

Cadeau aux linuxiens

Pour déterminer le temps d’exécution d’une tache, comme réalisé juste au dessus :

/usr/bin/time commande

 

Bonnes compilations !

TikZ  : Externalisez vos figures pour gagner en temps de compilation
4.8 (96 %) 5 votes
  • Pingback: Sortir des figures TikZ dans des fichiers annexes | Le Blog de Dorian()

  • Bonjour et merci pour toutes ces informations précieuses. Deux questions :
    1) Peux-on effacer les fichiers .log et .dpth générés ?
    2) Mes premiers essais montrent que l’image affichée est plus petite que celle affichée initialement. Comment faire pour augmenter la taille d’affichage du pdf ?
    Merci d’avance pour vos réponses.

    • Salut ! (pdf)latex seul ne peut pas supprimer les fichiers de compilations (tels que .log, .aux etc). Pour ce faire, tu peux toutefois utiliser la commande latexmk -c, ou carrément faire un script bash/bat qui te ferait genre pdflatex+bibtex+pdflatex+pdflatex+rm *.log…

      En ce qui concerne ton problème de taille d’image, parle-tu des fichiers externalisés ou bien des figures dans le document maître ? Dans le premier cas, c’est pas vraiment un problème, puisque les images restent vectorielles (donc peu importe leur échelle) ; dans le second, ce serait surprenant, je n’ai jamais remarqué cela…

    • Si tu te poses encore la question, j’ai trouvé dans la doc une info intéressante pour éviter de surcharger ton dossier de travail :
      \tikzsetexternalprefix{External-TikZ/}
      Qui permettra de ranger toutes les figures (ainsi que les .log, .md5 etc. aossociés) dans le dossier « External-TikZ ».

  • Pingback: TikZ : externalisation et références croisées | Le Blog de Dorian()

  • Négrier Romain

    Salut Dorian, merci pour toute les infos que tu donnes dans ton blog c’est vraiment appréciable ! J’ai suivi ton billet sur l’externalisation des figures et j’ai appliqué ce que tu proposes. Ca fonctionnait très bien jusqu’à ce que j’update PGF dans sa version 3.0.0. La commande pdflatex -shell-escape compile toutes les figures… Des idées ?

    • Salut !
      Merci pour l’intérêt que tu portes à mes travaux !
      J’ai fait quelques tests, et quelques recherches sur internet pour me renseigner. Depuis la version 3, pour chaque environnement tikzpicture, pgf fait un hash md5 sur le contenu, et le stocke dans un fichier texte (figure.md5). Il ne compile alors la figure que si le hash change.

      En gros, normalement, tu n’as plus besoin des \tikzset{external/remake next}. Il est précisé dans la doc que si le md5 n’est pas disponible, alors il compare la source elle-même pour y détecter une modification. Bref, je vois pas trop pourquoi ça marche pas chez toi… Tu peux essayer de modifier le moyen de détecter les modifications (voir page 621 de la doc).
      Essaye avec un cas minimal, et dis-moi ce que ça donne.

  • Pingback: Externalisation et includeonly | Le Blog de Dorian()