web-dev-qa-db-fra.com

Comment définir la taille de sortie dans GraphViz pour le format de point?

Je veux m'assurer que tous les nœuds sont dans une certaine plage (disons [0,0, W, H]) après la mise en page.

J'ai pensé que la boîte englobante serait la solution en utilisant l'attribut bb, mais les points et neato le remplace simplement.

Par exemple mon graphique:

strict digraph {
    1,2,3;
    1 -> 3;
    3 -> 2;
}

Sortie de neato -Gbb="0,0,50,50" -T dot file.txt:

strict digraph {
        graph [bb="0,0,120.49,162.36"];
        node [label="\N"];
        1        [height=0.5,
                pos="27,18",
                width=0.75];
        3        [height=0.5,
                pos="70.233,75.918",
                width=0.75];
        1 -> 3   [pos="e,57.954,59.469 39.043,34.133 43.004,39.441 47.504,45.468 51.827,51.261"];
        2        [height=0.5,
                pos="93.485,144.36",
                width=0.75];
        3 -> 2   [pos="e,87.436,126.56 76.221,93.545 78.643,100.67 81.496,109.07 84.177,116.97"];
}

J'obtiens les mêmes positions pour toute valeur de bb ou toute combinaison de size et dpi.

Ce dont j'ai besoin, c'est d'avoir tous les nœuds dans une boîte donnée.

Des suggestions sur la façon de procéder?

Article complet:

J'utilise * graphviz_layout * de networkx pour mettre en page mon graphique. Je dessine le graphique avec pyprocessing . Je veux éviter de redimensionner les résultats de * graphviz_layout *, s'il y a un moyen de dire à neato mes limites à la place.

29
shinjin

Voici la version TL; DR:

Pour générer une image PNG de 900 x 1500 pixels à partir du graphique de foo.gv, vous pouvez exécuter:

dot -Tpng -Gsize=9,15\! -Gdpi=100 -ofoo.png foo.gv

pour produire une image qui fait exactement 900 pixels de large ou 1 500 de haut, mais pas nécessairement les deux; puis:

convert foo.png -gravity center -background white -extent 900x1500 final.png

pour remplir l'image avec des espaces afin qu'elle soit exactement 900 par 1500 pixels; où convert fait partie de la suite ImageMagick .

Voici l'explication détaillée:

Clarifier:

  1. L'attribut bb est marqué comme "écriture seule" , donc aucun des moteurs de mise en page Graphviz n'est susceptible de respecter les valeurs que vous soumettez avant le traitement.

  2. Dans le cas général, Graphviz peut générer des graphiques vectoriels (évolutifs) et bitmap , donc DPI n'est pas toujours une métrique significative.

    En particulier, l'attribut dpi n'est valide que pour les formats de sortie bitmap et SVG.

Ce que vous essayez de faire est un peu compliqué car la taille en pixels d'une image générée par Graphviz est déterminée par deux attributs en interaction.

Prenons un graphique arbitraire comme exemple.

La commande gvgen‎ -dh3 générera un hypercube dirigé de degré trois. (Si vous souhaitez plus de détails à ce sujet, un rendu PDF de la page de manuel de gvgen est ici , mais cela n'a pas d'importance, c'est juste un graphique arbitraire à des fins de démonstration.)

Un rendu PNG par défaut généré par points de ce graphique peut être créé en exécutant la commande:

gvgen -dh3 | dot -Tpng -oexample.png

Lorsque je fais cela, j'obtiens une image au format PNG (bitmap) de 275 x 347 pixels. (Tel que rapporté par file example.png.)

L'attribut size vous permet de recommander une hauteur et une largeur maximales ou souhaitées pour l'image de sortie en pouces. C'est-à-dire que l'attribut size=3,5 indique à Graphviz de générer une image de 3 x 5 pouces au plus . Si l'image est inférieure à 3 par 5 pour commencer, Graphviz la laissera tranquille. Si l'image est plus grande que 3 pouces par 5 pouces pour commencer, Graphviz la réduira jusqu'à ce qu'elle tienne dans un canevas de 3 par 5 pouces (en préservant le rapport d'aspect de l'image originale).

L'ajout d'un point d'exclamation modifie l'attribut size d'une taille maximale à une taille souhaitée . Maintenant, si les deux dimensions sont plus petites que la taille spécifiée, le dessin est agrandi jusqu'à ce que au moins une dimension est égale à la taille spécifiée.

Par exemple, exécuter:

gvgen -dh3 | dot -Tpng -Gsize=3,5\! -oexample.png

(Notez que \! échappe au point d'exclamation pour bash. Dans un fichier DOT, vous écrivez simplement size=3,5!.)

génère une image de 288 x 363 pixels, légèrement plus grande dans les deux dimensions que la valeur par défaut.

Comment dot a-t-il trouvé ces chiffres? Eh bien, la valeur DPI par défaut de Graphviz est de 96 pixels par pouce. À cette résolution, une image de 3 x 5 pouces est un pixel de 288 x 480 image. Le moteur de mise en page a simplement agrandi l'image jusqu'à ce qu'au moins une des dimensions corresponde à la taille souhaitée.

Vous pouvez remplacer la valeur DPI par défaut à l'aide de l'attribut dpi , comme ceci:

gvgen -dh3 | dot -Tpng -Gsize=3,5\! -Gdpi=200 -oexample.png

Maintenant, l'image générée mesure 600 par 757 pixels. Encore une fois, Graphviz a simplement mis l'image à l'échelle jusqu'à ce que l'une des dimensions corresponde à la taille souhaitée (mais à cette résolution, une image de 3 x 5 pouces est une image de 600 x 1 000 pixels).

Par conséquent, si vous souhaitez générer une image contenant un nombre arbitraire de pixels, vous devez définir à la fois size et dpi de manière appropriée.

C'est-à-dire, supposons que vous vouliez créer une image de 900 par 1500 pixels. Vous pouvez utiliser:

gvgen -dh3 | dot -Tpng -Gsize=9,15\! -Gdpi=100 -oexample.png

ou

gvgen -dh3 | dot -Tpng -Gsize=3,5\! -Gdpi=300 -oexample.png

ou même:

gvgen -dh3 | dot -Tpng -Gsize=900,1500\! -Gdpi=1 -oexample.png

(Mais alors que ce dernier semblait fonctionner pour moi dans un test rapide, je recommanderais de rester avec une valeur DPI plus conventionnelle au cas où.)

Cela résout la plupart de votre problème, mais notez que Graphviz ne fait que redimensionner l'image jusqu'à ce que l'une des dimensions corresponde à la taille spécifiée. Selon le rapport d'aspect de votre image d'origine, vous pouvez ou non obtenir la taille exacte que vous recherchez.

C'est là que l'attribut ratio entre en jeu.

La commande:

gvgen -dh3 | dot -Tpng -Gsize=3,5\! -Gdpi=300 -Gratio=fill -oexample.png

devrait vous donner une image avec la dimension précise que vous recherchez, mais avec quelques mises en garde:

  • En pratique, il semble parfois donner une taille légèrement différente de celle souhaitée. Par exemple, lorsque j'exécute la commande ci-dessus, j'obtiens une image de 900 par 1472 pixels (plutôt que 900 par 1500). Je ne sais pas si cela est dû à une erreur d'arrondi ou quoi.

  • Pour ce faire, Graphviz doit mettre l'échelle à disposition indépendamment dans chaque dimension. Il est assez intelligent pour mettre à l'échelle la disposition et non l'image , donc le l'image n'est pas déformée en soi, mais en fonction de la différence entre le rapport d'aspect demandé et le rapport d'aspect "naturel" de la mise en page, l'espacement horizontal vs vertical peut sembler un peu bizarre.

ratio accepte également quelques valeurs différentes. Voir la documentation et/ou expérimenter un peu pour voir ce qu'ils font.

Pour ce que ça vaut, si vous voulez littéralement une image des dimensions précises de pixels que vous demandez, ma suggestion serait de laisser Graphviz mettre à l'échelle l'image de telle sorte que l'une des deux dimensions correspond, puis utiliser quelque chose comme ImageMagick pour remplir l'image pour obtenir le rapport hauteur/largeur précis que vous recherchez. Par exemple, la commande:

convert in.png -gravity center -background white -extent 900x1500 out.png

va centrer l'image (de in.png) sur un canevas de 900 x 1500 pixels (en l'enregistrant dans out.png) en remplissant la dimension horizontale ou verticale si nécessaire

65
Rod