2011-05-09 21 views
6

某些類型的對象在Mathematica中有特殊的輸入/輸出格式。這包括Graphics,光柵圖像,以及從Mathematica 8起的圖(Graph[])。不幸的是,大型圖形可能需要很長時間才能可視化,這比我在交互式工作中進行的大多數其他操作要長得多。阻止Mathematica中Graph []對象的自動佈局8

如何防止在StandardForm和TraditionalForm中自動佈局Graph[]對象,並將它們顯示爲例如。 -Graph-,最好保留輸出的可解釋性(可能使用Interpretation?)。我認爲這將涉及以某種方式更改Format和/或MakeBoxes,但我沒有成功完成此項工作。

我想以可逆的方式做到這一點,並且最好定義一個函數,該函數在應用於Graph對象(與GraphPlot不互不相同)時返回原始交互式圖形顯示。

在相關說明中,有沒有辦法檢索與特定符號關聯的格式/製作框定義? 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) 
+0

索博,請嘗試我的' $ PrePrint'版本並告訴我它是否有效。 – 2011-05-11 16:09:48

回答

2

雖然我沒有數學8嘗試這種在,一種可能性是使用此結構:

Unprotect[Graph] 

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

$short = True; 

之後,一個Graph對象應顯示在骷髏形式中,並且設置$short = False應該恢復默認行爲。

希望這個工程,自動切換:

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

馬克的有關修改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] 

enter image description here

我通過一個全球性的符號留在原地,方便切換的$short測試,但一個能離開它,和使用:

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

然後用$PrePrint = .來重置默認功能。

+0

它似乎工作。 'interactiveGraphPlot'給出了原始的,但是使用交互功能將它恢復爲<>表單。 (實際上,這部分並不重要)。我應該學習'Format'和'MakeBoxes'是如何工作的,以及它們(還有'ToBoxes')之間的區別。例如。爲什麼沒有修改的'MakeBoxes'不會返回一個交互對象,'ToBoxes'呢,還需要在這裏修改'MakeBoxes'? – Szabolcs 2011-05-09 16:59:49

+0

我不認爲我明白你說的是什麼,但是因爲'MakeBoxes'的輸出可能被認爲是Boxes,所以需要'ToBoxes';將其留出將導致錯誤。 MakeBoxes默認是做(類似於)ToBoxes,除非你給它特殊的規則,像這樣。 – 2011-05-09 17:30:45

+0

@Szabolcs感謝接受 – 2011-05-11 14:45:21

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命令需要更長的時間,但沒有接近與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秒。

+0

'圖表'本身不會執行佈局,它的交互式輸出確實如此。這就像等待渲染圖形一樣。因此,您甚至無法使用「定時」或「絕對定時」來測量此時間。是的,我可以壓制輸出,但總的來說,我並不想這麼做,偶爾也會忘記它:我不想因爲不得不因爲忘記壓制輸出而受到懲罰等待半分鐘或更長時間。 – Szabolcs 2011-05-10 08:47:17

+0

事實上,現在我開始懷疑它是佈局算法還是需要很長時間才能完成的圖形渲染...... – Szabolcs 2011-05-10 08:47:54

+0

我已經編輯我的示例以正確測量時間,即使有一些前端事件正在進行中本應該是微不足道的。我認爲時間表仍然支持我的結論。我同意圖形渲染可能比頂點佈局更昂貴。 – 2011-05-10 12:34:38

2

您可以使用GraphGraphLayout選項以及圖構造函數來抑制渲染。圖形仍可通過GraphPlot進行可視化。請嘗試以下

{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

爲了讓工作更輕鬆,你可以使用SetOptionsGraphLayout選擇你感興趣的所有圖形構造函數設置爲None