• 26017阅读
  • 23回复

用 Qt 生成热图(heat map) [复制链接]

上一主题 下一主题
离线pbe_sedm
 

图酷模式  只看楼主 倒序阅读 楼主  发表于: 2013-05-25
热图有时候叫热区图或者热力图,都是用于表现某种事物密集度的图形显示
我写的这个没有画底图,不然会更有趣,比如一个键盘,一张房屋平面图,或者一张Google地图,拿它做什么用,完全取决于你的需要。

一、主要用途
1、网站设计,可以帮助设计人员知道用户喜欢点哪些地方,对哪些东西感兴趣,以此来改良设计,改善用户体验,百度和腾讯都有提供此类有偿服务。 对位置不敏感,就比如有张全身照的美女图,通过统计就可以知道别人最喜欢看美女的哪个部位,是不是很有意思。
2、模拟分布,比如气象云图、无线射频信号的分布等等,都可以用这个来做。
3、众多例子:http://www.patrick-wied.at/static/heatmapjs/showcases.html

二、原理
1、首先可以参考下面几个链接
     JavaScript:  [一个用canvas画热力图的利器] http://www.cnblogs.com/bdqlaccp/archive/2012/09/12/2681518.html
            jQuery:  [浅谈Heatmap] http://huoding.com/2011/01/04/39
           Python:  [pyHeatMap : 使用Python绘制热图的库] http://oldj.net/article/python-heat-map/
2、基本原理:
      A、创建一个跟图片大小或者网页或者窗口一样大小的二维数组(可用一维实现),例如图片分辨率为1024x768,则你的二维数组为768行,1024列,数据所有元素均初始化为0。
      B、准备两张同样大小的画布(在Qt下可用QImage,在JavaScript下可用canvas,在Python下可用PIL库的Image),一张用于绘制灰度渐变圆圈(假设为 Alpha_Canvas),一张用于着色后显示输出(Output_Canvas)。
      C、准备一个调色板,调色板从0到255填充上线性渐变的颜色,这个颜色可根据需要自由指定,调色板主要用于着色操作中取颜色。
      D、我们假设在画布上点击一下算是采一个点,则点击一下对应的数组元素的值增加1,用于标识该位置(又)被点击了一次。
      E、我们保存一个整个数组中单个位置被点击次数最多的值(假设为:max),比如在整个画布中,(10,10)这个位置被点击了20次,而其他所有点均在该点的点击次数之下,则20被存储到该变量(max)中。这就意味着每点击一次都要拿当前坐标点的点击次数和最大点击次数相比,如果最大点击次数小于当前点击次数,则更新最大点击次数,并重新绘制整个图。
      F、选择Alpha_Canvas画布,在被点击的地方绘制一个径向渐变的圆,圆心为被点击的坐标,半径可根据需要自由设置,径向渐变圆的是灰度渐变圆圈,整个径向渐变圆圈是一个黑色圆圈,但圆心的颜色要比边界的深,而圆心的Alpha通道值是该点的被点击次数(假设为:current_count)与被点击次数最多的值之比乘以255(255要根据你的绘图环境来确定,在Qt中255表示完全不透明,0表示完全透明),即公式:current_count/max*255。
      G、选择Output_Canva画布,进行着色操作,根据上一步的圆心和半径可确定一个矩形区域,如果是重绘操作,则该矩形区域为整个图形区域。对该矩形区域进行遍历,取出Alpha_Canvas画布上每个颜色点的Alpha通道值,根据此值从调色板上取出对应的颜色,R、G、B三个值用从调色板取来的值,但Alpha通道值不能相同,在这里可以设置一个阈值,用于决定渐变开始的半径,也可以自由修改。将这四个值决定的颜色点绘制到Output_Canvas画布上,依此操作,直至遍历结束。
      H、完成着色操作后,整个绘图过程就完毕了。
3、开源项目
     JavaScript 版本:[heatmap.js]   http://www.patrick-wied.at/static/heatmapjs/index.html
     Python 版本:[pyHeatMap]  https://github.com/oldj/pyheatmap
     C++/Qt版本:[QHeatMap]   https://github.com/pbesedm/QHeatMap [本人实现]
4、JavaScript、Python、C++三种实现方法都有,相信你能明白原理,不明白请回复或联系我。

三、截图




























离线pxiao_xiao

只看该作者 1楼 发表于: 2013-06-29
这是好贴啊 咋没人回复
离线XChinux

只看该作者 2楼 发表于: 2013-06-29
需要用到这个的朋友自然有用,哈哈,大多数人碰不到这类需求.
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线zinsser

只看该作者 3楼 发表于: 2013-06-29
对于这一类等值云图,用OpenGL实现似乎更为直接。但若要绘制等值线图,不知道有没有什么成熟的解决方案?
离线pbe_sedm

只看该作者 4楼 发表于: 2013-06-30
如果把思路拓展一下,这种解决问题的方法可以在很多地方用得上,比如频谱分析的密度图,光谱图之类的,具体细节就不聊了,有心的朋友肯定能发现它的价值。
离线e730052
只看该作者 5楼 发表于: 2013-07-01
这种程度,算完美了。
离线voidbroken

只看该作者 6楼 发表于: 2013-07-03
好贴
离线pamxy

只看该作者 7楼 发表于: 2013-07-25
果断收藏了 _  _
你不是最优秀的,但你可以成为最优秀的, you are the best!
在线realfan

只看该作者 8楼 发表于: 2013-07-26
很专业
离线似水流年

只看该作者 9楼 发表于: 2013-07-27
引用楼主pbe_sedm于2013-05-25 13:43发表的 用 Qt 生成热图(heat map) :
热图有时候叫热区图或者热力图,都是用于表现某种事物密集度的图形化显示。
我写的这个没有画底图,不然会更有趣,比如一个键盘,一张房屋平面图,或者一张Google地图,拿它做什么用,完全取决于你的需要。
一、主要用途
1、网站设计,可以帮助设计人员知道用户喜欢点哪些地方,对哪些东西感兴趣,以此来改良设计,改善用户体验,百度和腾讯都有提供此类有偿服务。 对位置不敏感,就比如有张全身照的美女图,通过统计就可以知道别人最喜欢看美女的哪个部位,是不是很有意思。
.......


离线neil-wen

只看该作者 10楼 发表于: 2013-08-08
不错  很好
离线kelvinyeah
只看该作者 11楼 发表于: 2013-08-12
Professional,应该医疗领域用的比较多吧!好东西!
工作与IT关系不大了,从此将编程当乐趣发展!

只看该作者 12楼 发表于: 2013-12-20
好东西就是需要被顶。。。
博客地址:https://waleon.blog.csdn.net
微信公众号:高效程序员
QQ 群:242790253
微信群:加微信(iwaleon),邀请入群。

承接各种 C++/Qt/QML 项目,专业的团队,一流的服务,不二的选择!
离线量子飞跃

只看该作者 13楼 发表于: 2013-12-21
高端 大气 让我想起了卫星云图

只看该作者 14楼 发表于: 2014-03-18
您好!我现在想通过很多点数据(包含经纬度),制作热力地图反映哪些区域的点分布比较密集。 了解了百度热力图API示例(http://developer.baidu.com/map/jsdemo.htm#c1_15),源代码中的point带有count属性,这里count是表达什么含义?另外,我的实验点数据仅仅包含经纬度信息,不知道能否通过百度API实现热力地图?
离线foxgod

只看该作者 15楼 发表于: 2014-03-19
回 月亮加加加 的帖子
月亮加加加:您好!我现在想通过很多点数据(包含经纬度),制作热力地图反映哪些区域的点分布比较密集。 了解了百度热力图API示例(http://developer.baidu.com/map/jsdemo.htm#c1_15),源代码中的point带有count属性,这里count是表达什么含义?另外,我的实验点数据仅仅包含经纬度信息,不 .. (2014-03-18 18:40) 

你说我想写个程序,通过手机GPRS知道对方在百度地图上什么位置,应该怎么写??
离线woshizfs

只看该作者 16楼 发表于: 2014-03-19
编译的时候怎么报错:
F:\opensource\QHeatMap-master\QHeatMap-master\test\mainwindow.cpp:36: 错误:no matching function for call to 'QImage::fill(QColor)'
kuai
离线pbe_sedm

只看该作者 17楼 发表于: 2014-03-23
回 woshizfs 的帖子
woshizfs:编译的时候怎么报错:
F:\opensource\QHeatMap-master\QHeatMap-master\test\mainwindow.cpp:36: 错误:no matching function for call to 'QImage::fill(QColor)' (2014-03-19 10:18) 

你Qt版本是不是太旧了?
离线hss2799

只看该作者 18楼 发表于: 2014-06-16
很好,谢谢分享。
离线theotherone

只看该作者 19楼 发表于: 2014-08-08
我想问的是,如果两个渐变圆圈重合的地方,alpha值怎么确定?
屌丝程序猿,努力更屌丝  
博客:http://fearlazy.com
离线xubo6496918

只看该作者 20楼 发表于: 2014-09-12
感谢楼主!
离线huangturen

只看该作者 21楼 发表于: 2014-09-15
不能用啊!!!
C:\Users\biye\Downloads\QHeatMap-master\test\gradientpalette.cpp:22: error: C2614: “GradientPalette”: 非法的成员初始化:“gradient_”不是基或成员
C:\Users\biye\Downloads\QHeatMap-master\test\gradientpalette.cpp:42: error: C2065: “gradient_”: 未声明的标识符

等等!
离线nwnmrj

只看该作者 22楼 发表于: 2015-06-07
好东西!
离线x85371169

只看该作者 23楼 发表于: 2017-10-17
绘图速度比js版本慢了好多好多
快速回复
限100 字节
 
上一个 下一个