使用gnuplot绘制散点密度图

类别:    标签: gnuplot   阅读次数:   版权: (CC) BY-NC-SA

这篇文章来源于看到的一个回答Gnuplot: Scatter plot and density. 因为我需要绘制类似的图, 就花时间研究了一下链接中所提供的方法, 并进行了一点改进, 记在这里供需要的人参考.

首先明确一下问题: 有一组二维点, (xi, yi), i=1, 2, 3, …, n. 这些点之间存在较大程度的重叠, 我们将其绘制在平面上时想尽量直观地给出点分布的疏密情况.

下面以一个具体示例展开讨论. 我们分别以 (0, 0) 和 (2, 2) 为中心生成两组服从标准正态分布的点, 每组1000点, 共2000点.

直接绘制如下

可以看到, 直接绘制时很多点会重叠在一起, 导致无法直观地感受到数据点分布的疏密.

一种稍好点的绘制方式是使用透明度, 这样点密的位置, 看起来颜色会更深一些.

这种做法存在的问题是透明度数值的选取. 虽然也有一些方法可以估算最佳透明度, 但还是麻烦.

更好的做法是根据每个点周围其他点的密度来进行着色(或设置透明度), 一开始的链接所提供的方法就是这样. 为此, 我们先统计好每个点周围一定半径内分布的点数, 然后利用其作为点的着色变量.

我们设定统计半径为 0.1, 然后统计绘制

这个方法, 简单粗暴, 但就是慢. 因为要计算每个点到周围其他点的距离, 时间复杂度为o(N^2), 对上面测试的2000个点, 需要计算4百万次距离. 对其他脚本语言来说, 这可能不算什么, 但对gnuplot而言已经慢得有点无法接受了.

当然, 我们可以优化下距离的计算方法, 如避免使用平方根, 先进行简单判断等, 但这些都无法改进时间复杂度, 改进效果不大.

要进一步提供计算速度, 容易想到的是, 在统计每个点周围一定半径内的其他点时, 距离过大的点实际是不需要计算的, 这样的话, 我们可以先将每个点划分到一定的格子中, 在数算时只统计相邻格子中的点即可. 这种方法其实就是MD中常用的邻区搜索, 利用它可以将复杂度降低为o(N).

如果观察所得的图形, 可以发现另一问题, 那就是有些点的颜色仍然会有重叠, 导致疏密和颜色的对应并不明显. 简单的解决方法是先获得每个点周围其他点的个数, 再根据疏密进行排序, 绘制时先绘制密度低的点再绘制密度高的点, 这样颜色与疏密的对应看起来更合理.

既然我们可以分格子, 那么直接计算每个格子中点的个数, 处于同一格子中的点使用同一数据进行绘制即可. 这样虽然失去了点的具体位置信息, 但速度会有巨大提升.

当然, 我们也可以根据分格子后的数据绘制成二维密度图

◆本文地址: , 转载请注明◆
◆评论问题: https://jerkwin.herokuapp.com/category/3/博客, 欢迎留言◆


前一篇: gnuplot绘图的坐标系统
后一篇: dssp数据绘图脚本dssp2gp

访问人次(2015年7月 9日起): | 最后更新: 2024-05-14 14:45:30 UTC | 版权所有 © 2008 - 2024 Jerkwin