【Qwt 7.0 系列】多坐标轴与多绘图布局 —— 寄生绘图与 QwtFigure 容器

发布时间:2026/7/13 12:24:14

【Qwt 7.0 系列】多坐标轴与多绘图布局 —— 寄生绘图与 QwtFigure 容器
【Qwt 7.0 系列】多坐标轴与多绘图布局 —— 寄生绘图与 QwtFigure 容器本文是 Qwt 7.0 系列介绍和教程如果你正在寻找一个高性能、协议友好、同时支持 2D 和 3D 绘图的 Qt 数据可视化库那么这篇文章就是为你准备的。系列总述文章Qwt 7.0 —— 基于 Qt 的高性能 2D/3D 绘图库概述 | 高性能曲线绘制 | 常用图表类型 | 高级科学图表 | 多坐标轴与布局 | 交互功能 | 3D 数据可视化 | 坐标轴与刻度 | 控件与辅助元素 | 总体架构解析 | matplotlib 风格绘图项目地址GitHub | Gitee | 在线文档引言如果你用过原版 Qwt 6.x一定遇到过这样的痛点一个QwtPlot只能拥有上下左右四个坐标轴。当你需要在同一张图上绘制温度℃、压力kPa、流量L/s三种不同量级的数据时两个 Y 轴根本不够用。在 matplotlib 中这个问题通过twinx()/twiny()轻松解决但在 Qt 的绘图世界里长期以来没有优雅的方案。Qwt 7.0 带来了全新的寄生绘图Parasite Axes机制和QwtFigure 容器彻底打破了这一限制。这两个特性是 Qwt 7.0 最重要的架构创新之一原版 Qwt 6.x 完全不支持。本文将带你深入理解这两个全新功能从原理到实战一步步掌握多坐标轴叠加和多绘图布局的技巧。一、寄生绘图Parasite Axes—— 多坐标轴系统1.1 工作原理寄生绘图的核心思想很简单在宿主绘图的画布上方叠加一个透明的子绘图。这个子绘图拥有独立的坐标系统但和宿主绘图共享同一块绘图区域。它有三个关键特征特征说明画布区域一致寄生绘图的画布与宿主绘图保持相同尺寸独立坐标系统可以拥有自己的刻度范围、标签、单位透明背景只显示坐标轴和曲线不遮挡宿主绘图你可以把寄生绘图想象成一层透明薄膜贴在宿主绘图上面每层薄膜各自携带一套独立的坐标轴。1.2 创建寄生绘图createParasitePlot()通过QwtPlot::createParasitePlot()方法创建寄生绘图签名如下QwtPlot*createParasitePlot(QwtAxis::Position enableAxis);参数enableAxis指定寄生绘图初始显示的坐标轴位置其他坐标轴默认隐藏。下面是一个完整的示例// 创建宿主绘图QwtPlot*hostPlotnewQwtPlot();// ... 设置宿主绘图的参数曲线、标题等////////////////////////////////////////////////////////// 添加寄生坐标系////////////////////////////////////////////////////////QwtPlot*parasitePlothostPlot-createParasitePlot(QwtAxis::YLeft);// 额外启用寄生绘图的其他坐标轴parasitePlot-enableAxis(QwtAxis::YRight,true);parasitePlot-enableAxis(QwtAxis::XTop,true);// 设置寄生绘图与宿主共享 X 轴parasitePlot-setParasiteShareAxis(QwtAxis::XBottom);// 设置寄生轴标题parasitePlot-setAxisTitle(QwtAxis::YLeft,Y2 Left Axis);parasitePlot-setAxisTitle(QwtAxis::YRight,Y2 Right Axis);parasitePlot-setAxisTitle(QwtAxis::XTop,X2 Top Axis);// 在寄生绘图上添加曲线QColorcurColor(255,127,14);// 橙色与宿主曲线区分QwtPlotCurve*parasiteCurvenewQwtPlotCurve(parasite sine Wave 1);parasiteCurve-setSamples(generateSampleData(100,2000,2.3));parasiteCurve-attach(parasitePlot);parasiteCurve-setPen(curColor,1.5);parasiteCurve-setRenderHint(QwtPlotItem::RenderAntialiased,true);// 给寄生轴的刻度上色方便区分parasitePlot-axisWidget(QwtAxis::YLeft)-setScaleColor(curColor);parasitePlot-axisWidget(QwtAxis::YRight)-setScaleColor(curColor);parasitePlot-axisWidget(QwtAxis::XTop)-setScaleColor(curColor);运行效果如下单寄生绘图1.3 多寄生绘图叠加任意数量的坐标轴Qwt 7.0 的强大之处在于——寄生绘图的数量没有限制。只需在宿主绘图上多次调用createParasitePlot()即可创建任意多的坐标轴层。下面是创建第二个寄生绘图的代码////////////////////////////////////////////////////////// 添加第二个寄生坐标系////////////////////////////////////////////////////////QwtPlot*parasitePlot2hostPlot-createParasitePlot(QwtAxis::YLeft);// 启用额外坐标轴并设置共享parasitePlot2-enableAxis(QwtAxis::YRight,true);parasitePlot2-enableAxis(QwtAxis::XBottom,true);parasitePlot2-setParasiteShareAxis(QwtAxis::XTop);// 设置轴标题parasitePlot2-setAxisTitle(QwtAxis::YLeft,Y3 Left Axis);parasitePlot2-setAxisTitle(QwtAxis::YRight,Y3 Right Axis);parasitePlot2-setAxisTitle(QwtAxis::XBottom,X3 Bottom Axis);// 在第二个寄生绘图上添加曲线QColorcurColor2(192,43,149);// 紫色QwtPlotCurve*parasiteCurve2newQwtPlotCurve(parasite sine Wave 2);parasiteCurve2-setSamples(generateSampleData(200,1000,4.3));parasiteCurve2-attach(parasitePlot2);parasiteCurve2-setPen(curColor2,1);parasiteCurve2-setRenderHint(QwtPlotItem::RenderAntialiased,true);// 刻度上色parasitePlot2-axisWidget(QwtAxis::YLeft)-setScaleColor(curColor2);parasitePlot2-axisWidget(QwtAxis::YRight)-setScaleColor(curColor2);parasitePlot2-axisWidget(QwtAxis::XBottom)-setScaleColor(curColor2);两个寄生绘图叠加后的效果可以看到图上有三套不同颜色的坐标轴分别对应宿主绘图和两个寄生绘图。这在原版 Qwt 6.x 中是根本做不到的。1.4 寄生绘图的层级关系寄生绘图有明确的层级关系决定了坐标轴的布局顺序先添加的寄生绘图处于低层级其坐标轴靠近宿主绘图后添加的寄生绘图处于高层级其坐标轴远离宿主绘图布局时宿主绘图先完成自身布局然后从低层级到高层级依次布局寄生绘图的坐标轴。1.5 坐标轴共享配置通过setParasiteShareAxis()方法可以让寄生绘图与宿主绘图共享某个坐标轴。共享后该轴的刻度范围会自动同步// 寄生绘图的 X 轴与宿主共享parasitePlot-setParasiteShareAxis(QwtAxis::XBottom);这在 X 轴代表时间等公共维度时非常有用——多个 Y 轴各自独立但共享同一条 X 轴。1.6 生命周期管理与遍历生命周期寄生绘图的生命周期与宿主绘图绑定。宿主绘图销毁时所有寄生绘图自动销毁无需手动管理。判断与遍历通过以下方法可以区分和获取绘图对象// 判断是否为宿主/寄生绘图boolisHostplot-isHostPlot();boolisParasiteplot-isParasitePlot();// 获取宿主绘图在寄生绘图上调用QwtPlot*hostparasitePlot-hostPlot();// 获取所有寄生绘图在宿主绘图上调用QListQwtPlot*parasiteshostPlot-parasitePlots();// 获取所有绘图列表宿主 寄生在任何绘图上调用均可constQListQwtPlot*plotListplot-plotList();// plotList[0] 是宿主绘图本身for(QwtPlot*p:plotList){constQwtPlotItemListitemsp-itemList();for(QwtPlotItem*item:items){// 遍历所有绘图项}}注意一个绘图不会既是寄生绘图又是宿主绘图。在寄生绘图上调用createParasitePlot()将返回nullptr。二、QwtFigure —— 多绘图布局容器2.1 类似 matplotlib Figure 的概念如果说寄生绘图解决的是一个画布上多套坐标轴的问题那么QwtFigure解决的就是一个窗口里多个子图的问题。QwtFigure是一个类似 matplotlibFigure的容器窗口用于组织和管理多个QwtPlot组件。它提供了两种布局方式归一化坐标布局和网格布局。2.2 归一化坐标布局归一化坐标就是以[0, 1]范围的百分比来定位子图遵循 Qt 标准的左上角坐标系QwtFigure*figurenewQwtFigure();figure-setSizeInches(8,6);// 设置图形尺寸为 8x6 英寸figure-setFaceColor(Qt::white);// 设置背景色QwtPlot*plot1newQwtPlot();// 添加到左上角四分之一区域figure-addAxes(plot1,QRectF(0.0,0.0,0.5,0.5));// 或者使用分离参数形式QwtPlot*plot2newQwtPlot();figure-addAxes(plot2,0.5,0.0,0.5,0.5);// 右上角四个参数依次是x, y, width, height均为占整个 Figure 窗口的百分比。2.3 网格布局类似 subplot如果你熟悉 matplotlib 的subplot那么 QwtFigure 的网格布局会让你感到亲切// 3x2 网格第1行第0列0-basedQwtPlot*plot3newQwtPlot();figure-addGridAxes(plot3,3,2,1,0);// 3x2 网格第1行第1列QwtPlot*plot4newQwtPlot();figure-addGridAxes(plot4,3,2,1,1);// 3x2 网格第2行跨2列QwtPlot*hostPlotnewQwtPlot();figure-addGridAxes(hostPlot,3,2,2,0,1,2);addGridAxes的参数含义(plot, totalRows, totalCols, row, col, rowSpan, colSpan)其中rowSpan和colSpan可选用于跨行跨列。下面是一个综合使用归一化坐标和网格布局的完整示例效果2.4 坐标轴对齐功能当多个子图的 Y 轴刻度范围差异较大时画布的水平边界可能不对齐视觉上不够整齐QwtFigure 提供了addAxisAlignment()方法来解决这个问题// plot1、plot3、hostPlot 的左坐标轴对齐figure-addAxisAlignment({plot1,plot3,hostPlot},QwtAxis::YLeft);// plot2、plot4 的左坐标轴对齐figure-addAxisAlignment({plot2,plot4},QwtAxis::YLeft);对齐后相关子图的画布边界会自动调整到同一水平线注意只有可见的坐标轴才能对齐。如果某个子图的对应坐标轴未显示则无法参与对齐。2.5 交互式操作蒙版QwtFigureWidgetOverlayQwtFigure 还提供了一个交互式操作蒙版QwtFigureWidgetOverlay允许用户在运行时通过鼠标拖拽来调整子绘图的位置和大小类似于可视化设计器中的操作体验。QwtFigure*figurenewQwtFigure();// ... 添加子绘图 ...// 创建并显示操作蒙版QwtFigureWidgetOverlay*overlaynewQwtFigureWidgetOverlay(figure);overlay-show();运行效果如下蒙版提供两项核心功能可通过枚举控制enumBuiltInFunctionsFlag{FunSelectCurrentPlot1,// 选择当前绘图FunResizePlot2// 调整绘图大小};启用/禁用特定功能// 只保留选择功能禁用尺寸调整overlay-setBuiltInFunctionsEnable(QwtFigureWidgetOverlay::FunResizePlot,false);自定义蒙版外观overlay-setBorderPen(QPen(Qt::red,2,Qt::DashLine));overlay-setControlPointBrush(QBrush(Qt::green));overlay-setControlPointSize(QSize(10,10));overlay-showPercentText(false);// 隐藏百分比文本蒙版还提供两个有用的信号widgetNormGeometryChanged()子图几何尺寸变化和activeWidgetChanged()当前激活子图变化方便你响应用户操作。三、绘图布局调整无论是单绘图还是多绘图场景QwtPlotLayout都是控制绘图内部空间分配的核心引擎。它负责组织标题、图例、坐标轴和画布区域的位置与大小。3.1 画布边距画布边距控制画布与坐标轴之间的空白QwtPlotLayout*layoutplot-plotLayout();// 设置所有坐标轴的画布边距为 10 像素layout-setCanvasMargin(10);// 仅设置左侧 Y 轴的画布边距layout-setCanvasMargin(15,QwtAxis::YLeft);3.2 组件间距与画布对齐// 组件标题、画布、图例、页脚之间的间距layout-setSpacing(8);// 画布与坐标轴刻度对齐默认开启layout-setAlignCanvasToScales(true);// 也可以按轴单独控制layout-setAlignCanvasToScale(QwtAxis::XBottom,true);layout-setAlignCanvasToScale(QwtAxis::YLeft,false);对齐模式下画布边界与刻度线精确对齐不对齐模式下画布保持固定大小刻度标签完整显示。3.3 图例位置// 图例放在右侧占 20% 宽度layout-setLegendPosition(QwtPlot::RightLegend,0.2);// 图例放在底部layout-setLegendPosition(QwtPlot::BottomLegend);位置枚举说明QwtPlot::LeftLegend图例在 YLeft 轴左侧QwtPlot::RightLegend图例在 YRight 轴右侧QwtPlot::BottomLegend图例在页脚下方QwtPlot::TopLegend图例在标题上方3.4 寄生绘图的轴边距对于寄生绘图坐标轴之间的间距通过QwtScaleWidget的两个属性控制margin坐标轴靠近画布一侧到画布的距离默认 0紧贴画布edgeMargin坐标轴靠近绘图边界一侧到边界的距离默认 0紧贴边框添加寄生轴后在显示前应手动调用updateAllAxisEdgeMargin()自动计算各层轴的间距避免重叠hostPlot-updateAllAxisEdgeMargin();该函数会遍历宿主及所有寄生轴逐层计算 margin 和 edgeMargin使各层坐标轴均匀分布。四、与原版 Qwt 6.x 的区别这是很多读者关心的问题下面做一个对比总结特性原版 Qwt 6.xQwt 7.0坐标轴数量固定 4 个上下左右任意多个寄生绘图叠加多绘图布局容器无需手动用 QLayout 管理QwtFigure 容器支持归一化坐标和网格布局坐标轴对齐无addAxisAlignment() 自动对齐交互式布局调整无QwtFigureWidgetOverlay 蒙版多 Y 轴场景需要复杂的 hack原生支持API 简洁寄生绘图和 QwtFigure 都是 Qwt 7.0 全新引入的功能原版 Qwt 6.x 完全不支持。这是 7.0 最重要的架构创新之一借鉴了 matplotlib 的设计理念但完全基于 Qt 原生组件实现性能和集成度更好。五、总结本文介绍了 Qwt 7.0 的两大布局利器寄生绘图通过createParasitePlot()在同一画布上叠加任意多套独立坐标轴完美解决多 Y 轴、多量级数据的可视化需求。寄生绘图与宿主绘图共享画布、独立坐标系、生命周期自动管理。QwtFigure 容器类似 matplotlib Figure 的多绘图布局容器支持归一化坐标定位和网格布局还能通过addAxisAlignment()实现子图坐标轴对齐配合QwtFigureWidgetOverlay蒙版实现交互式布局调整。这两个功能让 Qwt 7.0 在多轴、多图场景下的能力大幅跃升从够用走向好用。系列文章系列总述Qwt 7.0 —— 基于 Qt 的高性能 2D/3D 绘图库第 1 篇快速入门与核心新特性概览第 2 篇曲线绘图详解 —— 从基础到百万级数据性能优化第 3 篇常用图表类型实战 —— 柱状图、散点图、箱线图与直方图第 4 篇高级科学图表 —— 光谱图、向量场、K线图与极坐标绘图第 5 篇多坐标轴与多绘图布局 —— 寄生绘图与 QwtFigure 容器第 6 篇交互功能详解 —— 平移、缩放、坐标轴交互与数据拾取第 7 篇3D 数据可视化 —— OpenGL 高性能三维绘图第 8 篇坐标轴与刻度系统 —— 刻度引擎、网格、图例与刻度朝内第 9 篇控件与辅助元素 —— 滑块旋钮、标记与装饰第 10 篇总体架构解析 —— 从单体到三库模块化的演进第 11 篇matplotlib 风格绘图 —— QwtPyPlot 接口详解相关链接项目地址https://github.com/czyt1988/QWTGitee 镜像https://gitee.com/czyt1988/QWT在线文档https://czyt1988.github.io/QWT/zh/系列总述https://blog.csdn.net/czyt1988/article/details/160193393

相关新闻

WasmVideoPlayer:浏览器里直接播放H265视频

WasmVideoPlayer:浏览器里直接播放H265视频

2026/7/11 8:54:45

文章目录WasmVideoPlayer:浏览器里直接播放H265视频技术实现线程模型缓冲控制音视频同步编译和使用已知问题WasmVideoPlayer:浏览器里直接播放H265视频 这个项目在 GitHub 上拿到了 1390 Star。 sonysuqin 开源了 WasmVideoPlayer,做的事情很…

从粉丝项目到技术实践:构建自动化内容管理流水线

从粉丝项目到技术实践:构建自动化内容管理流水线

2026/7/12 6:44:21

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Qwen 随心用,限时 5 折。 👉 点击领海量免费额度 这次我们来看一个名为“【TXT|崔然竣】Y2,Lets go!!!(cr.古罗马混凝土)”的项目。从标题和命名方式…

日单量从 500 到 5000:零售系统升级的 4 个信号与迁移路径

日单量从 500 到 5000:零售系统升级的 4 个信号与迁移路径

2026/7/13 9:38:52

一句话结论 零售企业系统升级的时机,不看公司规模,看经营复杂度。日单量从 500 到 5000 的过程中,通常会依次触发:打单瓶颈 → 库存混乱 → 仓库失控 → 供应链和对账崩溃。每个阶段对应不同的系统能力需求。一、四个升级信号 信号…

Windows桌面路径错乱?深入解析User Shell Folders注册表修复指南

Windows桌面路径错乱?深入解析User Shell Folders注册表修复指南

2026/7/13 12:16:03

1. 为什么你的Windows桌面会"离家出走"?你有没有遇到过这种情况:明明想给C盘腾点空间,把桌面文件夹移动到D盘,结果整个用户文件夹突然变成了桌面?所有文档、下载内容都堆在桌面上,系统还提示&quo…

iPhone17护眼钢化膜选购指南:从光学原理看懂内外双护方案

iPhone17护眼钢化膜选购指南:从光学原理看懂内外双护方案

2026/7/13 12:16:03

不少iPhone 17用户发现,新机贴上普通钢化膜后屏幕反而变得更刺眼,户外反光严重,看久了眼睛酸涩。这个问题不能只靠降低屏幕亮度来解决,根源在于普通钢化膜破坏了屏幕原有的光学设计,放大了外部反光,同时完全…

护眼钢化膜:从光学原理看,一块膜如何减轻用屏负担

护眼钢化膜:从光学原理看,一块膜如何减轻用屏负担

2026/7/13 12:16:03

贴了钢化膜之后屏幕反光更刺眼、画面变得不通透,看久了眼睛酸涩——这是很多用户都有的体验。问题的根源在于,传统钢化膜只做了物理防刮这一件事,却完全忽略了屏幕光线对眼睛的影响。真正的护眼钢化膜,核心任务不是防蓝光或降低亮…

动态规划 多重背包二进制优化:从分组原理到C++代码的5步实现

动态规划 多重背包二进制优化:从分组原理到C++代码的5步实现

2026/7/13 12:16:03

动态规划多重背包二进制优化:从分组原理到C代码的5步实现在算法竞赛和实际开发中,动态规划的多重背包问题是一个经典且实用的场景。当我们需要处理每种物品有数量限制的背包问题时,直接套用01背包的思路会导致时间复杂度爆炸。二进制优化技巧…

iPhone17护眼保护膜:从光学层面看懂贴膜与用眼舒适的关系

iPhone17护眼保护膜:从光学层面看懂贴膜与用眼舒适的关系

2026/7/13 12:16:03

iPhone 17贴了普通保护膜之后,屏幕的观感反而下降了:反光刺眼、画面不通透,看久了眼睛酸涩。这个现象不是个例,而是传统保护膜只关注防刮、没有处理屏幕光线的必然结果。真正的iPhone 17护眼保护膜,必须从光学层面解决…

为什么 OpenClaw 预装这些 Skill?

为什么 OpenClaw 预装这些 Skill?

2026/7/13 12:06:02

为什么 OpenClaw 预装这些 Skill? 开箱即用,让 AI 从第一天就能帮你干活。本文用 iPhone 预装 App 的类比,解释 OpenClaw 预装 Skill 的设计哲学。 就像 iPhone 预装 App 你买了一台新 iPhone,开机后发现已经预装了相机、地图、计…

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践

2026/7/13 7:41:16

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator XUnity.AutoTranslator作为Unity游戏社区中最成熟的文本翻译解决方…

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持

2026/7/12 0:03:42

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持 【免费下载链接】raspberrypi-kernel It provides openEuler kernel source for Raspberry Pi 项目地址: https://gitcode.com/openeuler/raspberrypi-kernel 前往项目官网免费下载&…

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧

2026/7/12 0:03:42

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧 【免费下载链接】integration-test The repo contains test suits for system integration test 项目地址: https://gitcode.com/openeuler/integration-test 前往项目官网免费下载:…

卡梅德生物技术快报|纯化重组蛋白:变异链球菌 SepM 截短蛋白载体构建、诱导优化与纯化重组蛋白全套参数方案

卡梅德生物技术快报|纯化重组蛋白:变异链球菌 SepM 截短蛋白载体构建、诱导优化与纯化重组蛋白全套参数方案

2026/7/13 0:05:25

1 研究背景与现存技术痛点(提出问题)在口腔微生物分子机制研究中,SepM 蛋白酶是调控变异链球菌群体感应、致龋菌素合成的核心功能蛋白,体外功能验证、抗体开发均依赖高纯度可溶性 SepM 蛋白。当前原核表达体系针对 SepM 存在三大技…

卡梅德生物技术快报|重组蛋白的表达和纯化:IMAC 金属螯合色谱全流程工艺手册|基质 - 配基 - 金属离子匹配与蛋白质分离纯化参数优化

卡梅德生物技术快报|重组蛋白的表达和纯化:IMAC 金属螯合色谱全流程工艺手册|基质 - 配基 - 金属离子匹配与蛋白质分离纯化参数优化

2026/7/13 0:05:25

1 研究背景与现存技术痛点(提出问题)基因工程、蛋白质组学、生物制药研发流程中,蛋白质分离纯化是决定下游实验成败的关键环节。当前实验室常规蛋白质分离纯化工艺存在三类难以标准化的技术瓶颈:传统离子交换、分子筛层析无特异性…

卡梅德生物技术快报|蛋白质分离纯化:肠激酶可溶性原核表达 + 两步层析全参数|标准化蛋白质分离纯化 SOP

卡梅德生物技术快报|蛋白质分离纯化:肠激酶可溶性原核表达 + 两步层析全参数|标准化蛋白质分离纯化 SOP

2026/7/13 0:05:25

研究痛点提出(提出问题)重组肠激酶是融合标签切除核心工具酶,当前原核表达体系存在三大标准化难题,直接阻碍可复现的蛋白质分离纯化流程搭建:Trx、GST、单 SUMO 标签融合产物绝大多数为包涵体,沉淀占比超 9…