本文含 2648 字,20 图表截屏
建议阅读 15 分钟
0
引言
本文是 Python 系列的 Matplotlib 补充篇。整套 Python 盘一盘系列目录如下:
- Python 入门篇 (上)
- Python 入门篇 (下)
- 数组计算之 NumPy (上)
- 数组计算之 NumPy (下)
- 科学计算之 SciPy (上)
- 科学计算之 SciPy (下)
- 数据结构之 Pandas (上)
- 数据结构之 Pandas (下)
- 基本可视化之 Matplotlib
- 统计可视化之 Seaborn
- 炫酷可视化之 PyEcharts
- 交互可视化之 Cufflinks (上)
- 交互可视化之 Cufflinks (下)
- 机器学习之 Sklearn
- 机学可视化之 Scikit-Plot
- 深度学习之 Keras (上)
- 深度学习之 Keras (中)
- 深度学习之 Keras (下)
Matplotlib 最初在设计时仅考虑了二维绘图。但在其 1.0 版本后,一些构建在二维绘图基础上的三维绘图也可以使用了。要画三维(立体) 图,首先导入 mplot3d 工具包。
代码语言:javascript复制from mpl_toolkits import mplot3d
一旦 mplot3d 工具包被导入,创建立体图有两种方式:
- 用 fig = plt.figure()和 ax = mplot3d.Axes3D(fig)
- 用 fig = plt.figure()和 ax = plt.axes(projection='3d')
第二种方式更简单些。如果要同时生成图和坐标系,还可用以下语句:
fig, ax = plt.subplots(1, 1,
subplot_kw={'projection':'3d'})
三种生成立体图的方式是等价的,生成的图如下所示。
本帖只介绍三种类型的 3D 图,它们在量化金融中最常用的,分别是
- 线框图 (wide frame)
- 曲面图 (surface)
- 条形图 (bar)
1
线框图
画线框图和曲面图数据都使用外汇波动率数据,首先用 Pandas 从 excel 读取数据,该波动率平面有 10 个期限和 5 个价位。
代码语言:javascript复制FX_vol = pd.read_csv( 'FX Volatility.csv', index_col=0 )
FX_vol
画立体图首先用 np.meshgrid() 函数创建 (x, y) 平面的网格 X 和 Y,它们的形状都是 (10, 4)。
线框图采用值网格并将其投影到指定的三维表面上,用 plot_wireframe() 函数来实现,其参数 X, Y, Z 对应的每个点 (x, y, z) 可当成坐标画在立体图中。
2
曲面图
曲面图类似于线框图,把线框包围的多边形填充成面。用 plot_surface() 函数来实现,代码和上面几乎一样,参数 color 和 edgecolor 分别控制面和边的颜色。
还可设定参数 cmap 填充渐变色,并在图旁附上颜色条。
继续追求完美。
波动率平面是由不同期限上的波动率曲线组成的,了解金融市场数据的读者应该对波动率微笑(volatility smile) 这个词不陌生,“微笑”是固定某个期限观察曲线沿着价位维度呈现的形状。在立体图中添加折线用 plot3D() 函数来实现,由于在 3D 空间画 2D 折线,那么也需要传入xs, ys, zs 三个参数。如下面代码第 6 和 7 行所示,在一个 for 循环中,固定期限维度 ys 不断添加折线 (xs, zs),即沿着价位维度 xs 的波动率值 zs。
虽然上图的视角不错,但有时默认的视角不是最好的,通过
view_init(elev, azim)
函数可以调整角度,其中参数 elev 值是水平面 (z = 0) 的仰角度 (elevation angle),参数 azim 值是 (x, y) 坐标系的方位角度 (azimuth angle)。下图给出了参数为 (0, 0)、(0, 90) 和 (90, 0) 的视图。
代码语言:javascript复制fig, ax = plt.subplots(1,3, figsize=(16,6), subplot_kw={'projection':'3d'})
ax[0].view_init(0,0)
ax[0].set( title='elev=0, azim=0', xlabel='X', ylabel='Y', zlabel='Z' )
ax[1].view_init(0,90)
ax[1].set( title='elev=0, azim=90', xlabel='X', ylabel='Y', zlabel='Z' )
ax[2].view_init(90,0)
ax[2].set( title='elev=90, azim=0', xlabel='X', ylabel='Y', zlabel='Z' )
plt.show()
回到实际例子,x, y, z 对应的是价位、期限和波动率。下图画出视角为 (0, 0) 的图,可看出水平面仰角为 0,从该图可以明显看出,不论哪个价位,波动率随着期限变长而变大。
下图画出视角为 (0, 90) 的图,水平面仰角还是 0,从该图可看出,不论哪个期限,波动率在 10 put 价位最大。
下图画出视角为 (90, 0) 的图,水平面仰角是 90,感觉在俯视水平面,波动率值大小的信息完全丢失。
这样一看,本例还是用默认的视角好。
3
条形图
3D 条形图和 2D 条形图相比,扩展了比较信息的能力。下面代码比较二项分布和泊松分布的概率质量函数 (PMF)。
条形图中的每个条需要两个参数:位置和大小,对应着下面代码中的 (x, y, z) 和 (dx, dy, dz)。
- 位置是在立体图中的坐标,x 和 z 都好理解,由于在 y 轴上画两个分布,因此有两个 y 值
- 大小指的条形的长宽高,长 dx 和宽 dy 分别是 0.5 和 0.2,而高 dz 就是 PMF 值
当 M 为 20,p 为 0.5,λ 为 M 和 p 的乘积等于 10 时,二项分布和泊松分布的差别挺大的。
将 M 改成 100,p 改成 0.1 后,同样将 λ 设为 M 和 p 的乘积,再运行上面代码生成下图,发现二项分布和泊松分布的图几乎是一样的。这时因为当 M 值越大和 p 值越小的时候,两个分布越来越近似。