2011-11-13 8 views
20

¿Es posible y práctico para Mathematica para dibujar algo como esto (ser creado por Graphviz):¿Cómo dibujar el diagrama de estado clásico usando Mathematica?

enter image description here

Esto es lo mejor que puedo conseguir (pero la forma y el estilo no son satisfactorios):

enter image description here

Código:

GraphPlot[{{A -> C, "go"}, {C -> B, "gone"}, {C -> D, 
    "went"}, {C -> C, "loop"}}, VertexLabeling -> True, 
DirectedEdges -> True] 
+0

No hay ninguna razón por la que no se puede utilizar para dibujar primitivas gráficas algo como esto. ¿Está solicitando una solución de diseño automático? –

+1

@ Mr.Wizard Sí, estoy buscando primitivas de mayor nivel para dibujar diagramas de estado complicados. No sé si Mathematica lo proporciona. Busqué en la documentación y revisé las opciones de la función "GraphPlot" y terminé con el código anterior. – Ning

+0

¿Por qué aceptó mi respuesta? La forma sigue mal. Te lo agradezco, pero creo que deberías esperar una mejor respuesta. –

Respuesta

21

Puede hacer algo como esto usando VertexRenderingFunction.

GraphPlot[{{A -> C, "go"}, {C -> B, "gone"}, {C -> D, "went"}, {C -> C, "loop"}}, 
DirectedEdges -> True, 
VertexRenderingFunction -> ({{White, Disk[#, 0.15]}, 
    AbsoluteThickness[2], Circle[#, 0.15], 
    If[MatchQ[#2, A | B], Circle[#, 0.12], {}], Text[#2, #]} &)] 

enter image description here


Método versión de febrero de el año 2015

Para preservar la capacidad de reorganizar de forma interactiva el gráfico con las herramientas de dibujo (doble clic) uno debe mantener los gráficos de vértices en el interior de GraphicsComplex, con índices en lugar de coordenadas. Creo que uno podría hacer esto desde VertexRenderingFunction usando una variable de incremento, pero parece más fácil y posiblemente más robusto hacerlo con el postprocesamiento. Esto funciona en las versiones 7 y 10 del Mathematica, presumiblemente, 8 y 9, así:

GraphPlot[ 
    {{A -> C, "go"}, {C -> B, "gone"}, {C -> D, "went"}, {C -> C, "loop"}}, 
    DirectedEdges -> True 
] /. 
Tooltip[Point[n_Integer], label_] :> 
    {{White, Disk[n, 0.15]}, 
    Black, AbsoluteThickness[2], Circle[n, 0.15], 
    If[MatchQ[label, A | B], Circle[n, 0.12], {}], Text[label, n]} 

enter image description here

+0

¿Hay una "VertexLabelingFunction"? – Ning

+0

@Ning Tuve un error en mi respuesta; Quise decir 'VertexRenderingFunction'. No creo que haya un Vertex ** Labeling * Funcion. Además, noté que tenía un defecto en mis gráficos en relación con su ejemplo original con respecto a los tamaños de círculo. Corregí esta es la segunda versión que acabo de poner. –

5

No hay necesidad de colocación interactiva de obtener sus vértices en el lugar deseado como sugiere mr.Wizard en his answer. Se puede utilizar para ese VertexCoordinateRules:

GraphPlot[{{A -> C, "go"}, {C -> B, "gone"}, {C -> D, "went"}, {C -> C, "loop"}}, 
    DirectedEdges -> True, 
    VertexRenderingFunction -> 
      ({{White, Disk[#, 0.15]}, AbsoluteThickness[2], Circle[#, 0.15], 
      If[MatchQ[#2, A | B], Circle[#, 0.12], {}], Text[#2, #]} &), 
    VertexCoordinateRules -> 
      {A -> {0, 0}, C -> {0.75, 0},B -> {1.5, 0.25}, D -> {1.5, -0.25}} 
] 

enter image description here

+0

No quise decir que era necesario tener un diseño interactivo, pero puedo ver cómo se puede inferir. Este método también funciona. ¿Conoces alguna forma de preservar la capacidad de edición además de una variación del truco que utilicé? –

+0

@ Mr.Wizard No veo una salida fácil. –

Cuestiones relacionadas