防止在Mathematica 8中自动布局Graph []对象

时间:2011-05-09 14:49:19

标签: wolfram-mathematica mathematica-8

某些类型的对象在Mathematica中具有特殊的输入/输出格式。这包括Graphics,光栅图像,以及Mathematica 8中的图形(Graph[])。不幸的是,大型图形可能需要很长时间才能实现可视化,这比我在交互式工作中对其进行的大多数其他操作要长得多。

如何阻止StandardForm和TraditionalForm中Graph[]个对象的自动布局,并将它们显示为例如-Graph-,最好保留输出的可解释性(可能使用Interpretation?)。我认为这将涉及以某种方式更改Format和/或MakeBoxes,但我没有成功实现此功能。

我想以可逆的方式执行此操作,并且最好定义一个函数,该函数在应用于Graph对象(与GraphPlot不同时将返回原始交互式图形显示,这是FormatValues不互动)。

在相关的说明中,有没有办法检索与某些符号关联的Format / MakeBoxes定义? Graph是一个相关函数,但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) 为空。

示例会话

{{1}}

3 个答案:

答案 0 :(得分:2)

虽然我没有使用Mathematica 8试试这个,但有一种可能性就是使用这个结构:

Unprotect[Graph]

MakeBoxes[g_Graph, StandardForm] /; TrueQ[$short] ^:= 
 ToBoxes@Interpretation[Skeleton["Graph"], g]

$short = True;

之后,Graph对象应以Skeleton形式显示,设置$short = False应恢复默认行为。

希望这可以自动切换:

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

Mark对修改Graph的担忧导致我考虑使用$PrePrint的选项。我认为这也应该防止缓慢的布局步骤发生。假设您尚未将$PrePrint用于其他内容,则可能更为可取。

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

$short = True

另外方便的是,至少Graphics(我再次无法在v7中使用Graph进行测试),您只需使用Print即可获得图片。在这里,用Graphics:

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

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

然后

Print[g]

enter image description here

我离开了$short测试,以便通过全局符号轻松切换,但可以将其留下并使用:

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

然后使用$PrePrint = .重置默认功能。

答案 1 :(得分:2)

您可以使用GraphLayout的{​​{1}}选项以及图构造函数来抑制渲染。仍然可以使用Graph显示图表。请尝试以下

GraphPlot

enter image description here

为了让您的工作更轻松,您可以使用{gr1, gr2, gr3} = {RandomGraph[{100, 120}, GraphLayout -> None], PetersenGraph[10, 3, GraphLayout -> None], Graph[{1 -> 2, 2 -> 3, 3 -> 1}, GraphLayout -> None]} 为您感兴趣的所有图表构建器设置SetOptions选项GraphLayout

答案 2 :(得分:1)

您是否尝试过简单地抑制输出?如果你这样做,我认为V8的Graph命令不会做任何布局。为了探索这一点,我们可以生成大量边缘列表,并比较graph[edges];Graph[edges];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

惰性graph命令当然是最快的。 Graph命令需要更长的时间,但只要GraphPlot命令就没有。因此,在我看来,Graph实际上并不像GraphPlot那样计算布局。

合乎逻辑的问题是,Graph花费了多少时间。让我们在一个简单的例子中检查InputForm Graph输出:

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]}]

请注意,图表的顶点已经确定,我认为这是Graph正在做的事情。事实上,在第一个例子中计算Graph[edges]所花费的时间,与我能想到的最快方式相比:

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

这花了0.087045秒。