3. 联合分布的基本可视化

成交笔数与成交量这两个变量,单独看各自都只是一个一维分布:笔数告诉我们某段时间内成交被拆成了多少笔,成交量告诉我们这段时间一共成交了多少手。但真正决定盘口“质感”的,是两者的联合形态——同样是一万手成交量,拆成 20 笔和拆成 2000 笔,对应的市场含义完全不同。要看清这种联合结构,最直接的手段就是把每一根 K 线(或每一个时间切片)表示成平面上的一个点,横轴放成交笔数,纵轴放成交量,然后观察点云如何聚集、如何延展、哪里出现孤立的离群点。

本节围绕三种可视化工具展开:二维直方图负责呈现“密度”,散点图负责呈现“个体与异常”,六边形分箱图则在两者之间取得平衡。三者不是互相替代的关系,而是从粗到细、从整体到局部的三层观察视角。

先明确坐标与数据口径

在动手画图之前,必须先固定口径,否则图形会失去可比性。约定如下:横轴为成交笔数 N(单位:笔),纵轴为成交量 V(单位:手),每个样本点对应一个等长时间切片(例如 1 分钟或 1 根日 K)。由于成交量通常跨越数个数量级,纵轴建议使用对数刻度 log10(V),否则绝大多数点会被压缩在底部,聚集结构完全看不出来。横轴在笔数跨度较大时同样可取对数。本文后续示例统一采用“横轴线性、纵轴对数”的约定,若切换为双对数,需在图中明确标注。

为了便于说明,构造一组教学示例数据(以下数值为合理假设,非实测):某标的 240 个分钟切片中,多数切片笔数集中在 80~400 笔、成交量在 200~3000 手之间,形成一条沿对角线方向延伸的主聚集带;另有约 6 个切片笔数超过 1500 笔但成交量不足 500 手,属于“高笔数、低量”的拆单密集区;还有 3 个切片成交量超过 20000 手而笔数仅 30 余笔,属于典型的大单扫货离群点。

成交笔数 N — 成交量 V 联合分布的三层观察 横轴:成交笔数(笔) 纵轴:成交量(手,对数刻度) ① 二维直方图 看密度:主聚集带在哪 大单 拆单 笔数 N V 颜色越深=落入该格样本越多 ② 散点图 看个体:离群点是谁 笔数 N V 大单扫货 拆单密集 ③ 六边形分箱图 看结构:密度与形状兼顾 笔数 N V 六边形面积固定,颜色编码计数 主聚集带:笔数与成交量同向增长,是正常交易节奏的“脊线”; 偏离脊线的两翼——左上(低笔数高量)与右下(高笔数低量)——正是需要重点识别的异常区域。

二维直方图:先把“密度地形”画出来

二维直方图的做法是把平面划分成规则的矩形网格,统计落入每个格子的样本数,再用颜色深浅或高度表示计数。它最大的价值是抗噪:单个异常点不会改变整体形状,主聚集带的位置、走向和宽度一目了然。实现上,先对 N 和 log10(V) 分别确定分箱边界,例如笔数按 50 笔一档、对数成交量按 0.2 一档,然后用二维计数矩阵渲染热力图。

import numpy as np
import matplotlib.pyplot as plt

# N: 成交笔数数组, V: 成交量数组(示例数据)
logV = np.log10(V)
xbins = np.arange(0, 2000, 50)
ybins = np.arange(1.5, 5.0, 0.2)

H, xe, ye = np.histogram2d(N, logV, bins=[xbins, ybins])
plt.pcolormesh(xe, ye, H.T, cmap="Blues")
plt.xlabel("成交笔数 N")
plt.ylabel("log10(成交量 V)")
plt.colorbar(label="样本计数")

读图时关注三件事:第一,颜色最深的格子连成的“脊线”斜率是多少,斜率接近 1 说明笔数与成交量近似同比例增长,斜率明显小于 1 则说明大成交量往往由少数大单完成;第二,脊线的宽度反映正常波动的离散程度,可作为后续判定离群的尺度基准;第三,脊线之外是否存在次级热点,例如右下角出现一块独立的浅色区域,往往对应程序化拆单行为。二维直方图的局限也很明显:分箱边界敏感,格子太粗会抹平结构,太细则每格样本稀少、颜色噪声大,而且它无法告诉你具体是哪一根 K 线落在异常格里。

散点图:把每个样本还原成个体

散点图不做任何聚合,每个切片一个点,因此它保留了全部个体信息,是识别离群点最直接的工具。上面示例中,红色点位于左上区(笔数 30 余笔、成交量超 2 万手),对应大单集中成交;橙色点位于右下区(笔数超 1500 笔、成交量不足 500 手),对应高频拆单。这两类点在二维直方图中只能表现为一个孤立的浅色格子,而在散点图中可以直接定位到具体时间切片,进而回查当时的盘口与消息面。

散点图的实用技巧是叠加参考线而非凭肉眼判断。常用做法是以主聚集带的中位斜率构造一条基准线 log10(V) = a + b·log10(N),再计算每个点到该线的垂直残差,残差超过 2 倍标准差的点标记为离群。这样“离群”就有了可复现的量化标准,而不是主观印象。当样本量达到数千以上时,散点会严重重叠,此时应降低点的不透明度(如 alpha=0.3)或改用六边形分箱。

六边形分箱图:密度与形状的折中

六边形分箱图(hexbin)用正六边形代替矩形网格。相比方形网格,六边形在相同面积下邻接关系更均匀,不会因为对角方向的距离偏大而产生视觉上的“十字纹”伪结构,因此更适合表现沿斜向延伸的聚集带。它的每个六边形面积固定,颜色编码该箱内的样本计数,本质上是一张平滑过的二维直方图,但形状更贴近真实点云的轮廓。

plt.hexbin(N, logV, gridsize=30, cmap="Purples", mincnt=1)
plt.xlabel("成交笔数 N")
plt.ylabel("log10(成交量 V)")
plt.colorbar(label="箱内计数")

参数 gridsize 控制六边形的疏密,取值越大分箱越细。实践中可先用 20~30 观察整体形态,再调大到 50 左右检查局部结构是否稳定;若两种粒度下主聚集带的位置和离群区域基本一致,说明结论稳健。注意 mincnt=1 会隐藏空箱,使图形更干净,但也可能掩盖“某区域完全没有样本”这一信息,分析稀疏区时应改为显示空箱。

三种图如何配合使用

合理的分析顺序是:先用二维直方图或六边形分箱图建立整体印象,确定主聚集带的位置、斜率与宽度,并圈出可疑的次级热点;再回到散点图,把可疑区域内的具体样本挑出来,核对时间戳、价格与盘口状态;最后把确认的离群点标注回分箱图上,形成一张既有全局结构又有具体案例的联合分布图。三者共用同一套坐标与口径,才能互相印证。

判断离群点时,务必区分“统计离群”与“业务异常”。统计上偏离主带 2 倍标准差的点未必是坏事,例如尾盘集合竞价的大单本就该表现为低笔数高量;反之,某些藏在主带内部的点虽然不离群,却可能因为笔数与成交量的比例突然反转而具有警示意义。图形负责发现候选,业务逻辑负责定性。
使用对数纵轴时,零成交量或零笔数的切片无法取对数,需在绘图前剔除或单独标记,否则会出现缺失值报错或坐标轴断裂。此外,不同标的的笔数量级差异很大,跨标的比较时应统一分箱边界或改用分位数分箱,避免图形形状被量级差异主导。