1. 为什么需要双坐标图在科研和工程领域我们经常会遇到需要同时展示两组量纲不同、数值范围差异大的数据。比如研究电机性能时既要显示转速单位rpm范围0-3000又要显示温度单位℃范围20-100。如果强行用同一个Y轴展示要么转速曲线被压扁成直线要么温度曲线变成几乎看不见的波动。我刚开始做实验时就犯过这个错误把电流和电压波形画在同一个坐标系里结果导师一眼就看出问题你这电流曲线怎么像心电图一样原来电压是0-5V范围而电流是0-100mA直接导致电流变化特征完全被掩盖。这就是双坐标图要解决的痛点——让不同量级、不同单位的多个数据集在同一张图中都能清晰展示各自的变化特征。2. plotyy基础用法详解2.1 最简双坐标图绘制先来看个最简单的例子用plotyy同时展示正弦波和指数曲线t 0:0.1:9*pi; figure [ax, h1, h2] plotyy(t, sin(t), t, exp(t));这三行代码就实现了左Y轴自动适配sin(t)的[-1,1]范围右Y轴自动适配exp(t)的[1,8000]范围返回三个关键句柄ax(坐标轴)、h1(左轴曲线)、h2(右轴曲线)实测发现plotyy有个智能特性当两组数据量级差超过100倍时右轴会自动采用对数坐标。比如把exp(t)改成exp(t/2)你会发现右轴变成了10^0到10^3的刻度。2.2 自定义曲线样式默认的蓝/绿配色可能不够醒目我们可以通过返回的句柄来定制set(h1, LineStyle, -, Marker, o, Color, r); set(h2, LineStyle, --, Marker, *, Color, b);这里有个实用技巧MarkerSize属性默认偏小建议设置为8-10set([h1 h2], MarkerSize, 8);2.3 添加轴标签和图例双坐标图的标注要特别注意区分左右轴ylabel(ax(1), 正弦值, FontSize, 12); ylabel(ax(2), 指数值, FontSize, 12); legend([h1 h2], {正弦波, 指数曲线}, Location, northwest);踩过坑的提示直接调用title()会居中显示但如果要加副标题建议用text()精确定位text(0.5, 1.05, 主标题, Units, normalized, HorizontalAlignment, center); text(0.5, 1.02, 副标题, Units, normalized, HorizontalAlignment, center);3. plotyy进阶技巧3.1 混合绘图类型plotyy第三个参数可以指定右轴的绘图类型。比如左轴用plot右轴用semilogyx 1:0.1:100; y1 x; y2 x.^3; plotyy(x, y1, x, y2, plot, semilogy);这个特性在展示频谱分析结果时特别有用左轴用线性坐标显示时域波形右轴用对数坐标显示频域分量。3.2 多曲线组合实际项目中经常需要左轴显示多组数据右轴显示另一组x 0:0.01:10; y1 sin(x); y2 0.5*sin(x); y3 10*cos(x); [ax, h1, h2] plotyy(x, [y1; y2], x, y3);注意h1此时是个包含两条曲线的数组设置属性时需要set(h1(1), Color, r); set(h1(2), Color, m); set(h2, Color, b);3.3 坐标轴精细控制需要手动设置刻度时推荐先用默认范围绘图再通过ax句柄调整set(ax(1), YLim, [-1.5 1.5], YTick, -1.5:0.5:1.5); set(ax(2), YLim, [0 100], YTick, 0:20:100);有个实用技巧保持右轴宽度与左轴一致set(ax(2), YAxisLocation, right, Box, off);4. axes组合方案4.1 为什么需要axes组合plotyy虽然方便但在以下场景力不从心需要超过两个Y轴要求坐标轴位置自由布局需要混合不同类型坐标系如极坐标直角坐标4.2 经典双轴实现方案figure % 创建左轴 ax1 axes(Position, [0.1 0.1 0.7 0.8]); plot(ax1, t, sin(t), b); ylabel(ax1, 正弦值); % 创建右轴 ax2 axes(Position, ax1.Position,... YAxisLocation, right,... Color, none); line(t, exp(t), Parent, ax2, Color, r); ylabel(ax2, 指数值);关键点ax2的Position必须与ax1完全一致Color,none使ax2背景透明必须显式指定Parent属性4.3 三轴系统实战演示温度、压力、流量三参数同图显示t 0:0.1:10; temp 20 5*sin(t); press 100 30*cos(t); flow 0.5 0.2*rand(size(t)); figure % 主坐标轴左轴 ax1 axes(Position, [0.1 0.1 0.6 0.8]); plot(ax1, t, temp, r); ylabel(ax1, 温度 (℃)); % 右轴 ax2 axes(Position, ax1.Position,... YAxisLocation, right,... Color, none); plot(ax2, t, press, b); ylabel(ax2, 压力 (kPa)); % 右轴上方叠加轴 ax3 axes(Position, [0.75 0.1 0.1 0.8],... Color, none); area(ax3, t, flow, FaceColor, g); ylabel(ax3, 流量 (L/min));这种方案虽然代码量增加但能实现plotyy无法做到的第三轴独立位置和尺寸每个轴使用不同的绘图函数完全自定义的样式控制5. 常见问题解决方案5.1 图例显示异常当使用axes组合时直接调用legend会只显示当前轴的曲线。正确做法是收集所有曲线句柄h1 plot(ax1, ...); h2 plot(ax2, ...); legend([h1 h2], {曲线1, 曲线2});5.2 坐标轴重叠有时右轴会遮挡左轴标签解决方法set(ax2, XTick, [], XColor, none); % 隐藏右轴的X轴 xlabel(ax1, 公共X轴标签);5.3 打印失真输出PDF或EPS时可能出现坐标轴错位推荐set(gcf, Renderer, painters); print -depsc2 output.eps6. 性能优化建议处理大数据量时1万点建议先绘制少量数据确定布局使用set(h, XData, x, YData, y)更新数据关闭自动重绘set(gcf, GraphicsSmoothing, off); set(gca, SortMethod, depth);在最近处理的一组10万点传感器数据中通过上述优化将渲染时间从8秒缩短到0.5秒。