4. 数据可视化基础
数据可视化,说白了就是给枯燥的数字穿上漂亮的外衣。我刚开始做量化的时候,整天对着密密麻麻的行情数据,眼睛都快瞎了。后来才明白——你没法靠肉眼从一万个数字里找出规律,但一张图就能让你秒懂趋势。
这一章,咱们就聊聊怎么把数据变成图表。我会从最基础的 Matplotlib 讲起,再到专业的 K 线图绘制,最后聊聊交互式图表。嗯,都是我在实战中反复用到的工具。
4.1 Matplotlib 基础绘图
Matplotlib 是 Python 可视化的老大哥。几乎所有其他可视化库,底层都离不开它。我个人习惯把它当作「画板」,其他库都是「画笔」。
先看一个最简单的折线图:
import matplotlib.pyplot as plt
import numpy as np
# 模拟收盘价
days = np.arange(1, 31)
prices = 100 + np.cumsum(np.random.randn(30) * 2)
plt.plot(days, prices)
plt.title('模拟收盘价走势')
plt.xlabel('交易日')
plt.ylabel('价格')
plt.show()
这段代码跑出来,你会看到一条上下波动的曲线。但说实话,这种图在量化里用处不大——太粗糙了。
%matplotlib inline,否则图可能不显示。我当年被这个坑过,折腾了半小时。
Matplotlib 的核心概念就三个:Figure(画布)、Axes(坐标系)、Axis(坐标轴)。你可以把 Figure 想象成一张白纸,Axes 是纸上画图的位置,Axis 就是横轴纵轴上的刻度。
来个多子图的例子:
fig, axes = plt.subplots(2, 2, figsize=(10, 6))
axes[0, 0].plot(days, prices, 'b-')
axes[0, 0].set_title('收盘价')
axes[0, 1].hist(prices, bins=15, color='green', alpha=0.7)
axes[0, 1].set_title('价格分布')
axes[1, 0].plot(days, prices.cumsum(), 'r--')
axes[1, 0].set_title('累计收益')
axes[1, 1].scatter(days, prices, s=20, c='purple')
axes[1, 1].set_title('散点图')
plt.tight_layout()
plt.show()
你看,一个画布上放四个图,对比起来特别方便。我在做策略回测时,经常把净值曲线、回撤曲线、持仓比例放在一起看。
4.2 K 线图绘制(mplfinance)
做量化交易,K 线图是绕不开的。Matplotlib 原生画 K 线很麻烦,得自己画矩形和线条。好在有个专门的库——mplfinance,一行代码就能搞定。
先安装:
pip install mplfinance
然后准备数据。mplfinance 要求数据格式是 pandas DataFrame,索引是日期,列名必须包含 Open、High、Low、Close、Volume:
import pandas as pd
import mplfinance as mpf
# 模拟数据
dates = pd.date_range('2024-01-01', periods=100, freq='D')
data = pd.DataFrame({
'Open': np.random.uniform(100, 110, 100),
'High': np.random.uniform(105, 115, 100),
'Low': np.random.uniform(95, 105, 100),
'Close': np.random.uniform(100, 110, 100),
'Volume': np.random.randint(1000, 5000, 100)
}, index=dates)
# 画K线
mpf.plot(data, type='candle', volume=True, style='charles')
mplfinance 支持多种样式。我个人喜欢用 style='yahoo',红绿配色看着舒服。你还可以加均线:
mpf.plot(data, type='candle', volume=True,
mav=(5, 10, 20), style='yahoo')
mav 参数就是移动平均线,传入一个元组,分别表示 5 日、10 日、20 日均线。嗯,这个在技术分析里太常用了。
4.3 技术指标可视化
光看 K 线还不够,咱们得把技术指标叠加上去。这里以均线和布林带为例。
4.3.1 均线叠加
其实 mplfinance 自带的 mav 参数就能画均线。但如果你想自定义颜色、线型,就得自己算:
# 自己计算均线
data['MA5'] = data['Close'].rolling(5).mean()
data['MA20'] = data['Close'].rolling(20).mean()
# 用 Matplotlib 画
plt.figure(figsize=(12, 6))
plt.plot(data.index, data['Close'], label='收盘价', alpha=0.6)
plt.plot(data.index, data['MA5'], label='5日均线', linewidth=1.5)
plt.plot(data.index, data['MA20'], label='20日均线', linewidth=1.5)
plt.legend()
plt.title('收盘价与均线')
plt.show()
这里有个坑:rolling 窗口期内的前几个值会是 NaN。比如 5 日均线,前 4 天没有值。画图时 Matplotlib 会自动跳过 NaN,但如果你要做计算,记得用 dropna() 处理。
4.3.2 布林带
布林带由中轨(20日均线)、上轨(中轨+2倍标准差)、下轨(中轨-2倍标准差)组成。代码实现:
# 计算布林带
data['Middle'] = data['Close'].rolling(20).mean()
data['Std'] = data['Close'].rolling(20).std()
data['Upper'] = data['Middle'] + 2 * data['Std']
data['Lower'] = data['Middle'] - 2 * data['Std']
# 画图
plt.figure(figsize=(12, 6))
plt.plot(data.index, data['Close'], label='收盘价', color='blue', alpha=0.5)
plt.plot(data.index, data['Middle'], label='中轨', color='orange', linestyle='--')
plt.plot(data.index, data['Upper'], label='上轨', color='red', linestyle=':')
plt.plot(data.index, data['Lower'], label='下轨', color='green', linestyle=':')
plt.fill_between(data.index, data['Upper'], data['Lower'], alpha=0.1, color='gray')
plt.legend()
plt.title('布林带')
plt.show()
4.4 交互式图表(Plotly 基础)
静态图有个问题——你没法缩放、悬停看数值。尤其是做回测分析时,我想看某一天的详细数据,静态图就无能为力了。这时候 Plotly 就派上用场了。
Plotly 生成的图表是 HTML 格式,可以在浏览器里交互。安装:
pip install plotly
来个交互式 K 线图:
import plotly.graph_objects as go
fig = go.Figure(data=[go.Candlestick(
x=data.index,
open=data['Open'],
high=data['High'],
low=data['Low'],
close=data['Close'],
name='K线'
)])
fig.update_layout(
title='交互式K线图',
xaxis_title='日期',
yaxis_title='价格',
xaxis_rangeslider_visible=False # 去掉底部滑块
)
fig.show()
鼠标悬停在 K 线上,会显示当天的 O、H、L、C 数据。还能用滚轮缩放,拖拽平移。说实话,自从用了 Plotly,我回测时基本不用静态图了。
再加个均线:
fig.add_trace(go.Scatter(
x=data.index, y=data['MA5'],
mode='lines', name='5日均线',
line=dict(color='orange', width=1)
))
fig.add_trace(go.Scatter(
x=data.index, y=data['MA20'],
mode='lines', name='20日均线',
line=dict(color='purple', width=1)
))
fig.show()
fig.show() 会直接显示交互图。如果要在网页上展示,可以用 fig.write_html('chart.html') 保存成独立文件。我经常把回测结果生成 HTML 图表,发给团队同事看,他们不用装 Python 也能打开。
4.5 本章知识体系
下面这张图,帮你理清数据可视化的核心脉络:
从这张图能看出来,四个分支层层递进。先掌握 Matplotlib 的基础概念,再学专业的 K 线绘制,然后叠加技术指标,最后用交互式图表提升分析效率。我个人建议的学习顺序也是这样——别一上来就搞 Plotly,先把静态图玩明白。
好了,数据可视化的基础就聊到这儿。记住一句话:图表是给人类看的,不是给机器看的。做量化交易,你首先要让自己看懂数据,然后才能让策略跑起来。下一章咱们会聊更高级的可视化技巧,但今天这些内容,足够你应付大部分日常分析了。