Saltar al contenido

¿Cómo puedo dibujar árboles simples en LaTeX?

Este equipo redactor ha estado horas buscando la solución a tu interrogante, te compartimos la respuestas por esto nuestro deseo es resultarte de gran ayuda.

Solución:

Aunque normalmente segundo el comentario de Will Robertson, ya que TikZ es fantástico y vale la pena aprender, creo que TikZ es exagerado para esta situación. Personalmente, encuentro su sintaxis de especificación de árbol más voluminosa de lo necesario. Mi herramienta preferida para el trabajo es el paquete qtree (que también está en CTAN y aparentemente está incluido tanto en TeX Live como en MikTeX). El paquete es realmente sencillo de usar. Considere el siguiente TeX:

Tree[.IP [.NP [.Det textitthe ]
               [.N1 [.N textitpackage ]]]
          [.I1 [.I textsc3sg.Pres ]
                [.VP [.V1 [.V textitis ]
                           [.AP [.Deg textitreally ]
                                [.A1 [.A textitsimple ]
                                      qrooftextitto use.CP ]]]]]]

Esto produce el siguiente árbol:

Ejemplo de árbol de análisis sintáctico de la teoría de la barra X.

¡Eso es todo lo que se necesita! Y lo bueno de esto es que la descripción de TeX lee como el árbol. Puedo echar un vistazo al TeX e instantáneamente sé cómo se verá el árbol creado. La sintaxis básica es simplemente [.node-namesubtrees... ]; qroof, que dibuja el triángulo, requiere su nombre de nodo al final. los 1 es solo un atajo para un primo en modo matemático. Además, qtree siempre representará _ y ^ también como subguiones y superguiones. (A menos que apague esto).

En general, puede proporcionar nombres de nodo al principio ([.+ 1 [.* 2 3 ]]) o el final ([ 1 [ 2 3 ].* ].+); incluso puede proporcionar nombres de nodo en ambos lugares, pero luego deben coincidir (como era de esperar). Esto, dicho sea de paso, es la razón por la que qroof toma su nombre de nodo de la forma en que lo hace. Incluso puede dejar el nombre del nodo desactivado por completo para obtener un nodo con una unión suave. Si algo de esto no está claro, consulte el manual.

Ahora, qtree tal cual tiene una desventaja, que es que está diseñado para sencillo árboles. Ofrece soporte limitado para cambiar el espaciado entre nodos, enmarcar partes de árboles y cosas así, pero no es capaz de hacer nada increíblemente elegante. Pero afortunadamente, si lo desea, aún puede obtenerlo: ingrese tikz-qtree. Este paquete le permite aprovechar todo el poder de TikZ para dibujar sus árboles. Las dos características obvias son: (a) en lugar de texto, las etiquetas en un árbol pueden ser arbitrarias nodes; y (b) puede redefinir cómo dibuja los bordes para obtener flechas, líneas discontinuas, bordes curvos, etc. Pero es más poderoso que solo esto: si inserta un Tree en una imagen de TikZ, puedes hacer lo que que desee con los nodos, como rodearlos, dibujar flechas entre ellos para una transformación, etc.

Tal vez no necesite este poder ahora, pero el mensaje para llevar a casa es que usar qtree no lo haré enciérrate en los árboles sencillos. Si decide que desea los árboles más potentes, todo lo que necesita hacer es cambiar una importación; todo seguirá funcionando como lo hizo, pero tú también obtendrás más potencia. No estoy seguro de si tikz-qtree esto realmente usa qtree debajo del capó o no, pero de cualquier manera, todos los sintaxis porque qtree todavía funciona, y la salida es idéntica, al menos por lo que puedo decir.


(PD: lingüistas, disculpen / corrijan cualquier error en el árbol anterior; han pasado uno o dos años desde mi curso de sintaxis).

Voy a presentar un alegato en nombre de forest. A pesar de que forest es extremadamente flexible y potente, también se puede utilizar de forma muy sencilla. Igual que qtree, utiliza una sintaxis simple y concisa que ‘se lee como un árbol’ pero encontré forestLa sintaxis es un poco más fácil de aprender. (Sin embargo, esto puede deberse a que aprendí qtree Primer me gusta tikz-qtree, te da todo el poder de TikZ pero, a diferencia de qtree, no tiene que cambiar los paquetes para usar ese poder como forest ya está usando TikZ debajo. Además, además de todo el poder de TikZ, tienes todo el poder de forest sí mismo. Y eso es muy significativo: soporte potente y especializado para dibujar árboles de todo tipo, de forma manual, automática y / o dinámica. Eche un vistazo a los ejemplos de este sitio para tener una idea de las posibilidades.

Para árboles simples, sin embargo, forest es muy simple.

Esta respuesta consta de dos partes. La primera parte se aplica a la versión actual de forest (versión 2). El segundo, que consiste en mi respuesta original, se aplica a la versión anterior de forest (versión 1). Los cambios no son muy buenos pero, si es nuevo en el paquete, le resultará más fácil seguirlo si lee la sección que se aplica a la versión que está utilizando sin modificaciones.


Actual forest: versión 2


Aquí hay un forest versión del código para el árbol publicado en la respuesta de Antal SZ.

documentclass[tikz,border=10pt]standalone
usepackage[linguistics]forest
begindocument
beginforest
  [IP
    [NP
     [Det
       [textitthe]
     ]
     [N$'$
       [N
         [textitpackage]
       ]
     ]
    ]
    [I$'$
      [I
        [textsc3sg.Pres
        ]
      ]
      [VP
        [V$'$
          [V
            [textitis]
          ]
          [AP
            [Deg
              [textitextremely]
            ]
            [A$'$
              [A
                [textitstraightforward]
              ]
              [CP
                [textitto wield, roof]
              ]
            ]
          ]
        ]
      ]
    ]
  ]
endforest
enddocument

La idea básica es que todos los nodos del árbol se encierran entre corchetes. El subárbol del nodo se incluye en los mismos corchetes, si tiene uno.

Tenga en cuenta que no hay puntos para los puntos de ramificación y que no es necesario dejar un espacio antes de un corchete de cierre. De hecho, el código anterior es equivalente a

beginforest
  [IP[NP[Det[textitthe]][N$'$[N[textitpackage]]]][I$'$[I[textsc3sg.Pres]][VP[V$'$[V[textitis]][AP[Deg[textitextremely]][A$'$[A[textitstraightforward]][CP[textitto wield, roof]]]]]]]]
endforest

Obviamente, esto es todo menos fácil de leer, de ahí mi preferencia por mucho espacio “innecesario”.

forest Sin embargo, no puede soportar una línea en blanco y deben evitarse.

Los árboles anteriores producen el siguiente resultado:

árbol

Cómo convertir un árbol en la especificación de soporte forest usos

Comience con la raíz y colóquela dentro de un forest medio ambiente y entre corchetes:

beginforest
  [IP% root
% rest of tree will go here
  ]
endforest

El resto del árbol consta de uno o más árboles más pequeños. Estos son subárboles del nodo raíz. En este caso, tenemos 2 subárboles, por lo que comenzamos con la raíz de cada subárbol y agregamos cada uno de ellos en su propio par de corchetes.

beginforest
  [IP% root
    [NP% root of subtree
% rest of subtree will go here
    ]
    [I$'$% root of subtree
% rest of subtree will go here
    ]
  ]
endforest

Luego puede trabajar en cada uno de los subárboles por turno y repetir la operación.

Estilos especiales

Como estamos interesados ​​en esta pregunta en árboles para lingüística, agregué la opción linguistics al cargar el paquete.

usepackage[linguistics]forest

Esto hace dos cosas: (1) carga el linguistics biblioteca, poniendo a disposición varios estilos de uso en lingüística (por ejemplo, el roof utilizado anteriormente); (2) cambia la apariencia predeterminada de los árboles.

Si solo quisiéramos que algunos árboles usaran los valores predeterminados de la biblioteca (quizás algunos de nuestros árboles son árboles lingüísticos y algunos son algún otro tipo de árbol), podríamos usar

usepackageforest
useforestlibrarylinguistics 

en el preámbulo. Entonces podríamos usar

forestapplylibrarydefaultslinguistics

dentro de un alcance TeX local en el cuerpo del documento para aplicar los valores predeterminados solo a los árboles seleccionados. Por ejemplo,

forestapplylibrarydefaultslinguistics
beginforest
  
endforest

beginforest
  
endforest

aplicaría lingustics por defecto al árbol dado por pero no a lo dado por .

Pero asumiremos que todos los árboles en nuestro documento actual son árboles lingüísticos por ahora.

Para hacer el techo triangular, solo agregamos , roof al nodo apropiado y forest aplica su estilo de techo triangular.

Si luego desea hacer árboles más complejos, también puede usar los estilos TikZ de la misma manera. Añadiendo , text=red a un nodo hará que el texto del nodo se vuelva rojo, por ejemplo.

     [N$'$, text=red
       [N
         [textitpackage]
       ]
     ]

nodo rojo

El estilo condicional ahorra escritura

También puede, si lo desea, guardar el cambio de fuente para cada nodo terminal. Si la mayoría de los nodos terminales deben estar en cursiva, puede decir

if n children=0% if the node doesn't have any children of its own
  font=itshape
,

Para aplicar este condicional a todo el árbol y, por lo tanto, en cursiva a todos los nodos terminales, podemos decir

  for tree=
    if n children=0
      font=itshape
    ,
  

después beginforest y antes de especificar el árbol en sí. Esto se conoce como el preámbulo del árbol.

Luego puede anular esto para el único nodo de pequeña capitalización, diciendo , font=scshape después de especificar el contenido del nodo.

Código completo para árbol revisado

documentclass[tikz,border=10pt]standalone
usepackage[linguistics]forest
begindocument
beginforest
  for tree=
    if n children=0
      font=itshape
    ,
  
  [IP
    [NP
     [Det
       [the]
     ]
     [N$'$
       [N
         [package]
       ]
     ]
    ]
    [I$'$
      [I
        [3sg.Pres, font=scshape]
      ]
      [VP
        [V$'$
          [V
            [is]
          ]
          [AP
            [Deg
              [extremely]
            ]
            [A$'$
              [A
                [straightforward]
              ]
              [CP
                [to wield, roof]
              ]
            ]
          ]
        ]
      ]
    ]
  ]
endforest
enddocument

Funciones adicionales seleccionadas

Una característica común solicitada para los árboles de lingüistas parece ser asegurar que los nodos terminales estén alineados.

forest le permite especificar que los nodos deben estar alineados en un común tier. Para usar esta función, simplemente escriba , tier= después de que se especifica el contenido del nodo.

Aquí hay un ejemplo extremo:

alineación de nivel extrema

beginforest
  for tree=
    fit=band,% spaces the tree out a little to avoid collisions
  
  [things
    [cabbages, tier=vegetables
      [peaches, tier=fruits]
    ]
    [kings, tier=aristocrats]
    [sealing wax
      [queens, tier=aristocrats
        [carrots, tier=vegetables]
        [pineapple, tier=fruits]
        [aubergine, tier=vegetables]
      ]
    ]
  ]
endforest

En el caso de nuestro árbol de lingüistas, solo queremos que los nodos terminales estén alineados. Ya estamos diciendo que los queremos en cursiva, por lo que podemos agregar una especificación de nivel allí.

Nosotros tuvimos

  for tree=
    if n children=0
      font=itshape
    ,
  

Ahora cambiamos esto a lo siguiente:

  for tree=
    if n children=0
      font=itshape,
      tier=terminal,
    ,
  

y el árbol cambia dramáticamente:

nodos terminales alineados


Más temprano forest: versión 1


Aquí hay un forest versión del código para el árbol publicado en la respuesta de Antal SZ.

documentclass[tikz,border=10pt]standalone
usepackageforest
begindocument
beginforest
  [IP
    [NP
     [Det
       [textitthe]
     ]
     [N$'$
       [N
         [textitpackage]
       ]
     ]
    ]
    [I$'$
      [I
        [textsc3sg.Pres
        ]
      ]
      [VP
        [V$'$
          [V
            [textitis]
          ]
          [AP
            [Deg
              [textitextremely]
            ]
            [A$'$
              [A
                [textitstraightforward]
              ]
              [CP
                [textitto wield, triangle]
              ]
            ]
          ]
        ]
      ]
    ]
  ]
endforest
enddocument

La idea básica es que todos los nodos del árbol se encierran entre corchetes. El subárbol del nodo se incluye en los mismos corchetes, si tiene uno.

Tenga en cuenta que no hay puntos para los puntos de ramificación y que no es necesario dejar un espacio antes de un corchete de cierre. De hecho, el código anterior es equivalente a

beginforest
  [IP[NP[Det[textitthe]][N$'$[N[textitpackage]]]][I$'$[I[textsc3sg.Pres]][VP[V$'$[V[textitis]][AP[Deg[textitextremely]][A$'$[A[textitstraightforward]][CP[textitto wield, triangle]]]]]]]]
endforest

Obviamente, esto es todo menos fácil de leer, de ahí mi preferencia por mucho espacio “innecesario”.

forest Sin embargo, no puede soportar una línea en blanco y deben evitarse.

Los árboles anteriores producen el siguiente resultado:

árbol

Cómo convertir un árbol en la especificación de soporte forest usos

Comience con la raíz y colóquela dentro de un forest medio ambiente y entre corchetes:

beginforest
  [IP% root
% rest of tree will go here
  ]
endforest

El resto del árbol consta de uno o más árboles más pequeños. Estos son subárboles del nodo raíz. En este caso, tenemos 2 subárboles, por lo que comenzamos con la raíz de cada subárbol y agregamos cada uno de ellos en su propio par de corchetes.

beginforest
  [IP% root
    [NP% root of subtree
% rest of subtree will go here
    ]
    [I$'$% root of subtree
% rest of subtree will go here
    ]
  ]
endforest

Luego puede trabajar en cada uno de los subárboles por turno y repetir la operación.

Estilos especiales

Para hacer el techo triangular, solo agregamos , triangle al nodo apropiado y forest aplica su estilo de raíz triangular.

Si luego desea hacer árboles más complejos, también puede usar los estilos TikZ de la misma manera. Añadiendo , text=red a un nodo hará que el texto del nodo se vuelva rojo, por ejemplo.

     [N$'$, text=red
       [N
         [textitpackage]
       ]
     ]

nodo rojo

Ramas para lógicos y lingüistas

Incluso los árboles simples de lógicos y lingüistas probablemente necesiten un poco de estilo para verse bien. En particular, los árboles suelen tener ramas que comienzan en un punto común debajo del nodo principal y se extienden hasta un punto por encima del secundario. Aunque esto no es predeterminado, podemos implementarlo diciendo

parent anchor=south,% start branches beneath the parent
child anchor=north,% end branches above the child

Para aplicar esto a todo el árbol, podemos decir

beginforest
  for tree=
    parent anchor=south,
    child anchor=north,
  
  [IP
    ...
  ]
endforest

sucursales para lógicos y lingüistas

El estilo condicional ahorra escritura

También puede, si lo desea, guardar el cambio de fuente para cada nodo terminal. Si la mayoría de los nodos terminales deben estar en cursiva, puede decir

if n children=0% if the node doesn't have any children of its own
  font=itshape
,

Luego puede anular esto para el único nodo de pequeña capitalización, diciendo , font=scshape después de especificar el nodo contenido.

Código completo para árbol revisado

documentclass[tikz,border=10pt,multi]standalone
usepackageforest
begindocument
beginforest
  for tree=
    parent anchor=south,
    child anchor=north,
    if n children=0
      font=itshape
    ,
  
  [IP
    [NP
     [Det
       [the]
     ]
     [N$'$
       [N
         [package]
       ]
     ]
    ]
    [I$'$
      [I
        [3sg.Pres, font=scshape]
      ]
      [VP
        [V$'$
          [V
            [is]
          ]
          [AP
            [Deg
              [extremely]
            ]
            [A$'$
              [A
                [straightforward]
              ]
              [CP
                [to wield, triangle]
              ]
            ]
          ]
        ]
      ]
    ]
  ]
endforest
enddocument

Funciones adicionales seleccionadas

Una característica común solicitada para los árboles de lingüistas parece ser asegurar que los nodos terminales estén alineados.

forest le permite especificar que los nodos deben estar alineados en un común tier. Para usar esta función, simplemente escriba , tier= después de que se especifica el contenido del nodo.

Aquí hay un ejemplo extremo:

alineación de nivel extrema

beginforest
  for tree=
    parent anchor=south,
    child anchor=north,
    fit=band,% spaces the tree out a little to avoid collisions
  
  [things
    [cabbages, tier=vegetables
      [peaches, tier=fruits]
    ]
    [kings, tier=aristocrats]
    [sealing wax
      [queens, tier=aristocrats
        [carrots, tier=vegetables]
        [pineapple, tier=fruits]
        [aubergine, tier=vegetables]
      ]
    ]
  ]
endforest

En el caso de nuestro árbol de lingüistas, solo queremos que los nodos terminales estén alineados. Ya estamos diciendo que los queremos en cursiva, por lo que podemos agregar una especificación de nivel allí.

Nosotros tuvimos

  for tree=
    parent anchor=south,
    child anchor=north,
    if n children=0
      font=itshape
    ,
  

Ahora cambiamos esto a lo siguiente:

  for tree=
    parent anchor=south,
    child anchor=north,
    if n children=0
      font=itshape,
      tier=terminal,
    ,
  

y el árbol cambia dramáticamente:

nodos terminales alineados

Para un árbol simple, no “gráfico”, puede utilizar el dirtree paquete:

documentclassarticle
usepackagedirtree
begindocument

dirtree%
.1 debug.
.2 filename.
.2 modules.
.3 module.
.3 module.
.3 module.
.2 level.


enddocument

sucio

Acuérdate de que tienes la opción de interpretar si te ayudó.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *