MATLAB | 终于找到了修改图例图标的方法(可以自己设计图例啦?)

news2024/10/7 18:20:18

讲一点扒MATLAB底裤的事情叭,就是之前写的有一些绘图函数,比如阴影柱状图,想要把图例里的图标进行修改让其也带着阴影,我采取的是直接绘制一些会检测图例框移动的阴影图标来冒充图例的图标,那么有没有办法真正的自定义图例呢?

还真找到了方法,先给大家讲讲怎么办到的,之后可能会专门写一些相关的函数哈:

或者右上角心形图例:

或者直接把方形框改掉:

感谢@左右逢源
(https://www.zhihu.com/people/zuo-you-feng-yuan-4-38)
提供的思路和部分代码!!


原理

首先,众所周不知,MATLAB图例有很多隐藏属性,大概这样:

首先想的是怎么把图例图标里绑定的那个对象给取出来,我们研究发现办法还是很多的,例如:

hLegend.EntryContainer.NodeChildren(n).Icon.Transform.Children.Children

或者麻烦一点:

hLegend.EntryContainer.Children(n).Children(1).Transform.Children.Children

或者使用findobj后直接选择对象:

objHdl=findobj(hLegend.EntryContainer)
objHdl(4).Transform.Children.Children

左右逢源给出了一段批量获取的代码:

lgdEntryChild=hLegend.EntryContainer.NodeChildren;
iconSet=arrayfun(@(lgdEntryChild)lgdEntryChild.Icon.Transform.Children.Children,lgdEntryChild,UniformOutput=false)

获取了这个对象后其实就可以直接对其进行修改了:

clc;clear;close all
hold on;
plot(1:5,'LineWidth',2);
plot(2:6,'LineWidth',2);
hLegend=legend();
hLegend.Title.String='MyLegend';

% 批量获取全部图标对象
pause(1e-6)
lgdEntryChild=hLegend.EntryContainer.NodeChildren;
iconSet=arrayfun(@(lgdEntryChild)lgdEntryChild.Icon.Transform.Children.Children,lgdEntryChild,UniformOutput=false);

% 换颜色+加粗
iconSet{2}.ColorData=uint8([0;0;0;255]);
iconSet{2}.LineWidth=10;

那么有没有办法对其进行组合呢?,这个办法是左右逢源想到的,大体就是copy一份对象并修改所属的组(父类)即可:

% 复制并改父类
tempIcon=copy(iconSet{1});
tempIcon.Parent=iconSet{2}.Parent;


very amazing 啊,于是我们就开始了各种尝试:

写着玩的代码

圆圈+十字

创造新的图例最简单的就是把几个老图例进行组合,因此我先试了一个圆圈+十字的组合:

clc;clear;close all
hold on
% 绘制等高线图为构造自定义图例提供素材
x=linspace(-2*pi,2*pi);
y=linspace(0,4*pi);
[X,Y]=meshgrid(x,y);
Z=sin(X)+cos(Y);
contour(X,Y,Z,'LineWidth',1);
% 绘制横线竖线为构造自定义图例提供素材
plot(1:5,'LineWidth',1);
scatter(1,1,'LineWidth',1,'Marker','|');
% 获取横线竖线素材,之所以分两次构建图例
% 且copy第一次构建图例的素材
% 是因为如果直接将图例素材移动再
% 删除无用素材的EntryContainer也依旧会保留空白
hLegend1=legend();
pause(1e-6)
lgdEntryChild=hLegend1.EntryContainer.NodeChildren;
iconSet=arrayfun(@(lgdEntryChild)copy(lgdEntryChild.Icon.Transform.Children.Children),lgdEntryChild,UniformOutput=false);
% 第二次构建图例且只保留等高线图的图例
cHdl=findobj(gca,'Type','Contour');
hLegend2=legend(cHdl,'Data');
pause(1e-6)
iconParent=hLegend2.EntryContainer.NodeChildren(1).Icon.Transform.Children;
icon=hLegend2.EntryContainer.NodeChildren(1).Icon.Transform.Children.Children;
% 简单修改素材组成(删除等高线图例的两个内圈环)
delete(icon(1))
delete(icon(2))
% 修改横线竖线素材的父类组
iconSet{1}.Parent=iconParent;
iconSet{2}.Parent=iconParent;
% 修饰素材颜色和大小利于拼接
iconSet{1}.EdgeColorData=uint8([0;0;0;255]);
iconSet{1}.Size=8;
iconSet{2}.ColorData=uint8([0;0;0;255]);
icon(3).ColorData=uint8([0;0;0;255]);

方形等高线?

这时候已经发现是通过VertexData来控制形状,试了试将自身图例图标复制并缩小:

clc;clear;close all
hold on
% 绘制等高线图为构造自定义图例提供素材
fill([0,0,1,1],[1,0,0,1],[1,1,1],'LineWidth',.8)

hLegend=legend();
pause(1e-6)
icon=hLegend.EntryContainer.NodeChildren.Icon.Transform.Children.Children;

% 复制第一圈改颜色
LineIcon=copy(icon(1));
QuadIcon=copy(icon(2));
LineIcon.VertexData=(LineIcon.VertexData-.5).*.7+.5;
LineIcon.Parent=icon(1).Parent;
QuadIcon.VertexData=(QuadIcon.VertexData-.5).*.7+.5;
QuadIcon.ColorData=uint8([255;220;220;255]);
QuadIcon.Parent=icon(2).Parent;
% 复制第二圈改颜色
LineIcon=copy(icon(1));
QuadIcon=copy(icon(2));
LineIcon.VertexData=(LineIcon.VertexData-.5).*.4+.5;
LineIcon.Parent=icon(1).Parent;
QuadIcon.VertexData=(QuadIcon.VertexData-.5).*.4+.5;
QuadIcon.ColorData=uint8([210;220;225;255]);
QuadIcon.Parent=icon(2).Parent;

三角形

此时发现了LineLoop以及Quadrilateral对象调整不了点数,只能做有限的修改:

clc;clear;close all
hold on
% 绘制等高线图为构造自定义图例提供素材
fill([0,0,1,1],[1,0,0,1],[1,1,1],'LineWidth',.8)

hLegend=legend();
pause(1e-6)
icon=hLegend.EntryContainer.NodeChildren.Icon.Transform.Children.Children;
icon(1).VertexData=single([0     1 1     1
                           0     1 1     0
                           0     0 0     0]);

爱心

又经过尝试发现LineStrip以及TriangleStrip对象可以调整点数,尝试构造了一个心形图例图标:

clc;clear;close all
x = -1:1/100:1;
 
y1 = 0.6 * abs(x) .^ 0.5 + ((1 - x .^ 2) / 2) .^ 0.5;
y2 = 0.6 * abs(x) .^ 0.5 - ((1 - x .^ 2) / 2) .^ 0.5;
plot([x, flip(x)], [y1, y2], 'r')

hLegend=legend();
pause(1e-6)
icon=hLegend.EntryContainer.NodeChildren.Icon.Transform.Children.Children;

XX=[x, flip(x),x(1)]./2+.5;
YY=([y1, y2,y1(1)]-.2)./2+.5;
XYZ=single([XX;YY;0.*XX]);

icon.VertexData=XYZ;
icon.LineWidth=2;

看起来比较支持横平竖直的图例。


其他隐藏属性的利用

隐藏分割线

知道了那些隐藏属性能做到的尝试还是很多的,比如隐藏标题和图例图标之间的横线:

clc;clear;close all
hold on;
plot(1:5,'LineWidth',2);
plot(2:6,'LineWidth',2);
hLegend=legend();
hLegend.Title.String='MyLegend';

% 批量获取全部图标对象
pause(1e-6)
hLegend.TitleSeparator.Visible='off';

可以更好看一点。

平行四边形框

clc;clear;close all
hold on;
plot(1:5,'LineWidth',2);
plot(2:6,'LineWidth',2);
hLegend=legend();
hLegend.Title.String='MyLegend';

pause(1e-6)
hLegend.BoxEdge.VertexData=single([0    -.5    1     1.5
                                   0     1     1     0
                                   0     0     0     0]);


以上就是我们目前为止对其隐藏属性做的全部尝试,感觉能做出很多有意思的东西,未来也有可能开发的绘图函数真的用上了自己设计的图例图标,以上代码还不完善,还需要设计各种监听回调才能达到真正使用的级别,但给大家科普一下这些隐藏的玩意还是挺有意思的,下期见~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/720316.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何轻松应对广泛存在开源“0Day”

跟不少安全人员讨论过一个很通俗的话题 作为网安从业者最讨厌的是什么? 不同的人给了很多不同的答案 有的人说: 但更多的人都在说: “零日漏洞”(zero-day)又叫零时差攻击,是指被发现后立即被恶意利用的安全漏洞。通俗地讲&…

QScintilla自制代码编辑器系列(1)编译库文件与运行测试例子

1.下载工程源码 我本人机器上的QT是6.4 可以下载最新的代码 https://www.riverbankcomputing.com/static/Downloads/QScintilla/2.14.0/QScintilla_src-2.14.0.zip 2. 编译生成文件 无需改动可以顺利生成库文件 3. 运行例子 1)拷贝头文件 将整个Qsci文件夹拷…

面试官:你的项目有什么亮点?我:解决了JS脚本加载失败的问题!

前后端面试题库 (面试必备) 推荐:★★★★★ 地址:前端面试题库 web前端面试题库 VS java后端面试题库大全 面试官:你的项目有什么亮点?解决了什么问题? 你:嗯...... 面试官&#…

7.3 【Linux】磁盘的分区、格式化、检验与挂载

想在系统中新增一颗磁盘时,需要做: 1.对磁盘进行分区,以创建可用的partition; 2.对该partition进行格式化(format),以创建系统可用的filesystem; 3.可对刚刚创建好的filesystem进行检验; 4.…

Acrel-5000重点用能单位能耗在线监测系统在湖南三立集团的案例分析

安科瑞 崔丽洁 摘要:根据《重点用能节能办法》(国家发展改革委等第七部委2018年15号令)、《重点用能单位能耗在线监测系统推广建设工作方案》(发改环资[2017]1711号)和《关于加速推进重点用能单位能耗在线监测系统建设…

介绍几种OPTIONS检测的方法

概述 日常的VOIP开发中,OPTIONS检测是常用的网络状态检测工具。 OPTIONS原本是作为获取对方能力的消息,也可以检测当前服务状态。正常情况下,UAS收到OPTIONS心跳,直接回复200即可。 与ping不同的是,OPTIONS检测不仅…

前后端分离开发

目录 前后合开发(不推荐) 前后端分离开发(主流) 项目开发的基本步骤 接口文档的管理平台--YApi 前后合开发(不推荐) 沟通成本高分工不明确不便于管理不便于扩展 前后端分离开发(主流&…

让浮动元素在一行显示

&#x1f4dd;个人主页&#xff1a;爱吃炫迈 &#x1f48c;系列专栏&#xff1a;HTMLCSS &#x1f9d1;‍&#x1f4bb;座右铭&#xff1a;道阻且长&#xff0c;行则将至&#x1f497; <div class"wrap"><div class"item">1</div><di…

ubuntu实现自动挂载u盘

ubuntu实现自动挂载u盘 但是&#xff0c;有些设施可以在没有图形工具的情况下进行复制&#xff0c;并且在系统上占用的空间非常小。 例如&#xff0c;在我的设置中&#xff0c;我已经实现了USB自动挂载服务&#xff0c;而无需使用任何外部工具/服务&#xff0c;只有udev和syst…

Junit5相关技术

Selenium自动化测试框架 Junit针对Java的单元测试框架 拿一个技术写自动化测试用例&#xff08;Selenium3&#xff09; 拿一个技术管理已经编写好的测试用例(Junit5) 写代码前需要添加依赖&#xff1a;Junit5 一、注解 1.1 Test 表示当前这个方法是一个测试用例 1.2 Di…

DCN v2阅读笔记

Deformable ConvNets v2: More Deformable, Better Results 是 Deformable Convolutional Networks 研究的续作&#xff0c;发表在 CVPR 2019上。 作者对 DCNv1 的自适应行为进行研究&#xff0c;观察到虽然其神经特征的空间支持比常规的卷积神经网络更符合物体结构&#xff0…

2023年的无线蓝牙耳机哪些牌子好,真无线蓝牙耳机品牌排名

本文将为您详细介绍每款蓝牙耳机的设计特点、音质表现、续航能力和智能功能等关键信息。我们将提供客观、全面的分析&#xff0c;帮助您更好地了解每款产品的优势和适用场景&#xff1b;无论您是追求高保真音质的音乐发烧友&#xff0c;还是需要轻便舒适的耳机进行运动&#xf…

Kafka入门, 消费者工作流程(十八)

kafka消费方式 pull(拉)模式&#xff1a; consumer采用从broker中主动拉取数据。 Kafka采用这种方式。 push(推)模式&#xff1a; Kafka没有采用这种方式&#xff0c;因为由broker决定消息发送速率&#xff0c;很难适应所有消费者的速率。例如推送速度是50m/s&#xff0c;consu…

rocketmq客户端日志过大造成磁盘使用率占用过高

目录 问题现象 排查占用 自定义客户端日志配置未生效 总结 问题现象 收到项目报警&#xff1a;磁盘占用率超标通知 排查占用 从上述可以看出&#xff0c;实质是跟正常业务日志无关的&#xff0c;/home/work/log挂出来了&#xff0c;与/根目录下无关 查看根目录下日志占用…

frp实现远程开机

前一篇刷完小米路由器后&#xff0c;自带了frp&#xff0c;所以继续走着 前提&#xff1a;(我有阿里云公网服务器、域名&#xff09; 第一步&#xff0c;配置路由器&#xff08;客户端&#xff09;frp [common] server_addr frp.xxx.cn #需要在阿里云服务器添加解析 serve…

【macOS 系列】如何取消程序坞下方app的未读消息的小红点

如何取消程序坞下方app的未读消息的小红点 需要针对单独的软件一次设置&#xff0c;不能批量设置。将标记为APP图标取消勾选即可。

【UnityDOTS 七】IAspect的使用

IAspect的使用 前言 IAspect是Unity DOTS中用来更方便组织数据集合的接口。可以将我们需要的数据集合放到一个IAspect中&#xff0c;然后用这个自定义的IAspect去进行查询。 一、IAspect是什么&#xff1f; 如上面官方文档说的&#xff0c;是一个高级的Component组合体。 可以…

Gartner发布2023新兴技术雷达图,超级自动化安全、生成式AI是高影响力技术

在Gartner发布的“2023新兴技术影响力雷达图”中&#xff0c;围绕智能世界、生产力革命、透明度和隐私****以及关键使能技术四大主题&#xff0c;对24种最具颠覆和市场变革性的新兴趋势和技术进行了评估。 其中&#xff0c;边缘AI、边缘计算机视觉处于雷达图核心位置&#xff…

Redis-问题

1.redis的槽是什么&#xff1f; Redis Cluster中有一个16384长度的槽的概念,他们的编号为0、1、2、3……16382、16383。这个槽是一个虚拟的槽,并不是真正存在的。 2.redis的槽有什么用&#xff1f; 缓存 对于高访问量的网站,缓存是提高性能的重要手段。使用Redis槽技术可以将…

机器学习23:《数据准备和特征工程-I》概述

机器学习帮助我们找到数据中的模式&#xff0c;然后我们用这些模式来预测新的数据点。为了获得正确的预测&#xff0c;我们必须构建数据集并正确地转换数据。在《数据准备和特征工程》系列文章中&#xff0c;笔者将重点介绍这两个关键步骤。在【机器学习7&#xff1a;特征工程】…