2011-05-09 6 views
6

Algunos tipos de objetos tienen un formato especial de entrada/salida en Mathematica. Esto incluye Graphics, imágenes ráster y, a partir de Mathematica 8, gráficos (Graph[]). Lamentablemente, los gráficos grandes pueden tardar mucho tiempo en visualizarse, mucho más que la mayoría de las otras operaciones que realizo durante el trabajo interactivo.Impedir el diseño automático de objetos Graph [] en Mathematica 8

¿Cómo puedo evitar el diseño automático de objetos Graph[] en StandardForm y TraditionalForm, y que se muestren como p. Ej. -Graph-, preferiblemente preservando la interpretabilidad de la salida (tal vez usando Interpretation?). Creo que esto implicará cambiar Format y/o MakeBoxes de alguna manera, pero no tuve éxito en hacer que esto funcione.

Me gustaría hacer esto de forma reversible, y preferiblemente definir una función que devolverá la visualización del gráfico interactivo original cuando se aplica a un objeto Graph (no es lo mismo que GraphPlot, que no es interactivo).

En una nota relacionada, ¿hay alguna manera de recuperar las definiciones de Format/MakeBoxes asociadas con ciertos símbolos? FormatValues es una función relevante, pero está vacía para Graph.

sesión de la muestra:

In[1]:= Graph[{1->2, 2->3, 3->1}] 
Out[1]= -Graph- 

In[2]:= interactiveGraphPlot[%] (* note that % works *) 
Out[2]= (the usual interactive graph plot should be shown here) 
+0

Szabolcs, por favor, intente mi ' Versión $ PrePrint' y dime si funciona. –

Respuesta

2

Aunque no tengo Mathematica 8 para tratar esto en, una posibilidad es utilizar esta construcción:

Unprotect[Graph] 

MakeBoxes[g_Graph, StandardForm] /; TrueQ[$short] ^:= 
[email protected][Skeleton["Graph"], g] 

$short = True; 

Después, un objeto Graph debe mostrar en forma de esqueleto, y establecer $short = False debe restaurar el comportamiento predeterminado.

Esperamos que esto funciona para automatizar la conmutación: preocupación

interactiveGraphPlot[g_Graph] := Block[{$short}, Print[g]] 

de Mark acerca de cómo modificar Graph me llevó a considerar la opción de utilizar $PrePrint. Creo que esto también debería evitar que se produzca el paso de diseño lento. Puede ser más conveniente, suponiendo que ya no esté usando $PrePrint para otra cosa.

$PrePrint = 
    If[TrueQ[$short], # /. _Graph -> Skeleton["Graph"], #] &; 

$short = True 

También convenientemente, al menos con Graphics (de nuevo no puedo probar con Graph en v7) se puede obtener la gráfica con simplemente Print. A continuación, se muestra con gráficos:

g = Plot[Sin[x], {x, 0, 2 Pi}] 

(* Out = <<"Graphics">> *) 

Entonces

Print[g] 

enter image description here

Salí de la prueba $short en su lugar para cambiar fácilmente a través de un símbolo global, pero uno podría dejarlo fuera y uso:

$PrePrint = # /. _Graph -> Skeleton["Graph"] &; 

Y a continuación, utilice $PrePrint = . para restablecer la funcionalidad predeterminada.

+0

Parece que funciona. 'interactiveGraphPlot' proporciona el original, pero el uso de las características interactivas lo revierte al formulario <>. (En realidad, esta parte no era tan importante de todos modos.) Debo aprender cómo funcionan 'Format' y' MakeBoxes', y la diferencia entre ellos (y también 'ToBoxes'). P.ej. ¿Por qué es que los 'MakeBoxes' no modificados NO devuelven un objeto interactivo,' ToBoxes' sí, pero uno necesita modificar 'MakeBoxes' aquí? – Szabolcs

+0

No creo entender lo que dijo, pero 'ToBoxes' es necesario porque se espera que la salida de' MakeBoxes' sea Cajas; dejarlo fuera resultará en un error. MakeBoxes por defecto está haciendo (algo así como) ToBoxes a menos que le des reglas especiales, como esta. –

+0

@Szabolcs gracias por aceptar –

1

¿Has probado simplemente suprimir la salida? No creo que el comando Graph del V8 haga ningún diseño, si lo haces. Para explorar esto, podemos generar una lista grande de bordes y comparar los tiempos de graph[edges];, Graph[edges]; y GraphPlot[edges];

In[23]:= SeedRandom[1]; 
edges = Union[Rule @@@ (Sort /@ 
     RandomInteger[{1, 5000}, {50000, 2}])]; 

In[25]:= t = AbsoluteTime[]; 
graph[edges]; 

In[27]:= AbsoluteTime[] - t 

Out[27]= 0.029354 

In[28]:= t = AbsoluteTime[]; 
Graph[edges]; 

In[30]:= AbsoluteTime[] - t 

Out[30]= 0.080434 

In[31]:= t = AbsoluteTime[]; 
GraphPlot[edges]; 

In[33]:= AbsoluteTime[] - t 

Out[33]= 4.934918 

El comando inerte es, por supuesto, el más rápido. El comando Graph lleva mucho más tiempo, pero no tan lejos como el comando GraphPlot. Por lo tanto, me parece que Graph no está, de hecho, computando el diseño, como lo hace GraphPlot.

La pregunta lógica es, ¿en qué está gastando el tiempo Graph? Examinemos el InputForm de Graph de salida en un caso simple:

Graph[{1 -> 2, 2 -> 3, 3 -> 1, 1 -> 4}] // InputForm 

Out[123]//InputForm= 
    Graph[{1, 2, 3, 4}, 
     {DirectedEdge[1, 2], 
     DirectedEdge[2, 3], 
     DirectedEdge[3, 1], 
     DirectedEdge[1, 4]}] 

Tenga en cuenta que se han determinado los vértices del grafo, y creo que esto es lo que está haciendo Graph. De hecho, la cantidad de tiempo que tomó para calcular Graph[edges] en el primer ejemplo, comparable a la forma más rápida que se me ocurre hacer esto:

Union[Sequence @@@ edges]; // Timing 

Esto tomó 0.087045 segundos.

+0

'Graph' en sí no hace el diseño, su salida interactiva sí. Es como esperar a que se rendericen los gráficos. Por lo tanto, ni siquiera puedes medir esta vez usando 'Timing' o' AbsoluteTiming'. Sí, puedo suprimir la salida, pero el punto es que realmente no quiero molestarme en hacerlo, y de todos modos lo olvidaré ocasionalmente: no quiero ser castigado por olvidarme de suprimir la salida al tener que espere medio minuto o más. – Szabolcs

+0

De hecho, ahora comencé a preguntarme si es el algoritmo de diseño o la representación gráfica lo que tarda tanto en completarse ... – Szabolcs

+0

He editado mi ejemplo para medir correctamente el tiempo, aunque hay algunas cosas de la interfaz que se suponía que era insignificante. Creo que los tiempos aún respaldan mis conclusiones. Estoy de acuerdo en que la renderización de gráficos es más costosa que el diseño de vértices. –

2

Puede usar la opción GraphLayout de Graph, así como los constructores de gráficos para suprimir la representación. Un gráfico aún se puede visualizar con GraphPlot. Pruebe lo siguiente

{gr1, gr2, gr3} = {RandomGraph[{100, 120}, GraphLayout -> None], 
    PetersenGraph[10, 3, GraphLayout -> None], 
    Graph[{1 -> 2, 2 -> 3, 3 -> 1}, GraphLayout -> None]} 

enter image description here

Con el fin de hacer el trabajo más fácil, puede utilizar SetOptions para establecer GraphLayout opción de None para todos los constructores de gráficos que le interesan.

Cuestiones relacionadas