JSL - 生成循環遍歷具有不同變量的列的 -xy 圖
問候,
背景:我有一個非常大的數據集,是半導體器件特定射頻測試的輸出。 在此射頻測試期間,有多種不同的重要條件。 我有 3 個輸出,在 16 個不同的通道上以 6 種不同的測試狀態進行測試,這需要我生成 105 個不同的圖表。
示例:測試狀態 1 下通道 1 上的增益與頻率;測試狀態 1 下通道 2 上的增益與頻率,其中我有 15 個通道和 6 個測試狀態。
我在這些討論板上搜索了解決方案,我來的壁櫥是 2017 年開始的一個主題,標題為“如何通過JSL將JMP圖導出到PPT?
我嘗試合併此解決方案中使用的腳本來幫助我,我可以讓它製作所需數量的繪圖,但無法過濾掉特定的通道。
我想我很難傳達這一點,所以如果您需要澄清,請詢問。
謝謝
Summarize( dt, lstChannel = By( :channel ) );
gb = Graph Builder(
invisible,
Size( 1225, 952 ),
Show Control Panel( 0 ),
Variables(
X( :Name( "Freq _(GHz)" ) ),
Y( :Gain ),
Group X( :wafer_num ),
Overlay( :RowCol ) ),
Elements( Smoother( X, Y, Legend( 19 ) ) )
);
For( i = 1, i <= N Items( GroupBy ), i++,
gb << Local Data Filter(
columns(
:wafer_num,
:channel,
:RowCol),
Where( :channel == LstChannel[i] ) ),
// I would like to loop through the teststates as well
Where( :teststate == 1 ),
Mode( Show( 1 ), Include( 1 ) ) );
If( i == 1,
gb << Save Presentation( "$TEMP/jmp_example2.pptx" ),
gb << Save Presentation( "$TEMP/jmp_example2.pptx", Append )
);
gb << remove data filter;
);
Open( "$TEMP/jmp_example2.pptx" );回复:JSL - 生成循環遍歷具有不同變量的列的 -xy 圖我猜另外兩個沒有連接
回复:JSL - 生成循環遍歷具有不同變量的列的 -xy 圖感謝您提供的信息,它總是很有洞察力。 我確實認為你碰巧是對我幫助最大的人,這是非常偶然的。 看,我是一家鑄造廠的工業工程師,該工廠擁有非常高的混合小批量產品組合,並且我們進行了大量的射頻測試。 你提到的一切:
- 有一個已知的範圍,例如控製或規格限制,
- 需要縮放到 +/- k sigma 之類的值,
- 需要控製網格線,例如每0.5 sigma一條網格線,
- 標稱值很大但變化很小的數據,例如,均值是 1750222,stdev 是 0.000023,然後我繪製一個變換 Y 均值並找出一個好的比例並使用算法,gdinc.jsl
- 執行分析並確定數據是否高度傾斜或塊狀(聚集)。
這就是我想要實現的目標,我們正在測試,我們的客戶正在使用一些基於無數據的廣泛規格限制,因此我們試圖根據+/- 3 sigma 和+/- 4.5 sigma 以及隨附的上限和下限控制來確定規格限制限制。另一個例子是,當我詢問是否加寬分佈圖的 X 軸時,這是因為我們當前的規格限制是 LSL = 20 和 USL = 40。 這就是為什麼我是 JMP 的熱心擁護者,因為質量和流程實用程序中擁有出色的工具。
我對繪製多元數據分析知之甚少,但我會嘗試一下。
事實上,這次談話讓我明白了為什麼我又來到這裡。 我希望您能提供有關使用您為我提供的用於“Fix Y by X”分析的圖形生成器和分佈的相同繪圖方法的意見。 我覺得這是一個非常好的分析工具,因為我們可以看到數據集之間的差異(統計上),在我們的例子中是wafer_number。 當然,我使用每對學生的 T 檢驗來比較平均值...... 我嘗試即插即用,但對 dispacth 函數感到困惑。附件是數據表和我正在嘗試執行的操作的“保存到腳本”窗口以及輸出圖片。 再次強調,您的所有幫助都非常有幫助。
旁注,我問我的經理我是否可以參加深入的劇本寫作課程,他說可以,所以如果您有任何建議,請告訴我。 我在馬里蘭州巴利特莫爾地區。
英格
回复:JSL - 生成循環遍歷具有不同變量的列的 -xy 圖英,
您沒有具體說明您要尋找什麼。 我通常使用 JMP 默認縮放比例,如果我希望所有子組都使用相同的軸縮放比例,則可以使用類似以下內容的縮放比例。 該腳本將感興趣的變量命名為 ylist,但這可以應用於任何數字連續變量(列),甚至日期時間。技巧是讓 JMP 對所有內容進行縮放,然後將軸設置複製到表列,然後使用該列的任何圖形都將部署該比例。
Names Default to Here(1);
ylist = {"Sepal length", "Sepal width", "Petal length", "Petal width"};
dt = Open("$sample_data/iris.jmp");
//get common axis
for(i=1, i<=nitems(ylist), i++,
ovl = dt << Overlay Plot(Invisible,
Y( Column(dt,ylist[i]) ), //yaxis
Overlay( 0 )
);
report(ovl)[AxisBox(1)] << Save to Column Property;
ovl << close window;
);
//now the same axis will be applied to all sub groups
ovl1 = dt << OverlayPlot( Y( :Petal length ), Overlay(0), By(:Species) );
//all 3 subgroups have the same Y - axis
//ovl = dt << OverlayPlot( Y( eval(ylist) ), Overlay(0), By(:Species) );
僅當滿足以下條件時,我才會對軸進行自定義縮放:
- 有一個已知的範圍,例如控製或規格限制,
- 需要縮放到 +/- k sigma 之類的值,
- 需要控製網格線,例如每0.5 sigma一條網格線,
- 標稱值很大但變化很小的數據,例如,均值是 1750222,stdev 是 0.000023,然後我繪製一個變換 Y 均值並找出一個好的比例並使用算法,gdinc.jsl
- 執行分析並確定數據是否高度傾斜或塊狀(聚集)。
關於異常值檢測,我還沒有找到一種適用於所有數據的方法。 對於具有強右偏數據的單變量數據(例如零膨脹泊松),我喜歡使用修改後的 Lenth 方法:
- uscreen = 中位數 + k * (上 p 百分位數 -中位數) / Abs( 正態分位數(p) )
- lscreen = 中位數 - k * (中位數 - 下(p)百分位數/ Abs(正態分位數(p) )
- 其中 p 可以是 0.1(對於 10 和 90 個百分位數)或 p 可以是 0.25,那麼這將是修改後的偽 sigma,並且對於匯總數據,通常 k 位於 [4,6] 中。 有時對於原始數據,我使用更大的 k。
- 另外,我通常會篩選一個變量的所有數據,但如果按組差異很大,如果每組都有足夠的數據,我會按組篩選。
下面是按組計算篩選值的示例。 如果 vargroup 有 10 個組,則 uscreen 和 lscreen 是大小為 10 的向量,vg 是 10 個 vargroup 名稱的列表。
//Find global outliers by vargroup for raw measurement data
//Use an assymetric 6 pseudo-sigma, computed from the 10 & 90th percentiles.
summarize( vg=by(vargroup),
c=count,
q10=quantile(varvalue,.10),
q50=quantile(varvalue,.50),
q90=quantile(varvalue,.90)
);
uscr = q50 + 6*(q90-q50)/Normal quantile(0.9);
lscr = q50 - 6*(q50-q10)/Normal quantile(0.9);請注意:
- 沒有一種正確的方法,您應該始終與審查數據的方法一起審查這些方法。 異常值永遠不應該被忽視,因為它們可能會帶來重要的信息。
- 我經常使用 2 級篩選,特別是當我需要計算控制限、篩選繪製點和篩選限制時……控制限不應容納 5 和 6 西格瑪數據。
- 如果您要創建每週分析,請注意您每周可以獲得不同的篩選值。 您可能希望每週使用相同的限制進行一次大型分析。
- 對於多變量數據,您應該使用多變量屏幕。 參見圖形。 根據單變量限制,兩個明顯的異常值受到控制。 因此,如果數據強相關,則應使用相關篩選。 JMP 多元有一個很好的多元屏幕。

回复:JSL - 生成循環遍歷具有不同變量的列的 -xy 圖早上好摩根0 ,
之前您提到“有多種方法可以自動縮放,並自動查找和消除異常值”
我想知道你是否介意與我分享?我已經做了很多編碼,並且通過一些小的調整我已經接近結束了。
英格
回复:JSL - 生成循環遍歷具有不同變量的列的 -xy 圖首先,我的名字是大衛。 很高興見到你..
這是正確的,我確實想要一個統一的比例,並會根據最壞的情況調整 -x 軸。我很想听聽您關於刪除異常值的建議。 這些正在殺死我的數據集.. 我們正在電氣測試的部件要么通過,要么勉強通過,要么災難性地失敗。 那些發生災難性故障的部件需要拆除。
我將把您修改後的腳本插入我的主腳本中進行測試。 再次,我非常感激。 我還要感謝您的 Include().. 我的腳本的很大一部分只不過是 SQL 數據拉動字符串。 我們的數據庫有 8 個不同的表,我必鬚根據測試類型從中提取數據。
再次感謝你...
這是一個示例供參考:我有 9 個這樣的代碼,它們佔用了大量代碼行,這些代碼通過一個 Include() 解決了
testdata_HAY_DC_QQ_Data = Expr(
"
SELECT
t1.testdate,
t1.wafer_id,
t1.wafer_number,
t1.lot_number,
t2.rownum,
t2.colnum,
t2.die_id,
t2.part_name,
t2.testname,
t2.channel,
t7.header_id,
t7.idx,
t7.run_id,
t7.set_id,
t7.Supply_Name,
t7.Voltage,
t7.Current
FROM tst_master t1
LEFT OUTER JOIN tst_dataset_header t2
ON ( t2.run_id = t1.run_id )
LEFT OUTER JOIN tst_dc_data t7
ON ( t7.header_id = t2.header_id )
WHERE (t1.wafer_number LIKE '"||SelectedLot||"')
AND (t2.testname LIKE '"||SelectedTest||"')
"
);
回复:JSL - 生成循環遍歷具有不同變量的列的 -xy 圖
因根斯特恩,
我的印像是您希望所有發行版都具有相同的規模。JMP Distribution 通常能夠出色地將直方圖縮放到手頭的數據。 但是,當您繪製數據子集時,各個直方圖的比例將會不同。 如果您知道數據的範圍,則為 Lo、Hi 和 inc 分配值。如果您希望腳本處理其範圍可能隨流程更改而更改的數據或?那麼計算 Lo 和 Hi 以及 inc 應該是腳本的任務。
對於之前的腳本,我只使用了最小值和最大值不排除的數據。
Lo = Floor( Col 最小值 ( :test_2 * If( Excluded(), Empty(), 1 ) ) );
Hi = Ceiling( Col Maximum( :test_2 * If( Excluded(), Empty(), 1 ) ) );
下面,我做了另一個修改,在兩端留出一些空間:計算未排除數據的標準偏差並添加一半標準偏差。我提出比較分佈的替代圖表的原因之一是 JMP 將縮放到所有包含的數據,並且您可以看到通道和測試狀態的影響。
dt = Current Data Table();
jjrn3 = New Window( "Distribution [test_2]", <<JOURNAL></JOURNAL>
有多種方法可以自動縮放、自動查找和消除異常值。 我不願意強烈推薦,因為一個行業接受的方法可能另一個行業不接受;普通數據方法通常不適用於塊狀數據(聚類數據或空間數據)或零膨脹缺陷數據或可靠性數據。我的目的是指出可能適合你也可能不適合你的替代方案。
回复:JSL - 生成循環遍歷具有不同變量的列的 -xy 圖
是的,你的技能非常出色,我隨時都會上你的 JSL 課程。
不過問題很快.. 我用 gd_inc.jsl 運行它,這就是我得到的.. 我可以看到規模幾乎是完美的,但我的 15 個數據集有這 2 個差異。 並不是說將來不會發生這種情況.. 當你說用你引用的第二個腳本修改你的腳本時,我很困惑。 我試圖尊重並找出 10.5 和 42.0 的來源,並認為它與 log() 函數有關,但不確定。

回复:JSL - 生成循環遍歷具有不同變量的列的 -xy 圖gd_inc() 是之前在此博客路徑上發送的用戶函數。我又附上了。在使用腳本之前將代碼添加到腳本中,或者將腳本(我稱之為gd_inc.jsl )保存到有用函數的公共目錄、您自己的個人庫以及當您想要計算良好的軸增量時的任何腳本,添加聲明。
Include( "mydirectory/gd_inc.jsl" );
對於支持公司報告的人來說,他們經常創建一個大腳本,命名為 usr_functions.jsl 之類的東西。然後,他們不再使用大量 Include() 語句,而是僅使用一個 Include("mydirectory/usr_functions.jsl")
這裡又是這個函數。 看看之前的帖子,有例子說明如何使用這個功能。
gd_inc = Function({xlo, xhi, ntic}, {sp,tt, yrnd, ginc, ndec,lc, ll},
sp = (xhi - xlo)/ntic;
tt = log10(sp);
yrnd = If(
tt > 0, 1 - Floor( tt ),
Abs( Floor( tt ) - 1 )
);
ginc =round(sp,yrnd);
ndec = length(word(2,char(ginc),"."));
lc = length(word(1,char(xhi),"."));
if(ndec>0, lc=lc+ndec+1);
if(xlo <0, lc++); //add 1 character for the negative sign
ll=[1,1,1];
ll[1] = ginc; //increment
ll[2] = ndec; //# decimals
ll[3] = lc; //character length
ll
); // end gd_inc
/* test cases
show(gd_inc(1,11,10), gd_inc(.001, .005, 10), gd_inc(10000,20200, 10) )
*/順便說一句,我多年來一直在使用和教授 JMP 和 JSL。 所以我的知識並沒有那麼驚人,只是想分享。
回复:JSL - 生成循環遍歷具有不同變量的列的 -xy 圖你對 JSL 的東西太棒了.. 我什至不知道是否能找到其中任何一個。 我現在正在測試發行版.. 我對其他圖表也感激不盡。 我確信我也會被問到如何做到這些。 僅供參考,我正在使用 JMP 12.1.0,但是我們公司正在轉向 JMP 14,我迫不及待地因為我在這個網站上找到了半導體工具包插件。
當涉及 gd_inc 語句時,我收到錯誤。
名稱未解析: gd_inc 正在訪問或評估 'gd_inc' , gd_inc( Lo, Hi, 10 ) /*###*/
在以下腳本中,錯誤標記為 /*###*/
dt = Current Data Table();
jjrn3 = New Window( "Distribution [test_2]", <<JOURNAL></JOURNAL>
回复:JSL - 生成循環遍歷具有不同變量的列的 -xy 圖因根斯特恩,
我附上了2個腳本:
- ModifiedDistribution[test_2].jsl,以及
- 其他分佈圖.jsl
要點是,並非每個平台報告都具有相同的結構或相同的消息,可用的內容取決於您的 JMP 版本。顯示樹結構和獲取 XML 是可以幫助您發現報告結構的消息,腳本索引列出了顯示框的消息。我喜歡使用 XPath() 來“處理”難以找到的對像或多個段,例如 BoxPlotSeg 和 HistSeg。但是,還有其他方法來引用對象。 要獲取直方圖的 Y 變量比例框的句柄,請使用
_xx = gb<< Xpath("//ScaleBox[@charID='1']");
_xx << 消息;
或者
報告( gb )[ScaleBox(1)] << 消息;
另一個腳本顯示了適合比較分佈的替代圖。
回复:JSL - 生成循環遍歷具有不同變量的列的 -xy 圖謝謝你的劇本... 我對你提出的第一個問題有疑問。 您只是將其放入主腳本中還是單獨的新腳本中?
我喜歡你繪製並提供給我老闆的圖表,所以我正在等待他關於在他要求的許多報告中實施該圖表的消息。
我還採用了您給我的腳本,說明如何通過 -y 繪製 -x 並用 Distribution 替換 Graph Builder,它幾乎完美地工作。 我確實有一個關於樹結構的問題。 我能夠反轉到這一行並找到文本框(1),但是通過分發修改,我在運行此腳本時收到錯誤。 我似乎無法找到需要刪除的部分。 我附上數據表和修改後的腳本,其中包括分佈函數。
(國標<<頂部報告)[文本框( 1 )] <<刪除; //刪除where語句
回复:JSL - 生成循環遍歷具有不同變量的列的 -xy 圖謝謝您的建議/代碼.. 這週我要嘗試一下.. 我有一個軟期限來演示數據拉取、表格格式和圖形輸出。 你的幫助大大增加了我成功的可能性
回复:JSL - 生成循環遍歷具有不同變量的列的 -xy 圖正如我在之前的回復中提到的,“您可以創建固定比例或使用最喜歡的算法來找到適合手頭數據的最佳比例。 ” 下面是為腳本 7_InteractiveDisplays_Alternates.jsl(針對《JSL Companion》第二版)創建的函數 gd_inc()。
這是我在編寫值範圍未知的應用程序時使用的函數的簡化。該腳本假設固定十進制格式可以工作。 更通用的腳本將確定是否有太多小數,然後切換到科學記數法或更改為對數刻度等。在使用它之前,您應該嘗試一下。
參數是低、高和增量數。 它返回一個由 inc 值、格式和最大長度的小數組成的向量;在完整的腳本中,它用於 x 軸,並且方向根據其長度而改變。 或者,如果應使用固定十進制格式以外的其他格式,則可以使用長度來觸發。
gd_inc = Function({xlo, xhi, ntic}, {sp,tt, yrnd, ginc, ndec,lc, ll},
sp = (xhi - xlo)/ntic;
tt = log10(sp);
yrnd = If(
tt > 0, 1 - Floor( tt ),
Abs( Floor( tt ) - 1 )
);
ginc =round(sp,yrnd);
ndec = length(word(2,char(ginc),"."));
lc = length(word(1,char(xhi),"."));
if(ndec>0, lc=lc+ndec+1);
if(xlo <0, lc++); //add 1 character for the negative sign
ll=[1,1,1];
ll[1] = ginc; //increment
ll[2] = ndec; //# decimals
ll[3] = lc; //character length
ll
); // end gd_inc
/* test cases
show(gd_inc(1,11,10), gd_inc(.001, .005, 10), gd_inc(10000,20200, 10) )
*/獲得結果後,修改腳本
_yscl = gd_inc(Lo,Hi, 10);
_xx[1] << Axis Setings( {Min( Lo ), Max( Hi ), Inc( _yscl[1] ),
Minor Ticks( 1 ),
Label Row( {Show Major Grid( 1 ), Show Minor Grid( 1 )} ),
Format("Fixed Dec",12,_yscl[2])
});
JMP 在自動縮放方面做得很好,縮放比例對於圖形生成器來說太寬的原因是它進行縮放以便能夠顯示點而不僅僅是平滑的曲線。 一種選擇是獲取樣條曲線值並繪製它們。
如果您選擇不是為此,您需要找到曲線的最大值和最小值,並且需要決定是否希望Y_i 的所有圖形都具有相同的比例,或者每個Y_i 和測試是否需要具有相同的比例或每個圖形都有自己的比例。JMP Spline Smooth() 函數返回樣條值,您可以找到每個可能曲線的最大值和最小值,然後獲得所有曲線的最大值和最小值。 這將提供 Lo 和 Hi,我通常使用 10 作為增量數。
然後使用gd_inc()函數並修改。如果您知道低值和高值,則為每個 Y 創建一個表或常量。
自定義縮放可能會因多條曲線和样條線等自定義曲線而變得混亂。如果我有時間,我會附上您的虛擬數據的更新腳本。
順便說一句,我不確定你的虛擬數據有多真實。 在 PowerPoint 中比較多個圖表可能會令人困惑。GraphBuilder 非常適合比較圖表。 與其使用大量圖表,不如進行一些比較(不一定是下面的)可能有用。 下面是用於測試的 Y_3 與通道以及不同的 X 值。

回复:JSL - 生成循環遍歷具有不同變量的列的 -xy 圖沒有加載表..
回复:JSL - 生成循環遍歷具有不同變量的列的 -xy 圖我剛剛嘗試了你的解決方案。 我通常將腳本保存到窗口,這樣我就可以看到圖形的外觀。
我附上了修改後的虛擬數據,讓您了解我到底想要實現什麼目標。
對於 15 個通道,在這種情況下有 2 個具有不同輸出的測試狀態,我看不到一種適合所有解決方案。
請告訴我你的想法。
該特定測試有 3 個輸出。我必須單獨評估。
大衛
回复:JSL - 生成循環遍歷具有不同變量的列的 -xy 圖非常感謝.. 今天晚上我要嘗試一下..
回复:JSL - 生成循環遍歷具有不同變量的列的 -xy 圖您可以創建固定比例或使用最喜歡的算法來找到適合手頭數據的最佳比例。
下面附有先前提供的腳本的修改版本。 下面列出了新代碼。請注意,對於虛擬數據,最佳縮放比例可能是 -8 到 8,但是,我選擇 -7 來演示多個圖形可能會被裁剪。
_xx = gb<< Xpath("//ScaleBox[@charID='Y']");
_xx[1] << Axis Setings({Min( -7 ), Max( 8 ), Inc( 1 ), Minor Ticks( 1 ),
Label Row( {Show Major Grid( 1 ), Show Minor Grid( 1 )} )});有多種方法可以確定如何編寫更改腳本。 最簡單的方法是編寫一個圖表的腳本,然後使用 GUI 來
更改軸或標題或圖例。 然後從紅色倒三角形(在圖形生成器輪廓上)選擇保存腳本>到腳本窗口。 使用此方法它將顯示一個 Dispatch 參數。見下文。
Graph Builder(
Size( 1242, 709 ),
Show Control Panel( 0 ),
Variables( X( :X ), Y( :Y ), Group X( :Wafer ID ), Overlay( :RowCol ) ),
Elements( Smoother( X, Y, Legend( 19 ) ) ),
Where( dt:Channel == chnl & dt:Test State == tst ),
SendToReport(
Dispatch(
{},
"Graph Builder",
OutlineBox,
{Set Title( "Results for Channel=1 and Test State=1" )}
),
Dispatch(
{},
"Y",
ScaleBox,
{Min( -7 ), Max( 8 ), Inc( 1 ), Minor Ticks( 1 ),
Label Row( {Show Major Grid( 1 ), Show Minor Grid( 1 )} )}
)
)
);由於您的標題是自定義的,因此將 Dispatch 刪除到 OutlineBox,然後在 for 循環中使用此代碼,每個圖表將具有腳本中指定的相同縮放比例。
回复:JSL - 生成循環遍歷具有不同變量的列的 -xy 圖我可以再問您一個與 For() 循環和圖表相關的問題嗎?
有沒有辦法自動縮放最佳擬合?
如果我可以從 Min = 5 和 Max = 30 獲得示例中的比例,我們就可以更好地了解零件在頻率範圍內的具體表現......
當然,我必須事先刪除異常值。
謝謝
回复:JSL - 生成循環遍歷具有不同變量的列的 -xy 圖我非常感謝你在這方面的幫助。 這裡的工作人員甚至沒有人可以遠程告訴我如何做你所做的事情。
有了這個,我完成這項工作的時間至少減少了 80%。
您的解決方案和我正在編寫的用於訪問數據庫文件的 SQL 腳本將使我們與客戶處於有利的位置。
再次感謝你..
D
回复:JSL - 生成循環遍歷具有不同變量的列的 -xy 圖感謝您的答复。 我將用你的例子來看看我是否能弄清楚..
我嘗試使用“選擇位置”語句,效果很好。我只是想減少我必須編寫的代碼量。 我對上面列出的所有參數進行了 5 種不同的測試。
當我嘗試這個時我會報告。
再次感謝..
回复:JSL - 生成循環遍歷具有不同變量的列的 -xy 圖你好,
我建議修改生成圖表的方法以使用 where 語句而不是數據過濾器。數據過濾器非常適合交互式可視分析,但是,由於您的視圖是不可見的,我建議您使用 where 語句。當使用where語句時,where文本框可見;它可以被刪除。 您還可以使用 By 參數 By(:Channel, :Test State)。 然後腳本需要訪問每個 GB 並保存演示文稿。
我不喜歡“保存演示文稿”,我喜歡使用 P3ICLI,這是一個免費的外部命令行程序,可以從 JMP 輸出創建 PPTX 幻燈片。 看使用 P3ICLI 創建 PPTX 的 JSL 示例。 與任何代碼一樣,它看起來很混亂,但可以創建非常自定義的內容,並且可以控製圖形和標題的大小。
然而,對於使用“保存演示文稿”保存多個繪圖,我們編寫了一些技巧來將多個佈局顯示記錄為圖片,使用“保存演示文稿”,但您必須調整大小。
無論如何,附加的是一個虛擬數據表來模擬您的場景和兩個腳本,每個腳本每頁保存一張圖片
希望這可以幫助。