開(kāi)發(fā)高級(jí)MATLAB可視化效果通常需要管理多個(gè)低層的圖形對(duì)象,包含動(dòng)態(tài)更新圖形的應(yīng)用程序更是如此。這種應(yīng)用程序可能需要非常耗時(shí)的編程。Chart 對(duì)象可提供高級(jí)應(yīng)用程序編程接口(API),實(shí)現(xiàn)可視化的自定義創(chuàng)建。圖表可為最終用戶(hù)提供方便的可視化 API,無(wú)需用戶(hù)執(zhí)行低層圖形編程。
本文以包含最佳擬合線的散點(diǎn)圖為主要示例,通過(guò)分步指導(dǎo)展示如何使用 MATLAB 面向?qū)ο蟮木幊虅?chuàng)建和實(shí)現(xiàn)自定義圖表,包括:
編寫(xiě)標(biāo)準(zhǔn)圖表模板
編寫(xiě)構(gòu)造方法
使用 private 屬性封裝圖表數(shù)據(jù)和圖形
使用 Dependent 屬性創(chuàng)建高級(jí)可視化 API
管理圖表生命周期
使用繼承簡(jiǎn)化附加圖表的開(kāi)發(fā)
圖表示例
MATLAB 提供幾種圖表,包括 heatmap 圖和 geobubble 圖,前者顯示疊放在彩色網(wǎng)格上的矩陣值,后者可快速在地圖上繪制離散數(shù)據(jù)點(diǎn)(圖1)。
圖1 heatmap圖和 geobubble 圖
此外,我們還創(chuàng)建幾種特定于應(yīng)用程序的圖表(圖2)。您可以從File Exchange 中隨本文使用的 MATLAB 代碼一起,下載這些圖表。
圖2 可在 File Exchange 中下載自定義圖表:
https://ww2.mathworks.cn/matlabcentral/fileexchange/65857-creating-specialized-charts-with-matlab-object-oriented-programming
創(chuàng)建二維散點(diǎn)圖:函數(shù)或圖表?
假設(shè)我們要?jiǎng)?chuàng)建包含對(duì)應(yīng)最佳擬合線的二維散點(diǎn)圖(圖 3)。我們可以使用 scatter 函數(shù)顯示離散 (x,y) 數(shù)據(jù)點(diǎn),并使用 Statisticsand Machine Learning Toolbox 中的 fitlm 函數(shù)計(jì)算最佳擬合線。
圖3 最佳擬合線和底層的分散數(shù)據(jù)
以上代碼可滿(mǎn)足靜態(tài)可視化的需求。但是,如果應(yīng)用程序要求對(duì)數(shù)據(jù)進(jìn)行動(dòng)態(tài)修改,我們會(huì)遇到幾個(gè)難題:
如果使用長(zhǎng)度與當(dāng)前 XData 相同的新數(shù)組替換 XData 或 Ydata,最佳擬合線不會(huì)動(dòng)態(tài)更新(圖 4)。
圖4 最佳擬合線在更改散點(diǎn)圖的 XData 后未更新
如果 Scatter 對(duì)象 s 的任一數(shù)據(jù)屬性(XData 或 YData)設(shè)置為長(zhǎng)度比當(dāng)前數(shù)組長(zhǎng)或短的數(shù)組,該對(duì)象會(huì)發(fā)出警告且不會(huì)執(zhí)行圖形更新。
我們可以通過(guò)設(shè)計(jì)一個(gè)圖表 ScatterFit 來(lái)解決這些難題。
構(gòu)建圖表代碼:函數(shù)或類(lèi)?
函數(shù)將代碼封裝為可重用單元,用戶(hù)無(wú)需重復(fù)代碼即可創(chuàng)建多個(gè)圖表。
請(qǐng)注意,此函數(shù)需要輸入兩個(gè)數(shù)據(jù)(x 和 y)。您可以指定圖形父項(xiàng) f(例如,圖形)作為第一個(gè)輸入?yún)?shù)。
scatterfit(x,y) 指定輸入的兩個(gè)數(shù)據(jù)
scatterfit(f,x,y) 指定圖形父項(xiàng)和數(shù)據(jù)
在第一種情況下,該函數(shù)展示自動(dòng)生成的行為,即將自動(dòng)創(chuàng)建圖表的圖形。
使用函數(shù)創(chuàng)建圖表具有某些缺點(diǎn):
圖表創(chuàng)建后數(shù)據(jù)無(wú)法修改
要更改圖表數(shù)據(jù),指定不同的數(shù)據(jù)輸入后,需要再次調(diào)用函數(shù)重新創(chuàng)建圖表
最終用戶(hù)很難查找可配置的圖表參數(shù)(如注釋和分散/線屬性)
用類(lèi)來(lái)實(shí)現(xiàn)圖表具有代碼封裝及方法可重用性等好處,同時(shí)支持對(duì)圖表進(jìn)行修改。
定義圖表類(lèi)
為了與 MATLAB 圖形對(duì)象保持一致,我們將圖表實(shí)現(xiàn)為 handle 類(lèi),以便在適當(dāng)位置修改圖表。我們支持在圖表屬性中使用點(diǎn)記法和 get/set 語(yǔ)法。要實(shí)現(xiàn)這一目標(biāo),我們從預(yù)定義 matlab.mixin.SetGet 類(lèi)(本身是 handle 類(lèi))中派生出 ScatterFit 圖表。
因此,任何屬性都將自動(dòng)支持表 1 中顯示的語(yǔ)法。
表1圖表屬性的訪問(wèn)和修改語(yǔ)法
編寫(xiě)圖表類(lèi)的構(gòu)造方法
構(gòu)造方法是類(lèi)定義中的一個(gè)函數(shù),用于構(gòu)造圖表對(duì)象。首先,將代碼從 scatterfit 函數(shù)復(fù)制到我們的圖表構(gòu)造方法之中。隨后,進(jìn)行以下修改支持所需圖表行為:
輸入?yún)?shù)。我們使用 varargin 支持在所有圖表輸入?yún)?shù)中使用名稱(chēng)值對(duì)。這意味著不需要指定輸入?yún)?shù),所有輸入值均可選。
父圖形。不同于函數(shù),如果已指定圖形構(gòu)造中沒(méi)有輸入 Parent,則無(wú)法為圖表自動(dòng)創(chuàng)建該輸入。我們使用空 Parent 創(chuàng)建 axes 對(duì)象。
請(qǐng)注意,此行為與 plot 和 scatter 等便捷函數(shù)的行為不同,后兩者可以自動(dòng)生成輸入。如果用戶(hù)將 Parent 指定為輸入?yún)?shù),則隨后將在構(gòu)造方法中對(duì)其進(jìn)行設(shè)置。
圖表圖形。我們可創(chuàng)建和存儲(chǔ)圖形所需的任何圖形對(duì)象。大多數(shù)圖表需要 axes 對(duì)象以及線或貼片對(duì)象等 axes 內(nèi)容。在 ScatterFit 圖表中,我們需要 Scatter 對(duì)象和 Line 對(duì)象。
圖形配置。我們可通過(guò)設(shè)置任何所需屬性配置圖表圖形。例如,我創(chuàng)建標(biāo)簽或標(biāo)題等注釋、設(shè)置 axes 的特定視圖、添加網(wǎng)格,或者調(diào)整顏色、樣式或線寬。
用戶(hù)指定的輸入。我們可設(shè)置最終用戶(hù)提供的任何名稱(chēng)值對(duì)參數(shù)。由于圖表派生自 matlab.mixin.SetGet,實(shí)現(xiàn)這一點(diǎn)非常容易:
如果用戶(hù)已作為名稱(chēng)值對(duì)輸入?yún)?shù)提供數(shù)據(jù)屬性,在此處設(shè)置這些數(shù)據(jù)(XData 和 YData)。我們還注意到,此編碼方法可確保用戶(hù)在指定名稱(chēng)值對(duì)時(shí)出現(xiàn)的任何錯(cuò)誤都將被圖表的屬性 set 方法發(fā)現(xiàn)和解決(稍后討論)。
如可行,我們將使用基元對(duì)象創(chuàng)建圖表圖形,因?yàn)楦呒?jí)便捷函數(shù)在調(diào)用時(shí)將重置多個(gè)現(xiàn)有 axes 屬性(圖2)。但是,這條原則存在例外情況:在 ScatterFit 內(nèi)部,我們將使用 scatter 函數(shù)創(chuàng)建 Scatter 圖形對(duì)象,因?yàn)樗С謱?duì)個(gè)別標(biāo)記的尺寸和顏色進(jìn)行后續(xù)更改。
表2 基元和高級(jí)圖形函數(shù)的示例
封裝圖表數(shù)據(jù)和圖形
在大多數(shù)圖表中,底層圖形包含至少一個(gè) axes 對(duì)象及其內(nèi)容(例如線或面對(duì)象)或多個(gè)對(duì)等的 axes 對(duì)象(例如,圖例或彩條)。這些圖表還包含內(nèi)部數(shù)據(jù)屬性,以確保公共屬性之間保持一致。我們存儲(chǔ)底層圖形和內(nèi)部數(shù)據(jù)為專(zhuān)有圖表屬性。例如,ScatterFit 圖表會(huì)維護(hù)以下專(zhuān)有屬性:
我們使用命名約定 XData_ 指示該版本是圖表數(shù)據(jù)的專(zhuān)有內(nèi)部版本。用戶(hù)可見(jiàn)的對(duì)應(yīng)公共數(shù)據(jù)屬性將命名為 XData。
使用 private 屬性主要有三個(gè)目的:
限制底層圖形的可見(jiàn)性,隱藏實(shí)現(xiàn)細(xì)節(jié),減少 API 中的視覺(jué)混亂
限制對(duì)底層圖形的訪問(wèn),減少繞過(guò) API 的幾率
輕松同步圖表數(shù)據(jù)(例如,我們需要對(duì) ScatterFit 的 XData 和 YData 屬性進(jìn)行關(guān)聯(lián))
提供可視化API
設(shè)計(jì)圖表的一個(gè)主要原因是提供方便、直觀的 API。我們使用與現(xiàn)有圖形對(duì)象屬性一致的名稱(chēng)為 ScatterFit 圖表提供容易識(shí)別的屬性(圖 5)。
圖5 ScatterFit 圖表API
用戶(hù)可使用表 1 中所示的語(yǔ)法訪問(wèn)或修改這些屬性。關(guān)聯(lián)的圖表圖形會(huì)動(dòng)態(tài)更新,以響應(yīng)屬性的修改。例如,更改圖表的 LineWidth 屬性會(huì)更新最佳擬合線的 LineWidth。
我們使用 Dependent 類(lèi)屬性實(shí)現(xiàn)圖表 API。Dependent 屬性的值未進(jìn)行顯式存儲(chǔ),而是獲取自類(lèi)中的其他屬性。在圖表中,Dependent 屬性依賴(lài)于低級(jí)別圖形等專(zhuān)有屬性或內(nèi)部數(shù)據(jù)屬性。
要定義 Dependent 屬性,我們首先使用屬性 Dependent 在 properties 塊中聲明其名稱(chēng)。這表明該屬性的值依賴(lài)于類(lèi)中的其他屬性。
通過(guò)編寫(xiě)對(duì)應(yīng)的 get 方法,我們還可以指定依賴(lài)于其他屬性的屬性。此方法會(huì)返回單個(gè)輸出參數(shù),即 Dependent 屬性的值。在 ScatterFit 圖表中,XData 屬性(圖表公共接口的一部分)就是底層 XData_ 屬性,它作為圖表的 private 屬性存儲(chǔ)在內(nèi)部。
我們?yōu)槊總€(gè)可配置的圖表屬性編寫(xiě) set 方法。此方法將用戶(hù)指定的值分配到正確的內(nèi)部圖表屬性,以在必要時(shí)觸發(fā)圖形更新。
對(duì)于 ScatterFit 圖表,我們支持對(duì)數(shù)據(jù)屬性(XData 和 YData)進(jìn)行動(dòng)態(tài)修改(包括長(zhǎng)度更改)。當(dāng)用戶(hù)設(shè)置圖表的(公共)XData 時(shí),我們將根據(jù)比較新數(shù)據(jù)矢量與現(xiàn)有數(shù)據(jù)的長(zhǎng)短,填充或截?cái)嘞鄬?duì)的(專(zhuān)有)數(shù)據(jù)屬性 YData_。請(qǐng)記住,如果用戶(hù)在創(chuàng)建圖表時(shí)已指定 XData,此 set 方法將被構(gòu)造方法調(diào)用。
我們通過(guò)調(diào)用不同的 update 方法刷新圖表圖形。此方法包含在 Scatter 對(duì)象中設(shè)置新數(shù)據(jù)、重新計(jì)算最佳擬合線,以及在對(duì)應(yīng)的 Line 對(duì)象中設(shè)置新數(shù)據(jù)所需的代碼。
我們以相同方式為 YData 實(shí)現(xiàn) set 方法,以切換 X/YData 屬性的角色。還會(huì)從 set 方法中為YData調(diào)用 update 方法。
要?jiǎng)?chuàng)建適用于最終用戶(hù)的豐富 API,我們會(huì)實(shí)現(xiàn)一組廣泛的 Dependent 屬性。建議在每個(gè)圖表中至少包含表 3 中所示的屬性。
表3. 建議的 Dependent 屬性
請(qǐng)注意,在大多數(shù)情況下,這些屬性將直接映射到底層圖表 axes。例如,Parent 屬性的 get 和 set 方法將圖表對(duì)象的 Parent 映射到 axes 的 Parent。
我們通過(guò)定義額外公共接口屬性啟用對(duì)可視化設(shè)置的控制,其中每個(gè)屬性映射到圖表維護(hù)的特定低級(jí)別圖形對(duì)象。在此類(lèi)別中,ScatterFit 圖表支持各種線相關(guān)屬性,如最佳擬合線相關(guān) LineStyle、LineWidth 和 LineColor。例如,圖表對(duì)象的 LineColor 屬性會(huì)映射到線對(duì)象的 Color 屬性。
此類(lèi)別中的典型圖表屬性包括:
視圖相關(guān)屬性——例如,axes 的 View、XLim 和 Ylim
注釋——例如,axes 的 Xlabel、Ylabel 和 Title
裝飾性屬性——例如,顏色、線寬,樣式、網(wǎng)格、透明效果和明暗度
管理圖表的生命周期
ScatterFit 圖表與其底層 axes 對(duì)象密切關(guān)聯(lián),該對(duì)象作為圖表的 private 屬性之一存儲(chǔ)。要正確管理圖表的生命周期,我們需要確保兩種行為:
刪除 axes(例如,通過(guò)關(guān)閉主圖形窗口)即刪除圖表。如果不能保證這一點(diǎn),一旦修改圖表的數(shù)據(jù)屬性,將導(dǎo)致 MATLAB 嘗試更新刪除的圖形對(duì)象,從而引發(fā)錯(cuò)誤
刪除圖表(例如,在其超出范圍時(shí)或當(dāng)其句柄顯式刪除時(shí))即刪除 axes。如果做不到這一點(diǎn),則在刪除圖表后,仍會(huì)殘留其靜態(tài)圖形
MATLAB 中的每個(gè)圖形對(duì)象都具有 DeleteFcn 屬性——一種在圖形對(duì)象超出范圍后被自動(dòng)調(diào)用的回調(diào)函數(shù)。因此,在圖表構(gòu)造方法中設(shè)置 axes 的 DeleteFcn 滿(mǎn)足第一個(gè)要求。
此處,onAxesDeleted 是 private 類(lèi)方法,僅充當(dāng)圖表析構(gòu)方法周?chē)陌b程序。如前所述,每個(gè) handle 類(lèi)在創(chuàng)建時(shí)都包含可自定義析構(gòu)方法。當(dāng)對(duì)象超過(guò)范圍后,析構(gòu)方法將被調(diào)用。
通過(guò)編寫(xiě)自定義圖表類(lèi)的析構(gòu)方法,我們可滿(mǎn)足第二個(gè)要求。在圖表析構(gòu)時(shí),我們將刪除圖表的axes。
實(shí)現(xiàn)這兩個(gè)要求后,圖表對(duì)象與其底層 axes 將具有相同的生命周期(圖 6)。
圖6管理圖表和 axes 生命周期
簡(jiǎn)化附加表格的開(kāi)發(fā)
在編寫(xiě)幾個(gè)圖表后,我們能夠輕松識(shí)別相似性和重復(fù)的代碼段。通過(guò)在超類(lèi)中集中放置通用代碼,我們可以加速編寫(xiě)額外圖表的進(jìn)程。每個(gè)新圖表可派生自此超類(lèi),這可使我們專(zhuān)注于實(shí)現(xiàn)該特定圖表的細(xì)節(jié),減少重復(fù)編碼的需求。
我們的超類(lèi)(即 Chart)具有以下結(jié)構(gòu):
Chart 派生自 matlab.mixin.SetGet。
Chart 將實(shí)現(xiàn)六個(gè)核心 Dependent 屬性 Parent、Position、Units、OuterPosition、ActivePositionProperty 和 Visible。
Chart 具有 protected 屬性 Axes(底層對(duì)等圖形)。
Chart 構(gòu)造方法將創(chuàng)建對(duì)等的 axes 對(duì)象并將 axes 的 DeleteFcn 設(shè)置為 protected 方法 onAxesDeleted。此方法進(jìn)而將刪除圖表對(duì)象。
-
數(shù)據(jù)
+關(guān)注
關(guān)注
8文章
7256瀏覽量
91887 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4381瀏覽量
64894 -
圖表
+關(guān)注
關(guān)注
0文章
33瀏覽量
9013
發(fā)布評(píng)論請(qǐng)先 登錄
[Actor] 通過(guò)actor創(chuàng)建控制中心與數(shù)據(jù)采集工作站來(lái)看操作者架構(gòu)
完整版—單片機(jī)編程思想(推薦下載?。?/a>
無(wú)刷電機(jī)電調(diào)的基本原理
基于鴻蒙原生ArkTS語(yǔ)法開(kāi)發(fā)的圖表組件--柱狀圖

SciChart 3D for WPF圖表庫(kù)

SciChart—高性能的JavaScript圖表和圖形庫(kù)

Chart FX——金融圖表
Chart FX——圖表導(dǎo)出

Chart FX——打印圖表

Chart FX-使用API傳輸數(shù)據(jù) 使用Value屬性傳輸數(shù)據(jù)

Chart FX-圖表渲染尺寸和格式

gitee 支持的編程語(yǔ)言有哪些
Chart FX-選擇圖表輸出

評(píng)論