本节摘要:句柄图形(Handle Graphics)把一张图组织成对象树,每个属性可编程读写,是 Matlab 可视化从"画出来"进化到"精确控制"的关键机制。本节讲对象树结构、句柄获取与属性修改、批量风格管理,以及论文级导出流程。
改一个刻度字号,早期只能翻菜单点对话框——改第二十张图时人会疯。句柄图形的解法是:图是数据,不是图片。图窗、坐标区、曲线、文本各是对象,有句柄(引用),属性可读写。于是"统一全部图的风格"从二十次手工操作变成一段循环。
每个节点就是一个对象,父对象管理子对象的布局。获取句柄的方式随版本演化:老写法 gcf/gca 取"当前"对象,新写法(R2014b 之后)创建时直接返回句柄,推荐后者:
fig = figure; ax = axes(fig); ln = plot(ax, x, sin(x)); % ln 即线对象句柄 ln.LineWidth = 2; % 点语法改属性 ln.Color = [0.2 0.4 0.8]; ax.FontSize = 14; ax.XTick = 0:pi/2:2*pi; % 刻度位置精确控制 ax.XTickLabel = {'0','\pi/2','\pi','3\pi/2','2\pi'};
点语法(ln.LineWidth)与老的 set(ln,'LineWidth',2) 等价,新写法还带补全提示。查一个对象有哪些属性用 ln 直接回车,或 get(ln)。
figs = findobj(0, 'Type', 'figure'); % 全部图窗 for f = figs' axList = findall(f, 'Type', 'axes'); arrayfun(@(a) set(a, 'FontSize', 12, ... 'LineWidth', 1, 'TickDir', 'out'), axList); end
工程上更进一步的做法是把风格参数集中成一个结构体(或函数),每张图创建后统一过一遍——相当于给团队定义一套"出版样式表"。tiledlayout 的 NextTile 也返回坐标区句柄,多子图同样能精确定制。
exportgraphics(ax, 'result.png', 'Resolution', 300); exportgraphics(fig, 'result.pdf', 'ContentType', 'vector');
exportgraphics(R2020a 起)取代老的 print/saveas,按对象导出、自动裁边。选型经验:位图走 PNG 300dpi 够大多数期刊;需要无损缩放或版面精细排则出矢量 PDF;别用截屏,那是所有模糊图和锯齿字的源头。
⚠️ 常见坑:在循环里不关图窗,跑一晚留下几百个图窗把内存吃满。批量出图的循环末尾务必
close(fig),或改用"创建—导出—关闭"的流水线模式。
把"风格即代码"走完整个流程。目标:全组所有图统一字号、线宽、色序。做法是定义一个样式函数,每张图创建后套用:
function applyStyle(ax) % APPLYSTYLE 统一出版风格:字号12、刻度朝外、Tufte色序 ax.FontSize = 12; ax.LineWidth = 1.0; ax.TickDir = 'out'; ax.Box = 'off'; ax.ColorOrder = [0.12 0.47 0.71; 0.89 0.47 0.20; 0.30 0.30 0.30]; ax.Title.FontWeight = 'bold'; end
fig = figure('Units','centimeters','Position',[2 2 12 8]); ax = axes(fig); plot(ax, x, sin(x), x, cos(x)); applyStyle(ax) % 一行完成全部定制 exportgraphics(ax, 'styled.pdf', 'ContentType','vector')
解读:图窗尺寸用厘米直接指定(单栏图 12 厘米宽是常见版式),导出矢量 PDF 后字与线在印刷尺寸下所见即所得。团队协作时这个样式函数进版本库,比口头约定"大家字号用 12"可靠得多——样式漂移是多人报告图文风格不一致的头号原因,根因就是样式没有代码化。
句柄操作最常见的挫败是"找不到要改的对象"。三层排查:先 ax.Children 看坐标区下挂了什么;再 findall(ax, 'Type','text') 按类型深搜(findobj 不返回隐藏对象,findall 会);最后用"点击即取"模式——命令行运行后点击图上目标对象,其句柄与类型立即列出,图形对象不透明时这是最快的路。另一个版本类坑:R2014b 前后句柄机制重写,老代码里把句柄当 double 存进数组再比较的逻辑全部失效,新机制句柄是对象,迁移遗留代码时这段要人肉重写。
同一件事的三种历史形态。set(ln,'LineWidth',2) 是最早的统一接口,至今在批量操作(一个函数调用改多个对象)里最顺手;点语法 ln.LineWidth = 2 是 R2014b 后的推荐写法,有补全与查错;属性预设(启动配置里定义默认值)则让对象"生下来就长对",适合机构级统一样式。三者的选择逻辑:一次性修改用点语法,循环批处理用 set,全项目默认走预设。理解它们是同一棵对象树上的不同入口,比记住三套语法更重要。
gca/gcf 的"当前"语义;findall 批量套风格,是出版级一致性的来源;exportgraphics 是现代导出主力,矢量或高分辨率位图按用途选;