6
1

Présenter les résultats d'un championnat sportif avec LaTeX est aisé. Il suffit de rédiger un tableau dont lignes et colonnes correspondent chacune à un concurrent : à chacune de leurs intersections se trouvera le résultat de la rencontre ayant opposé le concurrent au concurrent .

En revanche, existe-t-il un moyen aisé de présenter les résultats d'une Coupe ? À savoir une compétition avec des seizièmes de finale, des huitièmes, etc. - et un nombre de concurrents diminuant de moitié à chaque tour ?

Rédiger un tel graphique à l'aide d'un tableau est assez contraignant, puisque le nombre de cases de celui-ci diminue à chaque tour : dans le cas d'un tournoi commençant aux seizièmes de finale, la première colonne comporte trente-deux rangées et la cinquième seulement deux !

Je prends un exemple déniché sur wikipédia : le tableau final de la Coupe du monde féminine de football 2015.

Comme je l'ai indiqué plus haut, le tableau ci-dessus a un nombre de rangées allant diminuant ; il offre aussi la caractéristique d'avoir certaines de ses données qui se répètent d'une colonne à l'autre : en toute logique, les deux finalistes de cette compétition sont présents dans chacune des colonnes.

Existerait-il une extension LaTeX gérant automatiquement le nombre de rangées allant diminuendo et proposant des raccourcis permettant de ne pas répéter les mêmes données de colonne en colonne ?

Posée 04 Sep '15, 16:01

Pathe's gravatar image

Pathe ♦♦
7.4k28196245
Taux d'acceptation : 55%

Modifiée 02 Aoû '19, 05:12

1

Il est certain que l'utilisation d'un tableau n'est pas la bonne solution pour créer un arbre. Ici, comme point de départ, j'utiliserais les 'tree' de TikZ ou le package 'forest'...

(05 Sep '15, 10:57) Paul Gaborit Paul%20Gaborit's gravatar image

Voici une solution utilisant les arbres de TikZ. Mais il faut encore fournir toutes les données de chaque match...

tableau

\documentclass[tikz]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{lmodern}
\usepackage[T1]{fontenc}
\usetikzlibrary{matrix,calc}

\colorlet{gain}{black}
\colorlet{perdant}{gray!50!black}

\def\gainpremier#1#2#3#4{
  node[match] {
    \textcolor{gain}{\textbf{#1}} \& \textcolor{gain}{#2} \\
    \textcolor{perdant}{#3} \& \textcolor{perdant}{#4} \\
  }
}

\def\gainsecond#1#2#3#4{
  node[match] {
    \textcolor{perdant}{#1} \& \textcolor{perdant}{#2} \\
    \textcolor{gain}{\textbf{#3}} \& \textcolor{gain}{#4} \\
  }
}

\begin{document}
\begin{tikzpicture}
  \tikzset{
    match/.style={
      matrix,matrix of nodes,ampersand replacement=\&,
      inner sep=0,nodes={inner sep=.2em,text height=.7em,text depth=.1em}
    },
    grow=left,
    level distance=10em,
    level 1/.style={sibling distance=12em},
    level 2/.style={sibling distance=6em},
    level 3/.style={sibling distance=3em},
    edge from parent path={
      (\tikzparentnode.west)
      -| ($(\tikzparentnode)!.5!(\tikzchildnode)$)
      |- (\tikzchildnode.east)
    },
  }
  \path \gainpremier{États-Unis}{5}{Japon}{2}
  child {\gainpremier{États-Unis}{2}{Allemagne}{0}
    child {\gainsecond{Chine}{0}{États-Unis}{1}
      child {\gainpremier{Chine}{1}{Cameroun}{0}}
      child {\gainpremier{États-Unis}{2}{Colombie}{0}}
    }
    child {\gainpremier{Allemagne}{1(5)}{France}{1(4)}
      child {\gainpremier{Allemagne}{4}{Suède}{1}}
      child {\gainpremier{France}{3}{Corée du Sud}{0}}
    }
  }
  child {\gainpremier{Japon}{2}{Angleterre}{1}
    child {\gainsecond{Australie}{0}{Japon}{1}
      child {\gainsecond{Brésil}{0}{Australie}{1}}
      child {\gainpremier{Japon}{2}{Pays-Bas}{1}}
    }
    child {\gainpremier{Angleterre}{2}{Canada}{1}
      child {\gainsecond{Norvège}{1}{Angleterre}{2}}
      child {\gainpremier{Canada}{1}{Suisse}{0}}
    }
  }
  ;
\end{tikzpicture}
\end{document}

Seconde proposition

Voici une amélioration du code précédent permettant l'ajout d'un titre et d'un fond coloré pour chaque colonne.

tableau

\documentclass[tikz]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{lmodern}
\usepackage[T1]{fontenc}
\usetikzlibrary{matrix,calc,backgrounds,fit}

\colorlet{gain}{black}
\colorlet{perdant}{gray!50!black}

\def\gainpremier#1#2#3#4#5{
  node[match,name=#1] {
    \textcolor{gain}{\textbf{#2}} \& \textcolor{gain}{#3} \\
    \textcolor{perdant}{#4} \& \textcolor{perdant}{#5} \\
  }
}

\def\gainsecond#1#2#3#4#5{
  node[match,name=#1] {
    \textcolor{perdant}{#2} \& \textcolor{perdant}{#3} \\
    \textcolor{gain}{\textbf{#4}} \& \textcolor{gain}{#5} \\
  }
}

\begin{document}
\begin{tikzpicture}
  \tikzset{
    label/.style={text depth=.2em,font=\itshape\scriptsize,anchor=south},
    match/.style={
      matrix,matrix of nodes,ampersand replacement=\&,
      inner sep=0,nodes={inner sep=.2em,text height=.7em,text depth=.1em}
    },
    grow=left,
    level distance=10em,
    level 1/.style={sibling distance=12em},
    level 2/.style={sibling distance=6em},
    level 3/.style={sibling distance=3em},
    edge from parent path={
      (\tikzparentnode.west)
      -| ($(\tikzparentnode)!.5!(\tikzchildnode)$)
      |- (\tikzchildnode.east)
    },
  }
  \path \gainpremier{1-1}{États-Unis}{5}{Japon}{2}
  child {\gainpremier{2-1}{États-Unis}{2}{Allemagne}{0}
    child {\gainsecond{4-1}{Chine}{0}{États-Unis}{1}
      child {\gainpremier{8-1}{Chine}{1}{Cameroun}{0}}
      child {\gainpremier{8-2}{États-Unis}{2}{Colombie}{0}}
    }
    child {\gainpremier{4-2}{Allemagne}{1(5)}{France}{1(4)}
      child {\gainpremier{8-3}{Allemagne}{4}{Suède}{1}}
      child {\gainpremier{8-4}{France}{3}{Corée du Sud}{0}}
    }
  }
  child {\gainpremier{2-2}{Japon}{2}{Angleterre}{1}
    child {\gainsecond{4-3}{Australie}{0}{Japon}{1}
      child {\gainsecond{8-5}{Brésil}{0}{Australie}{1}}
      child {\gainpremier{8-6}{Japon}{2}{Pays-Bas}{1}}
    }
    child {\gainpremier{4-4}{Angleterre}{2}{Canada}{1}
      child {\gainsecond{8-7}{Norvège}{1}{Angleterre}{2}}
      child {\gainpremier{8-8}{Canada}{1}{Suisse}{0}}
    }
  }
  ;
  \begin{pgfonlayer}{background}
    \node[inner sep=.2em,fit=(8-1)(8-2)(8-3)(8-4)(8-5)(8-6)(8-7)(8-8)]
    (huitieme){};
    \node[inner sep=.2em,fit=(4-1)(4-2)(4-3)(4-4)](quart){};
    \node[inner sep=.2em,fit=(2-1)(2-2)](demi){};
    \node[inner sep=.2em,fit=(1-1)](finale){};
    \node[inner sep=0,fit=(huitieme)(quart)(demi)(finale)](global){};

    \foreach \niveau/\couleur in {
      huitieme/cyan!10,
      quart/orange!10,
      demi/yellow!20,
      finale/red!10%
    }{
      \fill[fill=\couleur]
      (\niveau.west |- global.south)
      rectangle
      (\niveau.east |- global.north);
    }
    \path
    (huitieme |- global.north) node[label]{Huitièmes de finale}
    (quart |- global.north) node[label]{Quarts de finale}
    (demi |- global.north) node[label]{Demi-finales}
    (finale |- global.north) node[label]{Finale}
    ;
  \end{pgfonlayer}
\end{tikzpicture}
\end{document}

Troisième proposition

Ici, afin d'aligner les noms des pays à gauche et les scores à droite et pour garantir un alignement globale, on fixe la largeur de la matrice contenant un match en fixant la largeur de chacune des deux colonnes (merci à @touhami pour cette suggestion).

On ajoute aussi la petite finale (qui ne fait pas partie de l'arbre des matches), en la positionnant à l'intersection du dernier match des huitièmes de finale (8-8) et de la finale (1-1) d'où l'utilisation de (8-8 -| 1-1) (-: intersection horizontale, |: intersection verticale). On ajoute le titre (le label) "petite finale" avec un code similaire à celui permettant de placer les titres des colonnes.

tableau

\documentclass[tikz]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{lmodern}
\usepackage[T1]{fontenc}
\usetikzlibrary{matrix,calc,backgrounds,fit}

\colorlet{gain}{black}
\colorlet{perdant}{red!50!black}

\def\gainpremier#1#2#3#4#5{
  node[match,name=#1] {
    \textcolor{gain}{\textbf{#2}} \& \textcolor{gain}{#3} \\
    \textcolor{perdant}{#4} \& \textcolor{perdant}{#5} \\
  }
}

\def\gainsecond#1#2#3#4#5{
  node[match,name=#1] {
    \textcolor{perdant}{#2} \& \textcolor{perdant}{#3} \\
    \textcolor{gain}{\textbf{#4}} \& \textcolor{gain}{#5} \\
  }
}

\begin{document}
\begin{tikzpicture}
  \tikzset{
    label/.style={text depth=.2em,font=\itshape\scriptsize,anchor=south},
    match/.style={
      matrix,matrix of nodes,ampersand replacement=\&,
      inner sep=.2em,nodes={inner sep=.1em,text height=.7em,text depth=.1em},
      column 1/.style={text width=6em,align=left},
      column 2/.style={text width=1.5em,align=right}
    },
    grow=left,
    level distance=10.5em,
    level 1/.style={sibling distance=12em},
    level 2/.style={sibling distance=6em},
    level 3/.style={sibling distance=3em},
    edge from parent path={
      (\tikzparentnode.west)
      -| ($(\tikzparentnode)!.5!(\tikzchildnode)$)
      |- (\tikzchildnode.east)
    },
  }
  \path \gainpremier{1-1}{États-Unis}{5}{Japon}{2}
  child {\gainpremier{2-1}{États-Unis}{2}{Allemagne}{1}
    child {\gainsecond{4-1}{Chine}{0}{États-Unis}{1}
      child {\gainpremier{8-1}{Chine}{1}{Cameroun}{0}}
      child {\gainpremier{8-2}{États-Unis}{2}{Colombie}{0}}
    }
    child {\gainpremier{4-2}{Allemagne}{1(5)}{France}{1(4)}
      child {\gainpremier{8-3}{Allemagne}{4}{Suède}{1}}
      child {\gainpremier{8-4}{France}{3}{Corée du Sud}{0}}
    }
  }
  child {\gainpremier{2-2}{Japon}{2}{Angleterre}{1}
    child {\gainsecond{4-3}{Australie}{0}{Japon}{1}
      child {\gainsecond{8-5}{Brésil}{0}{Australie}{1}}
      child {\gainpremier{8-6}{Japon}{2}{Pays-Bas}{1}}
    }
    child {\gainpremier{4-4}{Angleterre}{2}{Canada}{1}
      child {\gainsecond{8-7}{Norvège}{1}{Angleterre}{2}}
      child {\gainpremier{8-8}{Canada}{1}{Suisse}{0}}
    }
  }
  ;

  \path (8-8 -| 1-1) \gainpremier{pf}{Allemagne}{2}{Angleterre}{1};

  \begin{pgfonlayer}{background}
    \node[inner sep=.2em,fit=(8-1)(8-2)(8-3)(8-4)(8-5)(8-6)(8-7)(8-8)]
    (huitieme){};
    \node[inner sep=.2em,fit=(4-1)(4-2)(4-3)(4-4)](quart){};
    \node[inner sep=.2em,fit=(2-1)(2-2)](demi){};
    \node[inner sep=.2em,fit=(1-1)](finale){};
    \node[inner sep=0,fit=(huitieme)(quart)(demi)(finale)](global){};

    \foreach \niveau/\couleur in {
      huitieme/cyan!10,
      quart/orange!10,
      demi/yellow!20,
      finale/red!10%
    }{
      \fill[fill=\couleur]
      (\niveau.west |- global.south)
      rectangle
      (\niveau.east |- global.north);
    }
    \path
    (huitieme |- global.north) node[label]{Huitièmes de finale}
    (quart |- global.north) node[label]{Quarts de finale}
    (demi |- global.north) node[label]{Demi-finales}
    (finale |- global.north) node[label]{Finale}
    (pf.north) node[label]{Petite Finale}
    ;
  \end{pgfonlayer}
\end{tikzpicture}
\end{document}
Lien permanent

Publiée 05 Sep '15, 17:15

Paul%20Gaborit's gravatar image

Paul Gaborit
2.0k16
Taux d'acceptation : 32%

Modifiée 15 Mai '21, 14:11

stefan's gravatar image

stefan ♦♦
8618

La réponse est remarquable. Une chose cependant : il faudrait présenter cela en colonnes, de préférence avec un fond coloré alternant d'une colonne à l'autre, chaque colonne possédant un en-tête précisant « quarts de finale », « demi-finale », etc. C'est pour cette raison que j'ai initialement pensé à un tableau.

(05 Sep '15, 19:54) Pathe ♦♦ Pathe's gravatar image

C'est parfait.

(07 Sep '15, 17:51) Pathe ♦♦ Pathe's gravatar image

@Pathe Si la réponse convient, il est préférable de le signifier en « l'acceptant » (en cliquant sur la coche figurant en haut à gauche) plutôt qu'au moyen d'un commentaire.

(07 Sep '15, 22:30) denis ♦♦ denis's gravatar image

Dans chaque colonne de résultats, j'aimerais aligner à gauche les noms de pays, tandis que les scores eux-mêmes resteraient alignés à droite comme c'est à présent le cas.

Je n'ai pas trouvé le paramètre réglant la position du texte dans chaque node.

Comment faire ?

(06 Nov '16, 23:07) Pathe ♦♦ Pathe's gravatar image

Par ailleurs, l'ajout du match pour la troisième place, qui si l'on s'en réfère à l'exemple devrait être placé au bas de la colonne de la finale, s'avère problématique.

(07 Nov '16, 01:08) Pathe ♦♦ Pathe's gravatar image
1

Pour ajouter la petite finale, juste avant \begin{pgfonlayer}, on peut insérer la ligne suivante : \path (8-8 -| 1-1) \gainpremier{pf}{Allemagne}{2}{Angleterre}{1};. Évidemment, il faut ajouter ce nouveau noeud (pf) dans la liste passée à fit pour la colonne de la finale.

(07 Nov '16, 08:37) Paul Gaborit Paul%20Gaborit's gravatar image

Concernant la mini-matrice utilisée pour chaque match, chacun des nœuds est centré (le nom du pays comme celui du score). Il suffit de tester avec un score supérieur à 9 pour s'en rendre compte. Pour choisir l'alignement, il ne faut plus utiliser matrix of nodes (dans le style match) et appeler soi-même \node en passant des options. Ce qui pourrait donner :

\def\gainpremier#1#2#3#4#5{ node[match,name=#1] { \node[text=gain,right]{\textbf{#2}}; \& \node[text=gain,left]{#3}; \\ \node[text=perdant,right]{#4}; \& \node[text=perdant,left]{#5}; \\ } }

(07 Nov '16, 08:42) Paul Gaborit Paul%20Gaborit's gravatar image

@Pathe et @Paul Gaborit On peut redefinir le style match pour avoir l'alignement désiré. (text width=2.1cm peut être inutile)

match/.style={ matrix,matrix of nodes,ampersand replacement=\&, inner sep=0,nodes={inner sep=.2em,text height=.7em,text depth=.1em}, column 1/.style={right,text width=2.1cm}, column 2/.style={left} },

(08 Nov '16, 00:05) touhami touhami's gravatar image

Le code pour l'inclusion de la petite finale fonctionne bien, même si je ne le comprends pas totalement.

On utilise un noeud « gain premier », on l'appelle « pf » : jusqu'ici ça va.

Mais je ne comprends pas son positionnement : pourquoi est-ce que \path (8-8 -| 1-1) suffit à le positionner au bas de la colonne de la finale ?

Quant à inclure la mention « petite finale » au-dessus de ce résultat, et sur fond blanc, j'en suis loin !

(08 Nov '16, 00:41) Pathe ♦♦ Pathe's gravatar image

@touhami : votre proposition de redéfinition du style « match » fonctionne, mais chose étrange, le quart de finale « France - Allemagne » est décalé à gauche par rapport aux trois autres quarts de finale. Pourquoi ?

(08 Nov '16, 00:48) Pathe ♦♦ Pathe's gravatar image

En fait les noeuds ont chacun une taille différente : tout dépend du texte que chaque noeud contient.

Ainsi la chaîne « Canada 1 / Suisse 0 » est-elle plus courte que « France 3 / Corée du Sud 0 », d'où des ruptures d'alignement vertical.

Pour bien faire, il faudrait spécifier une taille pour toutes les matrices contenant les résultats, ce qui permettrait d'aligner parfaitement ceux-ci. Et de rendre identiques tous les traits qui relient les résultats (par exemple de deux huitièmes de finale au quart de finale qui en découle).

(08 Nov '16, 00:59) Pathe ♦♦ Pathe's gravatar image
1

@Pathe c'est ça. On peut par exemple match/.style={ matrix,matrix of nodes,ampersand replacement=\&, inner sep=0,nodes={inner sep=.2em,text height=.7em,text depth=.1em}, column 1/.style={text width=2.3cm}, column 2/.style={text width=.5cm, align=right} },

puis remplacer level distance=10em par level distance=11em.

(08 Nov '16, 08:09) touhami touhami's gravatar image
1

@Pathe Pour le positionnement de la petite finale, j'utilise l'opérateur -| qui intersecte la position de deux nœuds, horizontalement pour le premier nœud (-) et verticalement pour le deuxième (|). Ici le premier nœud est 8-8 (le huitième match des huitièmes de finale) et le nœud 1-1 (la finale).

(08 Nov '16, 09:16) Paul Gaborit Paul%20Gaborit's gravatar image

Ajouter fill = white à label permet d'isoler la mention « petite finale » sur un fond blanc :

label/.style={fill = white, text depth=.2em, font=\itshape\scriptsize, anchor=south}

(08 Nov '16, 20:48) Pathe ♦♦ Pathe's gravatar image

Je suis navré de revenir à nouveau sur ce fil, mais j'essaye de commenter le code, et je ne réussis pas à trouver le paramètre permettant d'intervenir sur la longueur des fins traits noirs horizontaux qui partent d'un score et vont à la barre verticale située entre deux zones colorées.

(13 Nov '16, 18:52) Pathe ♦♦ Pathe's gravatar image

@Pathe Pour la distance qui sépare deux colonnes, c'est le paramètre level distance qui compte. Ensuite, c'est la valeur .5 dans edge from parent path qui indique que la barre verticale de liaison doit être au milieu des deux colonnes. Pour pouvoir faire varier cette valeur entre 0 et 1, il faudrait mieux utiliser ($(\tikzparentnode.west)!.5!(\tikzchildnode.east)$) plutôt que ($(\tikzparentnode)!.5!(\tikzchildnode)$).

(14 Nov '16, 03:01) Paul Gaborit Paul%20Gaborit's gravatar image

Si je comprends bien, (\tikzparentnode.west) -| ($(\tikzparentnode)!.5!(\tikzchildnode)$) |- (\tikzchildnode.east) veut dire que l'on tire la ligne :

  • en partant à l'horizontale de « l'ouest » des scores (parentnode),
  • une fois arrivés à mi-chemin entre parentnode et childnode sur l'axe des abscisses, on tourne à 90 degrés vers le bas,
  • une fois arrivés à la hauteur du childnode, nouveau virage à 90 degrés, et l'on arrête le trait à « l'est » du nom des pays (childnode).

J'ai bon ?

(14 Nov '16, 11:05) Pathe ♦♦ Pathe's gravatar image

Si j'ai bon, je ne comprends pas pourquoi mes traits démarrent au milieu des colonnes et non à l'ouest des parentnodes : cette partie de mon code est identique à celle présente ci-dessus.

(14 Nov '16, 11:06) Pathe ♦♦ Pathe's gravatar image

@Pathe merci de préciser ce que vous voulez par milieu des colonnes? ou un capteur-écran?

(14 Nov '16, 15:59) touhami touhami's gravatar image

Je m'explique : j'ai inséré les drapeaux, comme sur la source Wikipédia. Du coup mes colonnes ont besoin d'être plus larges. J'ai donc modifié ces lignes suivantes :

Ouvrir dans l'éditeur
  `column 1/.style={text width=7.9em,align=left},
  column 2/.style={text width=2.5em,align=right}
},
grow=left,
level distance=13em,`

... et ça change tout ! Je ne réussis pas à changer la longueur de ces traits.

(14 Nov '16, 16:07) Pathe ♦♦ Pathe's gravatar image

J'essaie de comprendre comment uploader une copie d'écran et je la poste illico.

(14 Nov '16, 16:07) Pathe ♦♦ Pathe's gravatar image

Voici ce que ça donne : Traits trops longs

(14 Nov '16, 16:10) Pathe ♦♦ Pathe's gravatar image

@Pathe pour reproduire ce problème il me fallait écrire (\tikzparentnode.west) -| ($(\tikzparentnode)!.5!(\tikzchildnode)$) |- (\tikzchildnode.center)

(14 Nov '16, 18:21) touhami touhami's gravatar image
Affichage de 5 parmi 23 Afficher 18 commentaire(s) en plus

Voici ce que ça donne :des traits trop longs

Lien permanent

Publiée 14 Nov '16, 16:11

Pathe's gravatar image

Pathe ♦♦
7.4k28196245
Taux d'acceptation : 55%

Modifiée 15 Mai '21, 14:12

stefan's gravatar image

stefan ♦♦
8618

1

Si j'ai bien compris la raison d'être de cette « capture d'écran », il vaudrait mieux qu'elle apparaisse en mise à jour de la question qu'en réponse.

(14 Nov '16, 18:30) denis ♦♦ denis's gravatar image

J'ai écrit en commentaire qui ne s'affiche plus :

@Pathe pour reproduire ce problème il me fallait écrire (\tikzparentnode.west) -| ($(\tikzparentnode)!.5!(\tikzchildnode)$) |- (\tikzchildnode.center)

(14 Nov '16, 18:53) touhami touhami's gravatar image
1

@Pathe Le mieux serait de créer une nouvelle question (faisant référence à celle-ci) avec le nouveau code qui pose problème.

(14 Nov '16, 19:35) Paul Gaborit Paul%20Gaborit's gravatar image
Votre réponse
(dés)activer l'aperçu

Suivre cette question

Par courriel :

Une fois que vous serez enregistré, vous pourrez souscrire à n'importe quelle mise à jour ici

Par flux RSS :

Réponses

Réponses et commentaires

Bases de Markdown

  • *italique* ou _italique_
  • **gras** ou __gras__
  • Lien ::[texte](http://url.com/ "Titre ")
  • Image : ?![alt texte](/path/img.jpg "Titre ")
  • Liste numérotée : 1. Foo 2. Bar
  • Pour ajouter un passage à la ligne, ajoutez deux espaces à l'endroit où vous souhaitez que la ligne commence.
  • Les balises HTML de base sont également prises en charge.