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

发布于 2024-11-06 10:54:29 字数 841 浏览 1 评论 0原文

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

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

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

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

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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

哆兒滾 2024-11-13 10:54:29

尽管我没有 Mathematica 8 来尝试此操作,但一种可能性是使用此构造:

Unprotect[Graph]

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

$short = True;

之后,Graph 对象应以骨架形式显示,并设置 $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 获取图形。此处以图形显示:

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

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

然后

Print[g]

在此处输入图像描述

我将 $short 测试留在原处通过全局符号轻松切换,但可以将其省略并使用:

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

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

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]

enter image description here

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.

潦草背影 2024-11-13 10:54:29

您可以使用GraphGraphLayout选项以及图形构造函数来抑制渲染。仍然可以使用 GraphPlot 来可视化图形。尝试以下

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

在此处输入图像描述

为了使工作更轻松,您可以使用 SetOptions对于您感兴趣的所有图形构造函数,将 GraphLayout 选项设置为 None

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

enter image description here

In order to make working easier, you can use SetOptions to set GraphLayout option to None for all graph constructors you are interested in.

凉城 2024-11-13 10:54:29

您是否尝试过简单地抑制输出?我不认为 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

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

逻辑问题是,Graph 将时间花在什么上。让我们在一个简单的情况下检查 Graph 输出的 InputForm

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 秒。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文