PGFPlots : grouper plusieurs graphiques

Une technique « classique » pour mettre côte à côte plusieurs graphiques consisterait à utiliser les environnements subfigure subfloat. Mais une manière plus élégante est de grouper ces graphiques, ce qui permet un gain de place et une gestion plus aisée des éventuelles interactions entre lesdits graphiques.

Pour ce faire, on utilisera donc la fonction groupplot, fournie par la librairie quasi-éponyme :

\usepackage{pgfplots}
\usepgfplotslibrary{groupplots}

Exemple minimal

Tiré de la doc officielle (page 205) :

\begin{tikzpicture}
	\begin{groupplot}[group style={
	  				group size=2 by 2,},
			  height=0.2\textheight,width=0.3\textwidth]
		\nextgroupplot
			\addplot coordinates {(0,0) (1,1) (2,2)};
		\nextgroupplot
 	   		\addplot coordinates {(0,2) (1,1) (2,0)};
		\nextgroupplot
 	   		\addplot coordinates {(0,2) (1,1) (2,1)};
		\nextgroupplot
  	  		\addplot coordinates {(0,2) (1,1) (1,0)};      
	\end{groupplot}
\end{tikzpicture}
Exemple minimal d'utilisation de groupplot
Exemple minimal d’utilisation de groupplot

L’utilisation est donc relativement simple : dans un premier temps, on définit le format du groupe sous forme de tableau (deux lignes et deux colonnes dans notre cas). Ensuite, pour chaque graphique, on retrouve les commandes habituelles de PGFPlots. On passe d’un graphique au suivant grâce à la commande \nextgroupplot.

Mais pour l’instant, on peut pas encore dire que le rendu casse des briques… On va donc le peaufiner un peu, et surtout enlever les éléments redondants.

Simplification des axes

Dans l’exemple précédent, on remarque que les gammes de valeur pour les axes x et  y sont les mêmes pour tous les graphes. On peut donc demander à ne les afficher qu’à gauche et en bas, et en profiter pour resserrer un peu tout ça :

\begin{tikzpicture}
  \begin{groupplot}[group style={
  						group size=2 by 2,
  						vertical sep=0.5em,horizontal sep=2ex,
  						x descriptions at=edge bottom,y descriptions at=edge left,
  						},
  					height=0.2\textheight,width=0.3\textwidth]
    \nextgroupplot
    	\addplot coordinates {(0,0) (1,1) (2,2)};
    \nextgroupplot
    	\addplot coordinates {(0,2) (1,1) (2,0)};
    \nextgroupplot
    	\addplot coordinates {(0,2) (1,1) (2,1)};
    \nextgroupplot
    	\addplot coordinates {(0,2) (1,1) (1,0)};      
  \end{groupplot}
\end{tikzpicture}

Ce qui nous donne donc :

 

Exemple minimal, mais amélioré
On a enlevé les notations redondantes sur les axes

 

Utilisations avancées

groupplot peut aussi être utilisé de façon un peu détournée, c’est à dire pour combiner plusieurs graphiques de façon invisible.

Discontinuité sur un axe

Mieux qu’un long discours, un exemple :

Utilisation de groupplot pour dessiner une discontinuité d'axe
Un graphique qui aurait pris une page complète sans la discontinuité sur l’axe Y

Le principe est de tracer dans un premier temps les valeurs supérieures (courbe « Data A »). Puis on colle un second graphique au bas du premier pour y tracer les valeurs inférieures. Il faut de plus demander à afficher un signe distinctif pour la discontinuité (le « crunch » ici), et ne pas tracer la bordure supérieure pour le deuxième graphique. Voici donc le code qui va bien :

\begin{tikzpicture}
	\begin{groupplot}[anchor=north west,
			  group style={
				group name=coupeplot,
				group size=1 by 2,
				xticklabels at=edge bottom,
				vertical sep=0pt
			    },
			  width=0.3\textwidth,
			  xmin=0, xmax=2]
		\nextgroupplot[ymin=16,ymax=30,
			       ytick={18,20,22,24,26,28,30},
			       axis x line*=top, 
			       axis y discontinuity=crunch,
			       height=0.3\textheight]
			\addplot coordinates {(0,25) (1,26) (2,28)}; 
				\addlegendentry{Data A}       				
		\nextgroupplot[ymin=0,ymax=5,
			       axis x line*=bottom,
			       height=0.15\textheight]
			\pgfplotsset{cycle list shift=+1}
			\addplot coordinates {(0,1) (1,2) (2,2)};
				\addlegendentry{Data B}
	\end{groupplot}
\end{tikzpicture}

Il nous faut tout de même prendre certaines précautions :

  • s’assurer que les valeurs de x sont dans la même gamme, sans quoi les points seraient décalés.
  • forcer le choix des ytick pour le graphique supérieur, sinon le ytick minimal du premier graphique risque de chevaucher le ytick max du deuxième.
  • vérifier le facteur d’échelle des axes y : comme on a deux graphiques différents, rien ne force a priori PGFPlots à utiliser le même facteur d’échelle pour les  deux axes y. Il vous faut donc jouer intelligemment sur les valeurs de ymin, ymax et height pour conserver l’échelle.

Deux axes y pour chaque groupplot

Pour finir en beauté, on veut maintenant afficher deux axes Y distincts : un à gauche et l’autre à droite, comme illustré ci-après :

Quatre graphiques et 2 axes y
Quatre graphiques et 2 axes y

Code :

\pgfplotsset{compat=newest}            % Permet l'affichage de deux axes y
 
\begin{tikzpicture}
	\begin{groupplot}[group style={
					group size=2 by 2,
					horizontal sep=2ex,vertical sep=3ex,
					x descriptions at=edge bottom,y descriptions at=edge left,
					group name=plots
					},
			  ytick pos=left,
			  height=0.2\textheight,width=0.4\textwidth,
			  xmin=0,xmax=1,ymin=0,ymax=2,
			  xlabel={$x$},ylabel={$f_a(x)$}]
  		\nextgroupplot[legend to name=grouplegend,legend columns=2]
  			\addplot expression[domain=0:1] {(sqrt(\x)};
				\addlegendentry {$f_a(x)=\sqrt{x+a}$}
  			\addlegendimage{/pgfplots/refstyle=plot:ga}
				\addlegendentry{$g_a(x)=\ln(x+a)$}
  		\nextgroupplot
  			\addplot expression[domain=0:1] {(sqrt(\x+0.1)};
  		\nextgroupplot
  			\addplot expression[domain=0:1] {(sqrt(\x+0.2)};
  		\nextgroupplot
  			\addplot expression[domain=0:1] {(sqrt(\x+0.3)};
	\end{groupplot}
	\begin{groupplot}[group style={
  					group size=2 by 2,
					horizontal sep=2ex,,vertical sep=3ex,
					x descriptions at=edge bottom,y descriptions at=edge right,
					},
			  xtick=\empty, axis line style=transparent,ytick pos=right,
			  height=0.2\textheight,width=0.4\textwidth,
			  xmin=0,xmax=1,ymin=-2,ymax=1,
			  ylabel={$g_a(x)$},]
		\pgfplotsset{cycle list shift=+1}
   		\nextgroupplot[title={$a$=0},title style={yshift=-2ex}]
    			\addplot expression[domain=0:1] {ln(\x)};
				\label{plot:ga}
    		\nextgroupplot[title={$a$=0.1},title style={yshift=-2ex}]
    			\addplot expression[domain=0:1] {ln(\x+0.1)};
    		\nextgroupplot[title={$a$=0.2},title style={yshift=-2ex}]
    			\addplot expression[domain=0:1] {ln(\x+0.2)};
    		\nextgroupplot[title={$a$=0.3},title style={yshift=-2ex}]
    			\addplot expression[domain=0:1] {ln(\x+0.3)};      
  	\end{groupplot}
  	\node at (plots c1r1.north east) [inner sep=0pt,anchor=north, yshift=10ex] {\ref{grouplegend}};
\end{tikzpicture}

L’astuce est en fait la même que d’habitude : on superpose deux groupes de graphes (ici deux groupes de 4), en prenant le soin de cacher l’axe x dans le deuxième groupe. Ici encore, il faut donc s’assurer d’avoir les mêmes gammes pour les abscisses.

Au passage, vous aurez noté l’utilisation de l’option title, qui permet de donner un titre à chaque graphique.

Comme vous pouvez le constater, il est possible d’utiliser une légende unique pour tout l’environnement groupplot. Dans mon exemple, j’ai utilisé le nom du groupe (option « group name=plots » et le nom du premier graphe (« c1r1 » pour « column 1 row 1 ») comme point d’ancrage pour placer la légende que j’ai créée « à la main ».

 

Pour aller plus loin

Si vous voulez une description complète de l’ensemble des fonctionnalités de groupplot, le mieux est d’aller voir la documentation officielle de PGFplots (pages 333 à 338).