Some types of objects have special input/output formatting in Mathematica. This includes Graphics
, raster images, and, as of Mathematica 8, graphs (Graph[]
). Unfortunately large graphs may take a very long time to visualize, much longer than most other operations I'm doing on them during interactive work.
How can I prevent auto-layout of Graph[]
objects in StandardForm and TraditionalForm, and have them displayed as e.g. -Graph-
, preferably preserving the interpretability of the output (perhaps using Interpretation
?). I think this will involve changing Format
and/or MakeBoxes
in some way, but I was unsuccessful in getting this to work.
I would like to do this in a reversible way, and preferably define a function that will return the original interactive graph display when applied to a Graph
object (not the same as GraphPlot
, which is not interactive).
On a related note, is there a way to retrieve Format/MakeBoxes definitions associated with certain symbols? FormatValues
is one relevant function, but it is empty for Graph
.
Sample session:
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)
Though I do not have Mathematica 8 to try this in, one possibility is to use this construct:
Unprotect[Graph]
MakeBoxes[g_Graph, StandardForm] /; TrueQ[$short] ^:=
ToBoxes@Interpretation[Skeleton["Graph"], g]
$short = True;
Afterward, a Graph
object should display in Skeleton form, and setting $short = False
should restore default behavior.
Hopefully this works to automate the switching:
interactiveGraphPlot[g_Graph] := Block[{$short}, Print[g]]
Mark's concern about modifying Graph
caused me to consider the option of using $PrePrint
. I think this should also prevent the slow layout step from taking place. It may be more desirable, assuming you are not already using $PrePrint
for something else.
$PrePrint =
If[TrueQ[$short], # /. _Graph -> Skeleton["Graph"], #] &;
$short = True
Also conveniently, at least with Graphics
(again I cannot test with Graph
in v7) you can get the graphic with simply Print
. Here, shown with Graphics:
g = Plot[Sin[x], {x, 0, 2 Pi}]
(* Out = <<"Graphics">> *)
Then
Print[g]
I left the $short
test in place for easy switching via a global symbol, but one could leave it out and use:
$PrePrint = # /. _Graph -> Skeleton["Graph"] &;
And then use $PrePrint = .
to reset the default functionality.
You can use GraphLayout
option of Graph
as well as graph-constructors to suppress the rendering. A graph can still be visualized with GraphPlot
. Try the following
{gr1, gr2, gr3} = {RandomGraph[{100, 120}, GraphLayout -> None],
PetersenGraph[10, 3, GraphLayout -> None],
Graph[{1 -> 2, 2 -> 3, 3 -> 1}, GraphLayout -> None]}
In order to make working easier, you can use SetOptions
to set GraphLayout
option to None
for all graph constructors you are interested in.
Have you tried simply suppressing the output? I don't think that V8's Graph
command does any layout, if you do so. To explore this, we can generate a large list of edges and compare the timings of graph[edges];
, Graph[edges];
, and 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
The inert graph
command is, of course, the fastest. The Graph
command takes much longer, but no where near as long as the GraphPlot
command. Thus, it seems to me that Graph
is not, in fact, computing the layout, as GraphPlot
does.
The logical question is, what is Graph
spending it's time on. Let's examine the InputForm
of Graph
output in a simple case:
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]}]
Note that the vertices of the graph have been determined and I think this is what Graph
is doing. In fact, the amount of time it took to compute Graph[edges]
in the first example, comparable to the fastest way that I can think to do this:
Union[Sequence @@@ edges]; // Timing
This took 0.087045 seconds.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With