2011-11-13 8 views
20

E 'possibile e pratico per Mathematica per disegnare qualcosa di simile (essendo creato da Graphviz):Come disegnare il classico diagramma di stato usando Mathematica?

enter image description here

questo è il meglio che posso ottenere (ma la forma e lo stile non sono soddisfacenti):

enter image description here

Codice:

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

Non v'è alcuna ragione per cui non è possibile utilizzare primitive grafiche per disegnare qualcosa di simile. Stai richiedendo una soluzione di layout automatico? –

+1

@ Mr.Wizard Sì, sto cercando alcune primitive di livello superiore per disegnare diagrammi di stato complicati. Non so se Mathematica lo fornisce. Ho cercato nella documentazione e controllato le opzioni della funzione "GraphPlot" e ho finito con il codice sopra. – Ning

+0

Perché hai accettato la mia risposta? La forma è ancora sbagliata. Lo apprezzo, ma penso che dovresti aspettare una risposta migliore. –

risposta

21

Puoi fare qualcosa di simile 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


metodo aggiornato febbraio 2015

Per preservare la capacità di riorganizzare in modo interattivo il grafico con gli strumenti di disegno (doppio clic) si deve tenere la grafica di vertice all'interno di GraphicsComplex, con indici anziché coordinate. Credo che si possa fare questo da VertexRenderingFunction usando una variabile incrementale, ma sembra più facile possibilmente più robusto farlo con la post-elaborazione. Questo funziona nelle versioni 7 e 10 del Mathematica, presumibilmente 8 e 9 così:

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

Esiste una "VertexLabelingFunction"? – Ning

+0

@Ning Ho avuto un errore nella mia risposta; Intendevo 'VertexRenderingFunction'. Non credo ci sia un Vertex ** Labeling * Funcion. Inoltre, ho notato che avevo un difetto nella mia grafica rispetto al tuo esempio originale riguardo alle dimensioni dei cerchi. Ho corretto questa è la seconda versione che ho appena messo. –

5

Non c'è bisogno per il posizionamento interattivo per ottenere i vertici nella posizione desiderata come suggerisce mr.Wizard in his answer. È possibile utilizzare VertexCoordinateRules per questo:

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

Non volevo dire che fosse necessario avere un layout interattivo, ma posso vedere come ciò possa essere dedotto. Anche questo metodo funziona. Sei a conoscenza di un modo per preservare la modificabilità oltre a una variante dell'hack che ho usato? –

+0

@ Mr.Wizard Non vedo una via d'uscita facile. –

Problemi correlati