禁用圖形更新與交互我有一個包含 ox、oy、dx 和 dy 列的數據表。 出於演示目的,您可以假設所有列都是隨機的,公式為:Random Normal(0, 10)。 真正的問題是具有坐標列表的網絡。
我想在 (ox, oy) 和 (dx, dy) 之間畫線,我可以使用圖形生成器或圖形框來完成此操作(下面的示例)。 然而,每次交互時,JMP 都會重新繪製線條,這使我的可視化速度非常慢(數據表中有 >10 000 行)。 我通過向圖形腳本中的原點和目標坐標添加一個小的隨機部分來測試這一點,並且一旦有任何交互(例如,使用抓取工具並拖動畫布、調整軸、調整圖形大小、調整窗口大小),線條確實改變了。 有沒有辦法阻止 JMP 更新圖表並重新運行腳本?
我在 Graph Builder(我更喜歡使用這個平台)或 Graph Box 中找不到方法。 我找到了
<< Graph Updating( Per Mouse Up );
message 但它只有兩個選項;據我所知,沒有“不更新”選項。 另外,我認為該消息無論如何都不適用於 Graph Box。
這是一個最小的圖形框示例,可以繪製線條,但線條會隨著每次交互而更新:
New Window( "Example",
Graph Box(
Frame Size( 300, 300 ),
Pen Color( "Blue" );
o_x = :ox << Get Values();
o_y = :oy << Get Values();
d_x = :dx << Get Values();
d_y = :dy << Get Values();
For( i=1, i<=N Items(o_x), i++,
origin = Eval List({o_x[i]*Random Normal( 1, 0.1 ), o_y[i]*Random Normal( 1, 0.1 )});
destination = Eval List({d_x[i]*Random Normal( 1, 0.1 ), d_y[i]*Random Normal( 1, 0.1 )});
Line(origin, destination);
);
);
);提醒一下,我只是在該圖形框腳本中添加了隨機法線,只是為了查看線條是否正在重新計算。 真正的問題有固定的坐標。
額外問題:有沒有辦法在構建圖形框後添加線條? 我在示例中找不到它。 我推測它們可能不會隨著每次鼠標交互而更新,但無法測試它。
自動化和腳本編寫數據混合和清理大規模定制回复:通過交互禁用圖形更新這是一個非常有趣的想法。 不幸的是,對於 20K 點,路徑必須通過移動和線條,圖形更加掙扎,速度甚至更慢。
但我會記住這一點以應對未來的問題,因為我喜歡這樣的想法:從技術上講,這裡有一條路徑,並且圖形代碼中不需要循環。
回复:通過交互禁用圖形更新我不知道我可以像 JSL 中那樣進行矢量化。 所以謝謝你教我這個方法!
一旦我將隨機性計算移出圖形框,數字就不會更新,但這是誤導性的。 我加入隨機性只是為了讓自己相信 JMP 正在重新繪製圖表。 因此,雖然這種方法有效,但它並沒有完全達到我想要的效果。 當我將隨機性計算拉入圖形框中後,所有線條都靜止不動。 但我一路上確實學到了一些東西。 謝謝!
另外,我仍然必須循環繪製線條,因為我的線條不應該是連接路徑。 因此,我不能只創建一對 x 和 y 矩陣並將它們傳遞給 Line 或 Line Seg。
我使用您的代碼使其與我的數據表一起使用,如下所示。 我會將表格附加到此消息中,以防其他人需要此解決方案。
Names Default To Here( 1 );
// origin
o_x = :ox << Get As Matrix;
o_y = :oy << Get As Matrix;
// destination
d_x = :dx << Get As Matrix;
d_y = :dy << Get As Matrix;
n = N Items( o_x );
// plot segments
New Window( "Example",
gb = Graph Box(
Frame Size( 300, 300 ),
Pen Color( "Blue" );
seg_x = (o_x :*</img> J( n, 1, Random Normal( 1, 0.1 ) )) || (d_x :*</img> J( n, 1, Random Normal( 1, 0.1 ) ));
seg_y = (o_y :*</img> J( n, 1, Random Normal( 1, 0.1 ) )) || (d_y :*</img> J( n, 1, Random Normal( 1, 0.1 ) ));
For( i=1, i<=n, i++,
Line( seg_x[i, -1], seg_y[i, -1] )
)
)
);
回复:通過交互禁用圖形更新恕我直言,JMP 確實非常_非常_需要更新此功能。我已經多次遇到這個問題,而且很簡單,沒有有效的解決方法。JMP 應該僅在發生變化(例如圖形大小)時重新運行圖形腳本,而不僅僅是在滾動/更改窗口大小時重新運行圖形腳本。
話雖如此,我發現執行此類操作的最快方法如下所示。我創建了一個 SVG 路徑(根據我的經驗,這無疑是在 JMP 中渲染複雜路徑的最快方法),並有一個哨兵來確定是否重建路徑。作為示例,我添加了一個強制重建路徑的按鈕。
希望這會有所幫助,但更好的是 JMP 開發人員提供一個與所有其他顯示管理器系統(包括多線程、信號/槽、回調等)一樣運行的系統。
我還嘗試過使用此方法來獲取所需渲染的圖像,檢查圖形框的大小,如果大小未更改,則使用保存的圖像作為要顯示的內容。這就是 JMP 應該做的事情,並且永遠不應該設置為在每個可能的機會積極執行圖形腳本。然而,我對這種方法的運氣不佳,因為 JMP 沒有提供使該方法正常工作所需的工具
self = New Namespace();
self:table = Current Data Table();
self:redraw = 1;
self:path = "";
self:build path = Function( {},
{Default Local},
self:path = "";
For Each Row( self:table,
self:path ||= Eval Insert( "\[M^:ox * Random Normal( 1, 0.1 )^,^oy * Random Normal( 1, 0.1)^ L^dx * Random Normal( 1, 0.1 )^,^:dy * Random Normal( 1, 0.1 )^]\" )
);
);
Eval( Eval Expr(
New Window( "Example",
<<ON close=""></ON>
回复:通過交互禁用圖形更新我認為問題在於,每當有更改時,框架框都會自動更新,因此最好在渲染之前進行所有更改。 此外,您還可以對操作進行矢量化以提高速度,而不是使用 For() 函數顯式迭代。 圖形片段也提供了一些優點,但目前它們的記錄很少。
看看這個方法:
Names Default to Here( 1 );
// origin
o_x = :ox << Get As Matrix;
o_y = :oy << Get As Matrix;
// destination
d_x = :dx << Get As Matrix;
d_y = :dy << Get As Matrix;
n = N Items( o_x );
// vectorize for line segments
seg = (o_x :*</img> J( n, 1, Random Normal( 1, 0.1 ))) || (o_y f:* J( n, 1, Random Normal( 1, 0.1 ))) ||
(d_x :*</img> J( n, 1, Random Normal( 1, 0.1 ))) || (d_y f:* J( n, 1, Random Normal( 1, 0.1 )));
// plot segments
New Window( "Example",
gb = Graph Box(
Frame Size( 300, 300 ),
Pen Color( "Blue" );
Line Seg( seg );
)
);
// later, update seg, then send gb << Reshow message to graph box
(我沒有你的數據表,所以我無法測試它,但它仍然應該說明該方法。)