【Qwt 7.0 系列】坐标轴与刻度系统 —— 刻度引擎、网格、图例与刻度朝内

发布时间:2026/7/5 2:52:18

【Qwt 7.0 系列】坐标轴与刻度系统 —— 刻度引擎、网格、图例与刻度朝内 【Qwt 7.0 系列】坐标轴与刻度系统 —— 刻度引擎、网格、图例与刻度朝内本文是 Qwt 7.0 系列介绍和教程如果你正在寻找一个高性能、协议友好、同时支持 2D 和 3D 绘图的 Qt 数据可视化库那么这篇文章就是为你准备的。系列总述文章Qwt 7.0 —— 基于 Qt 的高性能 2D/3D 绘图库概述 | 高性能曲线绘制 | 常用图表类型 | 高级科学图表 | 多坐标轴与布局 | 交互功能 | 3D 数据可视化 | 坐标轴与刻度 | 控件与辅助元素 | 总体架构解析 | matplotlib 风格绘图项目地址GitHub | Gitee | 在线文档引言坐标轴是数据可视化的骨架。无论你的曲线画得多漂亮如果坐标轴的刻度不合理、标签看不清、网格太杂乱读者就无法准确理解数据。Qwt 7.0 作为基于原版 Qwt 6.2.0 的现代化维护分支提供了一套强大的刻度引擎和灵活的坐标轴配置系统能够应对从简单的线性图表到复杂的时间序列、对数坐标等各种场景。本篇是 Qwt 7.0 系列博客的第 8 篇将全面介绍 Qwt 7.0 的坐标轴与刻度系统包括刻度引擎线性、对数、日期时间三种引擎的原理与用法坐标轴控件刻度线配置、标签格式化、轴标题与外观网格线主/次网格的独立控制与样式配置图例系统外部图例与内嵌图例的使用刻度朝内显示Qwt 7.2.1 新增的紧凑布局功能一、刻度引擎 QwtScaleEngine刻度引擎是坐标轴系统的大脑。它负责根据数据范围自动计算合理的刻度位置——比如数据范围是 0~100引擎会自动选择 0、20、40、60、80、100 作为主刻度而不是 0、17、34 这样的奇怪数字。1.1 三种内置刻度引擎Qwt 7.0 提供三种内置刻度引擎引擎类适用场景主刻度示例QwtLinearScaleEngine线性数据默认0, 20, 40, 60, 80, 100QwtLogScaleEngine大范围/指数关系数据1, 10, 100, 1000QwtDateScaleEngine时间序列数据按时间级别自动选择1.2 线性刻度引擎默认线性刻度引擎是默认引擎适用于大多数均匀分布的数据。你甚至不需要显式创建它——QwtPlot默认就使用线性引擎。#includeQwtPlotQwtPlot*plotnewQwtPlot();// 默认使用线性刻度引擎启用自动刻度计算plot-setAxisAutoScale(QwtAxis::XBottom);// 设置主刻度数量上限最多10个主刻度plot-setAxisMaxMajor(QwtAxis::XBottom,10);// 设置次刻度数量上限每个主刻度区间最多5个次刻度plot-setAxisMaxMinor(QwtAxis::XBottom,5);刻度引擎会自动在 1、2、5、10 等美观间隔中选择最合适的刻度间距你只需要设定大致的刻度数量上限即可。下图是刻度引擎的演示效果展示了不同引擎和参数下的刻度表现1.3 对数刻度引擎当数据跨越多个数量级时线性刻度会让小数值挤在一起看不清。对数刻度引擎将坐标轴按对数分布适合频率响应图、地震图等场景。#includeQwtLogScaleEngine// 为Y轴设置对数刻度引擎plot-setAxisScaleEngine(QwtAxis::YLeft,newQwtLogScaleEngine());// 设置对数刻度范围跨越6个数量级plot-setAxisScale(QwtAxis::YLeft,0.001,1000);对数刻度的特点主刻度位于 10^n 位置0.001, 0.01, 0.1, 1, 10, 100, 1000…次刻度位于中间位置2, 3, 4, 5, 6, 7, 8, 9 对应倍数1.4 日期时间刻度引擎处理时间序列数据时日期刻度引擎能根据时间跨度自动选择合适的刻度级别——跨度大的用年份跨度小的用小时甚至分钟。#includeQwtDateScaleEngine#includeQwtDateScaleDraw#includeQwtDate// 设置日期刻度引擎plot-setAxisScaleEngine(QwtAxis::XBottom,newQwtDateScaleEngine());// 设置日期刻度绘制器自定义不同级别的日期格式QwtDateScaleDraw*dateDrawnewQwtDateScaleDraw();dateDraw-setDateFormat(QwtDateScaleDraw::Month,QString(yyyy-MM));// 月份级别显示年月dateDraw-setDateFormat(QwtDateScaleDraw::Day,QString(MM-dd));// 日期级别显示月日plot-setAxisScaleDraw(QwtAxis::XBottom,dateDraw);// 设置时间范围QwtDate::toDouble 将 QDateTime 转为轴坐标值QDateTime startQDateTime::fromString(2024-01-01,yyyy-MM-dd);QDateTime endQDateTime::fromString(2024-12-31,yyyy-MM-dd);plot-setAxisScale(QwtAxis::XBottom,QwtDate::toDouble(start),QwtDate::toDouble(end));QwtDateScaleDraw支持的时间级别格式如下级别说明默认格式Millisecond毫秒级hh:mm:ss.zzzSecond秒级hh:mm:ssMinute分钟级hh:mmHour小时级hh:mmDay日级MM-ddWeek周级MM-ddMonth月级yyyy-MMYear年级yyyy引擎会根据数据范围自动选择最合适的级别。比如数据跨度是半年它会选 Day 或 Week 级别如果是十年就选 Year 级别。1.5 自定义刻度分割如果自动计算无法满足需求你可以完全手动控制刻度位置#includeQwtScaleDiv// 手动创建刻度划分QwtScaleDiv scaleDiv;scaleDiv.setInterval(0,100);// 设置范围// 设置主刻度QListdoublemajorTicks;majorTicks020406080100;scaleDiv.setTicks(QwtScaleDiv::MajorTick,majorTicks);// 设置次刻度QListdoubleminorTicks;for(inti0;i100;i4){if(!majorTicks.contains(i))minorTicksi;}scaleDiv.setTicks(QwtScaleDiv::MinorTick,minorTicks);// 应用自定义刻度划分plot-setAxisScaleDiv(QwtAxis::XBottom,scaleDiv);1.6 刻度引擎属性刻度引擎还提供了一些属性来微调刻度计算行为属性说明IncludeReference强制包含参考值作为刻度Symmetric强制范围对称如 -100 ~ 100Floating端点不强制落在刻度上Inverted反转刻度方向// 获取刻度引擎并设置属性QwtScaleEngine*engineplot-axisScaleEngine(QwtAxis::XBottom);engine-setAttribute(QwtScaleEngine::IncludeReference,true);engine-setAttribute(QwtScaleEngine::Symmetric,false);engine-setAttribute(QwtScaleEngine::Floating,false);// 设置边距数据范围两端各留5%空白engine-setMargins(0.05);小贴士选择刻度引擎的简单原则——线性数据用线性引擎默认跨数量级数据用对数引擎时间数据用日期引擎。特殊需求手动设置刻度划分。二、坐标轴控件 QwtScaleWidgetQwtScaleWidget是坐标轴的显示控件负责绘制刻度线、刻度标签和轴标题。在QwtPlot中每个坐标轴都对应一个QwtScaleWidget实例。2.1 通过 QwtPlot 配置坐标轴日常使用中你通常通过QwtPlot的便捷方法来配置坐标轴而不需要直接操作QwtScaleWidget// 设置坐标轴标题plot-setAxisTitle(QwtAxis::XBottom,时间 (s));plot-setAxisTitle(QwtAxis::YLeft,电压 (V));// 设置坐标轴范围plot-setAxisScale(QwtAxis::XBottom,0,100);plot-setAxisScale(QwtAxis::YLeft,-10,10);// 控制坐标轴可见性隐藏顶部X轴显示右侧Y轴plot-setAxisVisible(QwtAxis::XTop,false);plot-setAxisVisible(QwtAxis::YRight,true);plot-replot();Qwt 7.0 使用QwtAxis::Position枚举标识四个基本坐标轴位置枚举值说明QwtAxis::XBottom底部水平轴QwtAxis::XTop顶部水平轴QwtAxis::YLeft左侧垂直轴QwtAxis::YRight右侧垂直轴2.2 获取并自定义坐标轴控件需要更精细的控制时可以通过axisWidget()获取底层的QwtScaleWidget// 获取特定位置的坐标轴控件QwtScaleWidget*scaleWidgetplot-axisWidget(QwtAxis::XBottom);// 设置刻度标签字体scaleWidget-setFont(QFont(Arial,8));// 自定义轴标题样式QwtTexttitle(时间 (s));title.setFont(QFont(Arial,10,QFont::Bold));title.setColor(Qt::darkBlue);scaleWidget-setTitle(title);// 设置刻度颜色scaleWidget-setPalette(QPalette(Qt::black));2.3 刻度标签格式化默认情况下刻度标签直接显示数值。如果你需要自定义格式比如加单位、控制小数位数可以继承QwtScaleDraw并重写label()方法#includeQwtScaleDraw// 自定义刻度绘制器classMyScaleDraw:publicQwtScaleDraw{public:virtualQwtTextlabel(doublevalue)constoverride{// 保留1位小数returnQwtText(QString::number(value,f,1));}};// 应用自定义刻度绘制器scaleWidget-setScaleDraw(newMyScaleDraw());这个技巧非常实用。比如你想在温度轴上显示 “36.5°C”在百分比轴上显示 “85%”都可以通过重写label()方法实现。2.4 颜色条光谱图专用QwtScaleWidget还支持显示颜色条常用于光谱图Spectrogram等需要颜色映射的场景// 启用颜色条scaleWidget-setColorBarEnabled(true);scaleWidget-setColorBarWidth(20);// 设置颜色映射蓝色到红色的渐变QwtLinearColorMap*colorMapnewQwtLinearColorMap(Qt::blue,Qt::red);scaleWidget-setColorMap(QwtInterval(0,100),colorMap);2.5 内置交互功能Qwt 7.0 新增Qwt 7.0 为坐标轴控件新增了内置交互功能支持直接在坐标轴上拖动平移和滚轮缩放// 启用内置平移功能左键拖动scaleWidget-setBuiltInAction(QwtScaleWidget::Pan,true);// 启用内置缩放功能scaleWidget-setBuiltInAction(QwtScaleWidget::Zoom,true);// 设置交互的鼠标按钮scaleWidget-setActionButton(Qt::LeftButton);// 左键拖动平移这是 Qwt 7.0 相比原版 Qwt 6.2.0 的一项实用改进——用户不需要编写额外的事件过滤器就能直接在坐标轴上拖动来浏览数据。三、网格 QwtPlotGrid网格线帮助读者更准确地判断数据点的坐标值是科学图表中不可或缺的辅助元素。QwtPlotGrid是 Qwt 提供的网格绘图项它会自动跟随坐标轴的刻度划分来绘制网格线。3.1 基本使用#includeQwtPlotGridQwtPlotGrid*gridnewQwtPlotGrid();// 启用主网格默认已启用grid-enableX(true);// X轴主网格垂直线grid-enableY(true);// Y轴主网格水平线// 启用次网格默认关闭grid-enableXMin(false);grid-enableYMin(false);// 附加到绘图grid-attach(plot);网格线会自动跟随坐标轴刻度的变化——当你缩放或平移绘图时网格线会自动调整位置无需手动维护。3.2 网格线样式主网格和次网格可以设置不同的样式通常主网格更醒目次网格更淡// 主网格灰色实线grid-setMajorPen(QPen(QColor(150,150,150),1.0,Qt::SolidLine));// 次网格浅灰色点线grid-setMinorPen(QPen(QColor(200,200,200),0.5,Qt::DotLine));// 也可以用快捷方法统一设置// grid-setPen(Qt::gray, 0.5, Qt::DotLine);小技巧在 Qt 中线宽设为0.0表示使用 1 像素的快速绘制线cosmetic pen对于网格线来说这能获得最细的线条效果。3.3 完整网格配置示例下面是一个包含网格、曲线的完整示例#includeQwtPlot#includeQwtPlotGrid#includeQwtPlotCurve#includeQwtLegendQwtPlot*plotnewQwtPlot();plot-setTitle(网格配置示例);plot-setCanvasBackground(Qt::white);// 创建并配置网格QwtPlotGrid*gridnewQwtPlotGrid();grid-enableX(true);grid-enableY(true);grid-enableXMin(true);// 启用次网格grid-enableYMin(true);// 主网格用灰色实线次网格用浅灰色点线grid-setMajorPen(QPen(QColor(150,150,150),1.0,Qt::SolidLine));grid-setMinorPen(QPen(QColor(220,220,220),0.0,Qt::DotLine));grid-attach(plot);// 添加一条正弦曲线QwtPlotCurve*curvenewQwtPlotCurve(信号);QPolygonF points;for(inti0;i100;i){doublexi;doubley5030*std::sin(i*0.1);pointsQPointF(x,y);}curve-setSamples(points);curve-setPen(QPen(Qt::blue,2.0));curve-attach(plot);plot-setAxisScale(QwtAxis::XBottom,0,100);plot-setAxisScale(QwtAxis::YLeft,0,100);plot-replot();3.4 网格核心方法速查方法说明enableX(bool)启用/禁用 X 轴主网格enableY(bool)启用/禁用 Y 轴主网格enableXMin(bool)启用/禁用 X 轴次网格enableYMin(bool)启用/禁用 Y 轴次网格setMajorPen()设置主网格画笔setMinorPen()设置次网格画笔setXDiv()手动设置 X 轴刻度划分setYDiv()手动设置 Y 轴刻度划分四、图例 QwtLegend图例用于标识不同曲线或数据系列的含义是多人阅读图表时的必备元素。Qwt 7.0 提供了两种图例方式外部图例QwtLegend和内嵌图例QwtPlotLegendItem。4.1 外部图例外部图例独立于画布占用绘图区域的边缘空间#includeQwtLegend// 创建并插入图例放在右侧QwtLegend*legendnewQwtLegend();plot-insertLegend(legend,QwtPlot::RightLegend);// 其他位置选项// QwtPlot::LeftLegend - 左侧// QwtPlot::BottomLegend - 底部// QwtPlot::TopLegend - 顶部// 第三个参数控制图例占比0.0~1.0// plot-insertLegend(legend, QwtPlot::RightLegend, 0.2); // 占20%宽度下图是图例演示效果展示了多条曲线的图例显示4.2 图例交互默认情况下点击图例项可以切换对应曲线的显示/隐藏状态这是非常实用的交互功能// 可点击模式默认——点击切换曲线显示legend-setItemMode(QwtLegend::ClickableItem);// 只读模式——仅展示不可点击// legend-setItemMode(QwtLegend::ReadOnlyItem);4.3 绘图项的图例属性每条曲线可以控制自己在图例中的显示方式QwtPlotCurve*curvenewQwtPlotCurve(曲线A);// 控制图例图标显示内容curve-setLegendAttribute(QwtPlotCurve::LegendShowLine,true);// 显示线条curve-setLegendAttribute(QwtPlotCurve::LegendShowSymbol,true);// 显示符号curve-setLegendAttribute(QwtPlotCurve::LegendShowBrush,true);// 显示填充// 设置图例图标大小curve-setLegendIconSize(QSize(20,15));4.4 内嵌图例如果不想让图例占用绘图边缘的空间可以使用QwtPlotLegendItem将图例直接绘制在画布上#includeQwtPlotLegendItem// 创建内嵌图例作为绘图项附加到画布QwtPlotLegendItem*legendItemnewQwtPlotLegendItem();legendItem-attach(plot);// 设置位置legendItem-setPosition(QwtPlotLegendItem::TopRight);// 右上角// 设置背景和边框legendItem-setBackgroundBrush(QBrush(Qt::white));legendItem-setBorderPen(QPen(Qt::gray,1));// 设置最大列数legendItem-setMaxColumns(1);内嵌图例的好处是它浮在画布上方不占用布局空间适合空间紧凑的场景。4.5 图例使用建议曲线数量推荐方案少量5条右侧外部图例中等5-10条底部外部图例大量10条内嵌图例或分组显示五、刻度朝内显示7.2.1 新增这是 Qwt 7.0 系列中一个虽小但实用的功能。从 7.2.1 版本开始Qwt 支持将坐标轴刻度线显示在绘图区域内部而非传统的朝外显示。5.1 什么是刻度朝内传统绘图中刻度线从轴线向外延伸。而刻度朝内功能将刻度线从画布边缘向内延伸刻度标签仍然保持在外部刻度朝外默认: 刻度朝内: ────┼────┼────┼────→ ────┼────┼────┼────→ │ │ │ │ │ │ ← 向内延伸 0 2 4 0 2 4 ┌────────────────┐ │ ← 刻度伸入画布 │ └────────────────┘5.2 使用方法API 非常简洁一个方法搞定#includeQwtPlot// 设置 YLeft 轴刻度朝内plot-setAxisTickDirection(QwtAxis::YLeft,QwtPlot::TickInside);// 设置 XBottom 轴刻度朝内plot-setAxisTickDirection(QwtAxis::XBottom,QwtPlot::TickInside);// 刷新显示plot-replot();枚举值说明枚举值说明QwtPlot::TickOutside刻度朝外默认行为QwtPlot::TickInside刻度朝内从画布边缘向内延伸下图展示了刻度朝内的实际效果5.3 独立控制与批量设置每个坐标轴可以独立设置刻度方向也可以批量设置// 所有轴刻度朝内plot-setAxisTickDirection(QwtAxis::YLeft,QwtPlot::TickInside);plot-setAxisTickDirection(QwtAxis::YRight,QwtPlot::TickInside);plot-setAxisTickDirection(QwtAxis::XBottom,QwtPlot::TickInside);plot-setAxisTickDirection(QwtAxis::XTop,QwtPlot::TickInside);plot-replot();// 查询当前设置QwtPlot::TickDirection dirplot-axisTickDirection(QwtAxis::YLeft);if(dirQwtPlot::TickInside){qDebug()当前刻度朝内;}5.4 适用场景刻度朝内功能特别适合以下场景紧凑布局在有限的窗口空间中最大化绘图区域出版物图表很多学术期刊偏好刻度朝内的风格嵌入式界面屏幕空间宝贵的嵌入式设备界面注意朝内刻度自动继承朝外刻度的样式设置长度、线宽、颜色无需重复配置。该功能还可与寄生轴Parasite Plot配合使用每个寄生绘图可独立设置刻度方向。六、与旧版本的区别如果你从原版 Qwt 6.2.0 迁移到 Qwt 7.0坐标轴系统有几个重要变化需要了解6.1 QwtAxisId 多轴架构7.0 新增原版 Qwt 6.2.0 的坐标轴系统只支持固定四个轴yLeft、yRight、xBottom、xTop每个位置只能有一个轴。Qwt 7.0 引入了QwtAxisId架构每个轴由Position 序号组成支持在同一位置放置任意多个坐标轴。通过QwtPlot::createParasitePlot()可以创建寄生绘图共享宿主画布区域但拥有独立的坐标轴。这意味着你可以同时在左侧放两个、三个甚至更多 Y 轴彻底突破了原版四轴限制。6.2 刻度朝内显示7.2.1 新增原版 Qwt 6.2.0 不支持刻度朝内显示刻度线只能朝外。Qwt 7.2.1 通过setAxisTickDirection()方法新增了这一功能。6.3 坐标轴内置交互7.0 新增原版 Qwt 6.2.0 的坐标轴控件不支持直接交互。Qwt 7.0 为QwtScaleWidget新增了内置平移和缩放功能用户可以直接在坐标轴上拖动浏览数据。6.4 兼容性Qwt 7.0 保留了旧版的Axis枚举兼容通过QWT_AXIS_COMPAT宏原来的QwtPlot::yLeft等写法仍然可用迁移成本很低。特性原版 Qwt 6.2.0Qwt 7.0坐标轴数量固定4个任意多轴QwtAxisId刻度朝内不支持7.2.1 支持坐标轴交互无内置平移/缩放旧枚举兼容-通过 QWT_AXIS_COMPAT 宏七、总结本篇全面介绍了 Qwt 7.0 的坐标轴与刻度系统刻度引擎是坐标轴的核心——线性引擎适合常规数据对数引擎适合大范围数据日期引擎适合时间序列。特殊需求可以手动创建QwtScaleDiv完全控制刻度位置。坐标轴控件提供了从标题、字体到刻度标签格式的全面自定义能力。Qwt 7.0 还新增了坐标轴内置交互功能。网格线自动跟随刻度变化主/次网格可独立控制样式是提升图表可读性的利器。图例系统支持外部图例和内嵌图例两种方式点击图例项可切换曲线显示状态。刻度朝内显示是 Qwt 7.2.1 的新功能通过简单的setAxisTickDirection()调用即可实现紧凑布局效果。QwtAxisId 多轴架构是 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

相关新闻