0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

关于面向对象编程创建专用图表的方法介绍

MATLAB 来源:djl 2019-09-12 14:23 次阅读

开发高级MATLAB可视化效果通常需要管理多个低层的图形对象,包含动态更新图形的应用程序更是如此。这种应用程序可能需要非常耗时的编程。Chart 对象可提供高级应用程序编程接口(API),实现可视化的自定义创建。图表可为最终用户提供方便的可视化 API,无需用户执行低层图形编程。

本文以包含最佳拟合线的散点图为主要示例,通过分步指导展示如何使用 MATLAB 面向对象的编程创建和实现自定义图表,包括:

编写标准图表模板

编写构造方法

使用 private 属性封装图表数据和图形

使用 Dependent 属性创建高级可视化 API

管理图表生命周期

使用继承简化附加图表的开发

图表示例

MATLAB 提供几种图表,包括 heatmap 图和 geobubble 图,前者显示叠放在彩色网格上的矩阵值,后者可快速在地图上绘制离散数据点(图1)。

关于面向对象编程创建专用图表的方法介绍

图1 heatmap图和 geobubble 图

此外,我们还创建几种特定于应用程序的图表(图2)。您可以从File Exchange 中随本文使用的 MATLAB 代码一起,下载这些图表。

关于面向对象编程创建专用图表的方法介绍

图2 可在 File Exchange 中下载自定义图表:

https://ww2.mathworks.cn/matlabcentral/fileexchange/65857-creating-specialized-charts-with-matlab-object-oriented-programming

创建二维散点图:函数或图表?

假设我们要创建包含对应最佳拟合线的二维散点图(图 3)。我们可以使用 scatter 函数显示离散 (x,y) 数据点,并使用 Statisticsand Machine Learning Toolbox 中的 fitlm 函数计算最佳拟合线。

关于面向对象编程创建专用图表的方法介绍

关于面向对象编程创建专用图表的方法介绍

图3 最佳拟合线和底层的分散数据

以上代码可满足静态可视化的需求。但是,如果应用程序要求对数据进行动态修改,我们会遇到几个难题:

如果使用长度与当前 XData 相同的新数组替换 XData 或 Ydata,最佳拟合线不会动态更新(图 4)。

关于面向对象编程创建专用图表的方法介绍

关于面向对象编程创建专用图表的方法介绍

图4 最佳拟合线在更改散点图的 XData 后未更新

如果 Scatter 对象 s 的任一数据属性(XData 或 YData)设置为长度比当前数组长或短的数组,该对象会发出警告且不会执行图形更新。

关于面向对象编程创建专用图表的方法介绍

我们可以通过设计一个图表 ScatterFit 来解决这些难题。

构建图表代码:函数或类?

函数将代码封装为可重用单元,用户无需重复代码即可创建多个图表。

关于面向对象编程创建专用图表的方法介绍

请注意,此函数需要输入两个数据(x 和 y)。您可以指定图形父项 f(例如,图形)作为第一个输入参数

scatterfit(x,y) 指定输入的两个数据

scatterfit(f,x,y) 指定图形父项和数据

在第一种情况下,该函数展示自动生成的行为,即将自动创建图表的图形。

使用函数创建图表具有某些缺点:

图表创建后数据无法修改

要更改图表数据,指定不同的数据输入后,需要再次调用函数重新创建图表

最终用户很难查找可配置的图表参数(如注释和分散/线属性)

用类来实现图表具有代码封装及方法可重用性等好处,同时支持对图表进行修改。

定义图表类

为了与 MATLAB 图形对象保持一致,我们将图表实现为 handle 类,以便在适当位置修改图表。我们支持在图表属性中使用点记法和 get/set 语法。要实现这一目标,我们从预定义 matlab.mixin.SetGet 类(本身是 handle 类)中派生出 ScatterFit 图表。

关于面向对象编程创建专用图表的方法介绍

因此,任何属性都将自动支持表 1 中显示的语法。

关于面向对象编程创建专用图表的方法介绍

表1图表属性的访问和修改语法

编写图表类的构造方法

构造方法是类定义中的一个函数,用于构造图表对象。首先,将代码从 scatterfit 函数复制到我们的图表构造方法之中。随后,进行以下修改支持所需图表行为:

输入参数。我们使用 varargin 支持在所有图表输入参数中使用名称值对。这意味着不需要指定输入参数,所有输入值均可选。

关于面向对象编程创建专用图表的方法介绍

父图形。不同于函数,如果已指定图形构造中没有输入 Parent,则无法为图表自动创建该输入。我们使用空 Parent 创建 axes 对象。

关于面向对象编程创建专用图表的方法介绍

请注意,此行为与 plot 和 scatter 等便捷函数的行为不同,后两者可以自动生成输入。如果用户将 Parent 指定为输入参数,则随后将在构造方法中对其进行设置。

图表图形。我们可创建和存储图形所需的任何图形对象。大多数图表需要 axes 对象以及线或贴片对象等 axes 内容。在 ScatterFit 图表中,我们需要 Scatter 对象和 Line 对象。

关于面向对象编程创建专用图表的方法介绍

图形配置。我们可通过设置任何所需属性配置图表图形。例如,我创建标签或标题等注释、设置 axes 的特定视图、添加网格,或者调整颜色、样式或线宽。

用户指定的输入。我们可设置最终用户提供的任何名称值对参数。由于图表派生自 matlab.mixin.SetGet,实现这一点非常容易:

关于面向对象编程创建专用图表的方法介绍

如果用户已作为名称值对输入参数提供数据属性,在此处设置这些数据(XData 和 YData)。我们还注意到,此编码方法可确保用户在指定名称值对时出现的任何错误都将被图表的属性 set 方法发现和解决(稍后讨论)。

如可行,我们将使用基元对象创建图表图形,因为高级便捷函数在调用时将重置多个现有 axes 属性(图2)。但是,这条原则存在例外情况:在 ScatterFit 内部,我们将使用 scatter 函数创建 Scatter 图形对象,因为它支持对个别标记的尺寸和颜色进行后续更改。

关于面向对象编程创建专用图表的方法介绍

表2 基元和高级图形函数的示例

封装图表数据和图形

在大多数图表中,底层图形包含至少一个 axes 对象及其内容(例如线或面对象)或多个对等的 axes 对象(例如,图例或彩条)。这些图表还包含内部数据属性,以确保公共属性之间保持一致。我们存储底层图形和内部数据为专有图表属性。例如,ScatterFit 图表会维护以下专有属性:

关于面向对象编程创建专用图表的方法介绍

我们使用命名约定 XData_ 指示该版本是图表数据的专有内部版本。用户可见的对应公共数据属性将命名为 XData。

使用 private 属性主要有三个目的:

限制底层图形的可见性,隐藏实现细节,减少 API 中的视觉混乱

限制对底层图形的访问,减少绕过 API 的几率

轻松同步图表数据(例如,我们需要对 ScatterFit 的 XData 和 YData 属性进行关联)

提供可视化API

设计图表的一个主要原因是提供方便、直观的 API。我们使用与现有图形对象属性一致的名称为 ScatterFit 图表提供容易识别的属性(图 5)。

关于面向对象编程创建专用图表的方法介绍

图5 ScatterFit 图表API

用户可使用表 1 中所示的语法访问或修改这些属性。关联的图表图形会动态更新,以响应属性的修改。例如,更改图表的 LineWidth 属性会更新最佳拟合线的 LineWidth。

我们使用 Dependent 类属性实现图表 API。Dependent 属性的值未进行显式存储,而是获取自类中的其他属性。在图表中,Dependent 属性依赖于低级别图形等专有属性或内部数据属性。

要定义 Dependent 属性,我们首先使用属性 Dependent 在 properties 块中声明其名称。这表明该属性的值依赖于类中的其他属性。

关于面向对象编程创建专用图表的方法介绍

通过编写对应的 get 方法,我们还可以指定依赖于其他属性的属性。此方法会返回单个输出参数,即 Dependent 属性的值。在 ScatterFit 图表中,XData 属性(图表公共接口的一部分)就是底层 XData_ 属性,它作为图表的 private 属性存储在内部。

关于面向对象编程创建专用图表的方法介绍

我们为每个可配置的图表属性编写 set 方法。此方法将用户指定的值分配到正确的内部图表属性,以在必要时触发图形更新。

对于 ScatterFit 图表,我们支持对数据属性(XData 和 YData)进行动态修改(包括长度更改)。当用户设置图表的(公共)XData 时,我们将根据比较新数据矢量与现有数据的长短,填充或截断相对的(专有)数据属性 YData_。请记住,如果用户在创建图表时已指定 XData,此 set 方法将被构造方法调用。

关于面向对象编程创建专用图表的方法介绍

我们通过调用不同的 update 方法刷新图表图形。此方法包含在 Scatter 对象中设置新数据、重新计算最佳拟合线,以及在对应的 Line 对象中设置新数据所需的代码。

关于面向对象编程创建专用图表的方法介绍

我们以相同方式为 YData 实现 set 方法,以切换 X/YData 属性的角色。还会从 set 方法中为YData调用 update 方法。

要创建适用于最终用户的丰富 API,我们会实现一组广泛的 Dependent 属性。建议在每个图表中至少包含表 3 中所示的属性。

关于面向对象编程创建专用图表的方法介绍

表3. 建议的 Dependent 属性

请注意,在大多数情况下,这些属性将直接映射到底层图表 axes。例如,Parent 属性的 get 和 set 方法将图表对象的 Parent 映射到 axes 的 Parent。

关于面向对象编程创建专用图表的方法介绍

我们通过定义额外公共接口属性启用对可视化设置的控制,其中每个属性映射到图表维护的特定低级别图形对象。在此类别中,ScatterFit 图表支持各种线相关属性,如最佳拟合线相关 LineStyle、LineWidth 和 LineColor。例如,图表对象的 LineColor 属性会映射到线对象的 Color 属性。

关于面向对象编程创建专用图表的方法介绍

此类别中的典型图表属性包括:

视图相关属性——例如,axes 的 View、XLim 和 Ylim

注释——例如,axes 的 Xlabel、Ylabel 和 Title

装饰性属性——例如,颜色、线宽,样式、网格、透明效果和明暗度

管理图表的生命周期

ScatterFit 图表与其底层 axes 对象密切关联,该对象作为图表的 private 属性之一存储。要正确管理图表的生命周期,我们需要确保两种行为:

删除 axes(例如,通过关闭主图形窗口)即删除图表。如果不能保证这一点,一旦修改图表的数据属性,将导致 MATLAB 尝试更新删除的图形对象,从而引发错误

删除图表(例如,在其超出范围时或当其句柄显式删除时)即删除 axes。如果做不到这一点,则在删除图表后,仍会残留其静态图形

MATLAB 中的每个图形对象都具有 DeleteFcn 属性——一种在图形对象超出范围后被自动调用的回调函数。因此,在图表构造方法中设置 axes 的 DeleteFcn 满足第一个要求。

关于面向对象编程创建专用图表的方法介绍

此处,onAxesDeleted 是 private 类方法,仅充当图表析构方法周围的包装程序。如前所述,每个 handle 类在创建时都包含可自定义析构方法。当对象超过范围后,析构方法将被调用。

关于面向对象编程创建专用图表的方法介绍

通过编写自定义图表类的析构方法,我们可满足第二个要求。在图表析构时,我们将删除图表的axes。

关于面向对象编程创建专用图表的方法介绍

实现这两个要求后,图表对象与其底层 axes 将具有相同的生命周期(图 6)。

关于面向对象编程创建专用图表的方法介绍

图6管理图表和 axes 生命周期

简化附加表格的开发

在编写几个图表后,我们能够轻松识别相似性和重复的代码段。通过在超类中集中放置通用代码,我们可以加速编写额外图表的进程。每个新图表可派生自此超类,这可使我们专注于实现该特定图表的细节,减少重复编码的需求。

我们的超类(即 Chart)具有以下结构:

Chart 派生自 matlab.mixin.SetGet。

Chart 将实现六个核心 Dependent 属性 Parent、Position、Units、OuterPosition、ActivePositionProperty 和 Visible。

Chart 具有 protected 属性 Axes(底层对等图形)。

Chart 构造方法将创建对等的 axes 对象并将 axes 的 DeleteFcn 设置为 protected 方法 onAxesDeleted。此方法进而将删除图表对象。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据
    +关注

    关注

    8

    文章

    6884

    浏览量

    88813
  • 函数
    +关注

    关注

    3

    文章

    4304

    浏览量

    62421
  • 图表
    +关注

    关注

    0

    文章

    25

    浏览量

    8850
收藏 人收藏

    评论

    相关推荐

    创建ubuntu虚拟机

    的存在形式,然后点击“下一步”完成。指定磁盘文件,这里默认即可。默认点击“完成”即可。至此,虚拟机创建完成。下一小节中我们介绍Ubuntu系统在虚拟机中的安装,其在真机中的安装方法与虚拟机类似。这里我们
    发表于 08-10 14:15

    名单公布!【书籍评测活动NO.39】仓颉编程快速上手 | 开发者的第一个仓颉语言程序

    、while 表达式、for-in 表达式和循环表达式的嵌套。 接着介绍了函数的定义和调用,然后介绍了函数的重载,最后介绍了变量的作用域。 面向
    发表于 07-24 17:01

    神经网络专用硬件实现的方法和技术

    神经网络专用硬件实现是人工智能领域的一个重要研究方向,旨在通过设计专门的硬件来加速神经网络的训练和推理过程,提高计算效率和能效比。以下将详细介绍神经网络专用硬件实现的方法和技术,并附上
    的头像 发表于 07-15 10:47 957次阅读

    编程电源使用方法

    编程电源使用方法编程电源使用方法 摘要:本文详细介绍了可编程电源的使用
    的头像 发表于 06-10 15:29 893次阅读

    为什么很少用C++开发单片机

    C语言是面向过程的语言,C++是面向对象编程语言。结合本文来说,面向过程相比面向
    发表于 03-25 14:26 831次阅读
    为什么很少用C++开发单片机

    g73编程R怎么算

    编程是一门使用计算机语言来创建、编写和修改代码的技能。在编程过程中,计算机程序员通过使用各种编程语言来告诉计算机执行特定的任务。其中,G73编程
    的头像 发表于 02-14 15:57 701次阅读

    vb运行时错误429不能创建对象

    系统中已经安装了对象所依赖的组件或库。如果缺少这些组件或库,就会导致不能创建对象的错误。解决这个问题的方法是安装所需的组件或库。 对象的类或
    的头像 发表于 01-09 11:07 2148次阅读

    如何在循环中断中创建工艺对象PID控制器?

    以下步骤将介绍如何在循环中断 OB“PID [OB200]”中调用工艺对象“PID_Compact” 。
    的头像 发表于 12-29 18:10 1746次阅读
    如何在循环中断中<b class='flag-5'>创建</b>工艺<b class='flag-5'>对象</b>PID控制器?

    SQL对象名无效的解决方法

    使用的对象名称,确保其有效性。本文将详细介绍SQL对象名无效的解决方法。 1. 检查对象名称的正确性 首先,需要检查使用的
    的头像 发表于 12-29 14:45 1648次阅读

    基于C/C++面向对象的方式封装socket通信类流程简析

    在掌握了基于 TCP 的套接字通信流程之后,为了方便使用,提高编码效率,可以对通信操作进行封装,本着有浅入深的原则,先基于 C 语言进行面向过程的函数封装,然后再基于 C++ 进行面向对象的类封装。
    的头像 发表于 12-26 10:00 1737次阅读

    基于C/C++面向对象的方式封装socket通信类

    在掌握了基于 TCP 的套接字通信流程之后,为了方便使用,提高编码效率,可以对通信操作进行封装,本着有浅入深的原则,先基于 C 语言进行面向过程的函数封装,然后再基于 C++ 进行面向对象的类封装。
    的头像 发表于 12-26 09:57 1280次阅读

    IC封装中快速创建结构的新方法

    IC封装中快速创建结构的新方法
    的头像 发表于 12-06 16:34 557次阅读
    IC封装中快速<b class='flag-5'>创建</b>结构的新<b class='flag-5'>方法</b>

    线程池的创建方式有几种

    的开销。线程池的创建方式有多种,下面将详细介绍几种常用的线程池创建方式。 手动创建线程池 手动创建线程池是通过实例化ThreadPoolEx
    的头像 发表于 12-04 16:52 824次阅读

    javascript的内置对象有哪些

    JavaScript是一门广泛应用于Web开发的脚本语言,它有很多内置对象,用于处理不同的数据类型、执行不同的操作和提供各种功能。在这篇文章中,我将详尽介绍JavaScript的内置对象,以帮助
    的头像 发表于 12-03 11:39 1287次阅读

    LabVIEW通过编程将图形类控件的X轴显示为时间戳

    以下部分,了解特定版本LabVIEW的相关属性节点的位置。 LabVIEW8.5及更高版本: 按照以下步骤以编程方式使X轴显示为时间戳数据: 1.右键单击框图中表示图形或图表的图标,然后选择创建»属性
    发表于 11-28 19:24