热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Qt绘制热力图

0.前言热力图是一种重要的数据可视化方式,可以直观地展现空间数据的疏密程度或频率高低。本文将使用QPainter+QImage来实现热力图绘制,效果参照百度ECharts图表库:《
0.前言

热力图是一种重要的数据可视化方式,可以直观地展现空间数据的疏密程度或频率高低。本文将使用QPainter+QImage来实现热力图绘制,效果参照百度ECharts图表库:

《Qt绘制热力图》

《从前慢》 ——–木心

记得早先少年时

大家诚诚恳恳

说一句 是一句

清早上火车站

长街黑暗无行人

卖豆浆的小店冒着热气

从前的日色变得慢

车,马,邮件都慢

一生只够爱一个人

从前的锁也好看

钥匙精美有样子

你锁了 人家就懂了

目录

1.实现思路

2.实现细节

3.代码链接

4.参考

1.实现思路

主要步骤如下:

a.每个单独的点为径向渐变色的圆,且透明度从中心到边缘逐渐降低

QRadialGradient gradient(posX,posY,radius); //径向渐变
gradient.setColorAt(0,QColor(0,0,0,alpha)); //点的透明度
gradient.setColorAt(1,QColor(0,0,0,0));
painter.setBrush(gradient);
painter.drawEllipse(QPointF(posX,posY),radius,radius);

b.多个点组合时,透明度是互相叠加的,所以我们先用透明度绘制一个Image(透明度就表示热度)

//透明度用Format_Alpha8就行了
_dataImg=QImage(ImgWidth,ImgHeight,QImage::Format_Alpha8);
_dataImg.fill(Qt::transparent);
//接下来追加绘制圆点

c.如果一个点出现多次,那么就需要有权重的概念,可以根据重复最多的点来作为计算的标准,也可以根据重复次数分段

//权重统计表(把权重单独拿出来,就可以不用遍历数据点来计算了)
//加()初始化为0
int *_countTable=new int[ImgWidth*ImgHeight]();
//以最大次数来计算该点的权重
const uchar alpha=uchar(_countTable[posX+posY*ImgWidth]/(double)_maxCount*255);

d.透明度的图绘制完成后就可以填充颜色,颜色根据透明度从计算好的颜色表中查表获得

void MainWindow::drawHeatImg()
{
//把alpha值转为颜色值
for(int row=0;row<_dataImg.height();row++)
{
//dataimg QImage::Format_Alpha8,一个点1个字节
const uchar *line_data=_dataImg.scanLine(row);
//heatimg QImage::Format_ARGB32,一个点4个字节
QRgb *line_heat=reinterpret_cast(_heatImg.scanLine(row));
for(int col=0;col<_dataImg.width();col++)
{
//根据alpha透明度从颜色表取颜色
line_heat[col]=_colorList[line_data[col]];
}
}
}
2.实现细节

a.颜色表的实现

颜色表我使用的线性渐变会知道Image来取颜色的方式,因为单纯 QLinearGradient 好像没有取某个点颜色的接口;还有就是计算颜色透明度的时候可能要考虑热力图整体的透明度。

颜色表的元素类型为 QRgb ,是 uint32 的 typedef ,表示 #AARRGGBB。

//根据线性渐变色条得到颜色表
QLinearGradient linear=QLinearGradient(QPoint(0,0),QPoint(255,0));
linear.setColorAt(0, Qt::blue);
linear.setColorAt(0.4, Qt::blue);
linear.setColorAt(0.5, Qt::cyan);
linear.setColorAt(0.6, Qt::green);
linear.setColorAt(0.8, Qt::yellow);
linear.setColorAt(0.95, Qt::red); //255对应透明度最大值,即中心点
//把渐变色绘制到Img方便取颜色
QImage img(256,1,QImage::Format_ARGB32);
QPainter painter(&img);
painter.fillRect(img.rect(),linear);
//HeatAlpha为热力图整体透明度
quint32 alpha=0;
for(quint32 i=0;i<256;i++){
//根据热力图透明度来计算颜色表的透明度
alpha=HeatAlpha/255.0*i;
//typedef unsigned int QRgb: format #AARRGGBB
//颜色+透明度
_colorList[i]=img.pixel(i,0)&0x00FFFFFF|(alpha<<24);
}

b.点的追加

如果点不是重合的,那么直接在透明度图中追加绘制就行,如果点重合了,那么出于权重对透明度的影响,需要重新绘制透明度图。

//为什么不直接if(pos_count>_maxCount)才重新绘制?
//而是有两个点叠加if(pos_count>1)就重新绘制?
//因为单纯的叠加目前还没有带入权重来计算,如果最大权重更大,那么这个叠加的点颜色就走样了
if(pos_count>1){
if(pos_count>_maxCount)
_maxCount=pos_count;
drawDataImg();
}else{
drawDataPoint(pt);
}

c.透明度图转热力图

因为我们是先绘制的透明度图来表示热度,再通过透明度查表来填充的颜色,所以我们需要两个Image。

//data用alpha叠加
_dataImg=QImage(ImgWidth,ImgHeight,QImage::Format_Alpha8);
_dataImg.fill(Qt::transparent);
//热力图通过alpha值查表
_heatImg=QImage(ImgWidth,ImgHeight,QImage::Format_ARGB32);
_heatImg.fill(Qt::transparent);

 绘制热力图的时候,我们使用 QImage 的 scanLine() 函数,以及颜色查表来提高效率。

//把alpha值转为颜色值
for(int row=0;row<_dataImg.height();row++)
{
//dataimg QImage::Format_Alpha8,一个点1个字节
const uchar *line_data=_dataImg.scanLine(row);
//heatimg QImage::Format_ARGB32,一个点4个字节
QRgb *line_heat=reinterpret_cast(_heatImg.scanLine(row));
for(int col=0;col<_dataImg.width();col++)
{
//根据alpha透明度从颜色表取颜色
line_heat[col]=_colorList[line_data[col]];
}
}
3.代码链接

代码git链接:

https://github.com/gongjianbo/MyTestCode/tree/master/Qt/MyHeatMap

实现效果:

《Qt绘制热力图》

《Qt绘制热力图》

4.参考

JS版:https://blog.csdn.net/HiddlestonCloud/article/details/83743449

Qt版:https://blog.csdn.net/pbe_sedm/article/details/8982357


推荐阅读
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • 本文由编程笔记#小编整理,主要介绍了关于数论相关的知识,包括数论的算法和百度百科的链接。文章还介绍了欧几里得算法、辗转相除法、gcd、lcm和扩展欧几里得算法的使用方法。此外,文章还提到了数论在求解不定方程、模线性方程和乘法逆元方面的应用。摘要长度:184字。 ... [详细]
  • 单页面应用 VS 多页面应用的区别和适用场景
    本文主要介绍了单页面应用(SPA)和多页面应用(MPA)的区别和适用场景。单页面应用只有一个主页面,所有内容都包含在主页面中,页面切换快但需要做相关的调优;多页面应用有多个独立的页面,每个页面都要加载相关资源,页面切换慢但适用于对SEO要求较高的应用。文章还提到了两者在资源加载、过渡动画、路由模式和数据传递方面的差异。 ... [详细]
  • 用Vue实现的Demo商品管理效果图及实现代码
    本文介绍了一个使用Vue实现的Demo商品管理的效果图及实现代码。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • WPF开发心率检测大数据曲线图的高性能实现方法
    本文介绍了在WPF开发中实现心率检测大数据曲线图的高性能方法。作者尝试过使用Canvas和第三方开源库,但性能和功能都不理想。最终作者选择使用DrawingVisual对象,并结合局部显示的方式实现了自己想要的效果。文章详细介绍了实现思路和具体代码,对于不熟悉DrawingVisual的读者可以去微软官网了解更多细节。 ... [详细]
  • 本文介绍了在MFC下利用C++和MFC的特性动态创建窗口的方法,包括继承现有的MFC类并加以改造、插入工具栏和状态栏对象的声明等。同时还提到了窗口销毁的处理方法。本文详细介绍了实现方法并给出了相关注意事项。 ... [详细]
  • 本文介绍了lintcode(12)题目的要求和解题思路,以及给出了相应的代码实现。题目要求在给定的字符串source中找到包括所有目标字符串字母的最短子串,并且时间复杂度为O(n)。解题思路是使用滑动窗口的方法,通过维护一个unordered_map来记录目标字符串中每个字符的出现次数,并使用双指针来寻找最小子串。代码实现部分给出了具体的实现代码。 ... [详细]
  • 如何在HTML中获取鼠标的当前位置
    本文介绍了在HTML中获取鼠标当前位置的三种方法,分别是相对于屏幕的位置、相对于窗口的位置以及考虑了页面滚动因素的位置。通过这些方法可以准确获取鼠标的坐标信息。 ... [详细]
  • JavaScript和HTML之间的交互是经由过程事宜完成的。事宜:文档或浏览器窗口中发作的一些特定的交互霎时。能够运用侦听器(或处置惩罚递次来预订事宜),以便事宜发作时实行相应的 ... [详细]
  • 使用eclipse创建一个Java项目的步骤
    本文介绍了使用eclipse创建一个Java项目的步骤,包括启动eclipse、选择New Project命令、在对话框中输入项目名称等。同时还介绍了Java Settings对话框中的一些选项,以及如何修改Java程序的输出目录。 ... [详细]
  • 本文介绍了互联网思维中的三个段子,涵盖了餐饮行业、淘品牌和创业企业的案例。通过这些案例,探讨了互联网思维的九大分类和十九条法则。其中包括雕爷牛腩餐厅的成功经验,三只松鼠淘品牌的包装策略以及一家创业企业的销售额增长情况。这些案例展示了互联网思维在不同领域的应用和成功之道。 ... [详细]
author-avatar
red_小火柿子
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有