用 Python 画 K 线图,做量化的朋友一定要掌握的技能

用 Python 画 K 线图,做量化的朋友一定要掌握的技能

最近炒股的朋友们老问我:"花姐,你能不能教我用 Python 画个 K 线图,研究研究趋势?"

听到这个问题,我差点没一口奶茶喷出来。

"用 Python 画 K 线?当然能!而且还得是高大上的动态交互图!"

说实话,一开始我也觉得画 K 线挺麻烦的,要处理数据、搞清楚指标、还得美观......结果后来发现,Pyecharts 这个库真的太香了!

今天咱们就一起来画出一个漂亮的 K 线图,均线、成交量 指标都加上,让你在 Python 里玩转金融数据!🎉

1. 什么是 Pyecharts?

Pyecharts 是 Python 里的一个强大可视化库,基于百度 Echarts,支持各种图表:柱状图、折线图、饼图、K 线图等等。相比 Excel 或 Matplotlib,Pyecharts 生成的图表更美观,而且支持交互!

1.1 安装 Pyecharts?

用 pip 轻松搞定:

bash 复制代码
pip install pyecharts

装好以后,我们先来画个简单的折线图,看看效果。

1.2 画个简单的折线图

python 复制代码
from pyecharts.charts import Line
from pyecharts import options as opts

# 创建折线图对象
line = Line()

# 添加数据
line.add_xaxis(["周一", "周二", "周三", "周四", "周五"])
line.add_yaxis("股票价格", [10, 12, 15, 13, 17])

# 设置标题
line.set_global_opts(title_opts=opts.TitleOpts(title="股票价格变化"))

# 渲染成 HTML
line.render("line_chart.html")

运行后,会在本地生成一个 HTML 页面,你会看到一条简单的折线,鼠标移动上去还会有交互效果!💡

1.3 关键步骤介绍

1.3.1 模块导入(基石搭建)
python 复制代码
from pyecharts.charts import Line  
from pyecharts import options as opts

核心作用 :加载可视化工具包

Line:折线图绘制核心类

opts:样式配置工具箱(控制标题/坐标轴/颜色等)

1.3.2 画布初始化(创建舞台)
python 复制代码
line = Line()

本质 :创建空白绘图区域

• 类比:准备画布和画笔,准备绘制折线图

1.3.3 数据注入(填充内容)
python 复制代码
# X轴:维度数据(通常为分类数据)
.add_xaxis(["周一", "周二", "周三", "周四", "周五"])  

# Y轴:指标数据(数值序列)
.add_yaxis("股票价格", [10, 12, 15, 13, 17])

数据绑定

• X轴 → 横坐标标签(星期)

• Y轴 → 股价波动数值

扩展性 :可连续添加多个add_yaxis()绘制多指标对比

1.3.4 样式配置(美化定型)
python 复制代码
.set_global_opts(title_opts=opts.TitleOpts(title="股票价格变化"))

核心配置项

title_opts:主/副标题设置

tooltip_opts:悬浮提示框样式

axis_opts:坐标轴标签格式

可扩展配置:支持50+种样式参数调整

1.3.5 输出成果(生成文件)
python 复制代码
.render("line_chart.html")

输出特性

• 生成完整HTML5文件

• 自带交互功能(缩放/悬浮提示/下载)

• 跨平台兼容(浏览器直接打开)

2. 画一张完整的 K 线图!

知道了基础用法,接下来,我们用 pyecharts 画 K 线图,并加上均线、成交量、MACD 指标,让它更专业!

2.1 获取股票数据

这里我们用上篇文章中讲的AKShare库来获取股票日线行情数据,把数据转存成csv文件,这样方便我们测试。

python 复制代码
import akshare as ak

df = ak.stock_zh_a_hist(symbol="000001", period="daily", start_date="20230101", end_date="20250101" ,adjust="qfq")
df.to_csv("kdata.csv",index=False)

这是测试用的csv数据

2.2 准备数据

K 线图的数据格式要求:

python 复制代码
k_data = [
    [开盘价, 收盘价, 最低价, 最高价],
    [开盘价, 收盘价, 最低价, 最高价],
    ...
]

2.3 读取csv数据并做处理

python 复制代码
import pandas as pd

# 读取数据并排序
df = pd.read_csv("kdata.csv", parse_dates=["日期"])

# 数据预处理
df['日期'] = pd.to_datetime(df['日期']).dt.strftime('%Y-%m-%d')  # 格式化日期

df = df.sort_values("日期") # 安装日期排序

data = df[["开盘", "收盘", "最低", "最高"]].values.tolist()  # 生成K线数据序列
print(data)

2.4 画蜡烛图(K 线)

python 复制代码
from pyecharts.charts import Kline
from pyecharts import options as opts

# 创建K线图
kline = Kline()
kline.add_xaxis(df['日期'].tolist())  # X轴日期数据
kline.add_yaxis(
        series_name="k线",  # y轴名称
        y_axis=data,  # K线数据序列
        itemstyle_opts=opts.ItemStyleOpts(
            color="#ef232a",    # 上涨颜色(红色)
            color0="#14b143",   # 下跌颜色(绿色)
            border_color="#000",  # 统一黑色描边
            border_color0="#000"
        )
    )
    
kline.set_global_opts(
        title_opts=opts.TitleOpts(title="股票K线走势图", subtitle=df['股票代码'][0]),
        xaxis_opts=opts.AxisOpts(
            type_='category',
            axislabel_opts=opts.LabelOpts(rotate=45),  # 日期标签旋转45度
            splitline_opts=opts.SplitLineOpts(is_show=True)  # 显示网格线
        ),
        yaxis_opts=opts.AxisOpts(
            splitarea_opts=opts.SplitAreaOpts(
                is_show=True, 
                areastyle_opts=opts.AreaStyleOpts(opacity=1)
            ),is_scale=True # 启用自动缩放
        ),
        datazoom_opts=[  # 添加数据缩放控件
            opts.DataZoomOpts(
                is_show=True,
                type_="inside",
                xaxis_index=[0],
                range_start=50,
                range_end=100
            ),
            opts.DataZoomOpts(
                is_show=True,
                xaxis_index=[0],
                type_="slider",
                pos_top="90%",
                range_start=50,
                range_end=100
            )
        ]
    )

# 生成HTML文件
kline.render("stock_kline.html")

效果展示:

2.5 添加均线

python 复制代码
# 计算移动平均线 (处理前4个NaN值)
ma_periods = [5, 10, 20]
for period in ma_periods:
    df[f'MA{period}'] = df['收盘'].rolling(window=period).mean().bfill()
    
from pyecharts.charts import Line
# 创建均线叠加图
line = Line()

# 添加各周期均线
ma_colors = {
    5: {"color": "#FF0000", "width": 2},   # 红色5日均线
    10: {"color": "#0000FF", "width": 2},  # 蓝色10日均线
    20: {"color": "#00FF00", "width": 2}   # 绿色20日均线
}

for period in ma_periods:
    line.add_xaxis(df['日期'].tolist())
    line.add_yaxis(
        series_name=f"MA{period}",
        y_axis=df[f'MA{period}'].tolist(),
        symbol="circle",
        symbol_size=0,
        linestyle_opts=opts.LineStyleOpts(
            color=ma_colors[period]["color"],
            width=ma_colors[period]["width"]
        ),
        label_opts=opts.LabelOpts(is_show=False),  # 关闭数据点标签
        is_smooth=True,  # 平滑曲线
        z_level=1  # 确保均线显示在K线上方
    )
    
# 合并图表
overlap_kline = kline.overlap(line)

2.6 加入成交量柱状图

python 复制代码
# 生成涨跌颜色列表(与K线颜色同步)
df['color'] = df.apply(lambda x: "#ef232a" if x['收盘'] >= x['开盘'] else "#14b143", axis=1)

# 创建成交量柱形图
from pyecharts.charts import Bar
from pyecharts.commons.utils import JsCode

vol_bar = (
    Bar()
    .add_xaxis(df['日期'].tolist())
    .add_yaxis(
        series_name="",
        
        y_axis=df['成交量'].tolist(),
        itemstyle_opts=opts.ItemStyleOpts(
            color=JsCode('''
                function(params) {
                    var colors = [%s];  
                    return params.dataIndex < colors.length ? colors[params.dataIndex] : '#14b143';
                }
            ''' % ("'" + "','".join(df['color'].tolist()) + "'"))  # 生成正确数组格式
        ),
        yaxis_index=1,
        bar_width='60%',
        label_opts=opts.LabelOpts(is_show=False)
    )
    .set_global_opts(
        xaxis_opts=opts.AxisOpts(
            type_="category",
            axislabel_opts=opts.LabelOpts(is_show=False),
            splitline_opts=opts.SplitLineOpts(is_show=False)
        ),
        yaxis_opts=opts.AxisOpts(
            position="right",
            axislabel_opts=opts.LabelOpts(formatter=JsCode(
                "function(value){return value > 10000 ? (value/10000).toFixed(1)+'万' : value;}"))
        )
    )
)

# 组合图表布局
from pyecharts.charts import Grid

grid = (
    Grid(init_opts=opts.InitOpts(width="1200px", height="800px"))
    .add(
        overlap_kline,  # 使用已合并的K线均线图
        grid_opts=opts.GridOpts(
            pos_left="10%", 
            pos_right="8%", 
            height="65%",  # 主图高度65%
            pos_top="10%"
        )
    )
    .add(
        vol_bar,
        grid_opts=opts.GridOpts(
            pos_left="10%",
            pos_right="8%",
            height="15%",  # 成交量图高度15%
            pos_top="80%"  # 从80%位置开始
        )
    )
)

# 修改渲染对象为grid
grid.render("stock_kline.html") 

2.8 美化+完整代码

python 复制代码
import pandas as pd

from pyecharts.charts import Kline
from pyecharts import options as opts

# 读取数据并排序
df = pd.read_csv("kdata.csv", parse_dates=["日期"])

# 数据预处理
df['日期'] = pd.to_datetime(df['日期']).dt.strftime('%Y-%m-%d')  # 格式化日期

df = df.sort_values("日期") # 安装日期排序

data = df[["开盘", "收盘", "最低", "最高"]].values.tolist()  # 生成K线数据序列


# 创建K线图
kline = Kline()
kline.add_xaxis(df['日期'].tolist())  # X轴日期数据
kline.add_yaxis(
        series_name="k线",  # y轴名称
        y_axis=data,  # K线数据序列
        itemstyle_opts=opts.ItemStyleOpts(
            color="#ef232a",    # 上涨颜色(红色)
            color0="#14b143",   # 下跌颜色(绿色)
            border_color="#000",  # 统一黑色描边
            border_color0="#000"
        )
    )
    
kline.set_global_opts(
        title_opts=opts.TitleOpts(title="股票K线走势图", subtitle=df['股票代码'][0]),
        xaxis_opts=opts.AxisOpts(
            type_='category',
            axislabel_opts=opts.LabelOpts(rotate=45),  # 日期标签旋转45度
            splitline_opts=opts.SplitLineOpts(is_show=True)  # 显示网格线
        ),
        yaxis_opts=opts.AxisOpts(
            splitarea_opts=opts.SplitAreaOpts(
                is_show=True, 
                areastyle_opts=opts.AreaStyleOpts(opacity=1)
            ),is_scale=True # 启用自动缩放
        ),
        datazoom_opts=[  # 添加数据缩放控件
            opts.DataZoomOpts(
                is_show=True,
                type_="inside",
                xaxis_index=[0],
                range_start=50,
                range_end=100
            ),
            opts.DataZoomOpts(
                is_show=True,
                xaxis_index=[0],
                type_="slider",
                pos_top="90%",
                range_start=50,
                range_end=100
            )
        ]
    )

# 计算移动平均线 (处理前4个NaN值)
ma_periods = [5, 10, 20]
for period in ma_periods:
    df[f'MA{period}'] = df['收盘'].rolling(window=period).mean().bfill()
    
from pyecharts.charts import Line
# 创建均线叠加图
line = Line()

# 添加各周期均线
ma_colors = {
    5: {"color": "#FF0000", "width": 2},   # 红色5日均线
    10: {"color": "#0000FF", "width": 2},  # 蓝色10日均线
    20: {"color": "#00FF00", "width": 2}   # 绿色20日均线
}

for period in ma_periods:
    line.add_xaxis(df['日期'].tolist())
    line.add_yaxis(
        series_name=f"MA{period}",
        y_axis=df[f'MA{period}'].tolist(),
        symbol="circle",
        symbol_size=0,
        linestyle_opts=opts.LineStyleOpts(
            color=ma_colors[period]["color"],
            width=ma_colors[period]["width"]
        ),
        label_opts=opts.LabelOpts(is_show=False),  # 关闭数据点标签
        is_smooth=True,  # 平滑曲线
        z_level=1  # 确保均线显示在K线上方
    )


# 合并图表
overlap_kline = kline.overlap(line)

# 生成涨跌颜色列表(与K线颜色同步)
df['color'] = df.apply(lambda x: "#ef232a" if x['收盘'] >= x['开盘'] else "#14b143", axis=1)

# 创建成交量柱形图
from pyecharts.charts import Bar
from pyecharts.commons.utils import JsCode

vol_bar = (
    Bar()
    .add_xaxis(df['日期'].tolist())
    .add_yaxis(
        series_name="",
        
        y_axis=df['成交量'].tolist(),
        itemstyle_opts=opts.ItemStyleOpts(
            color=JsCode('''
                function(params) {
                    var colors = [%s];  
                    return params.dataIndex < colors.length ? colors[params.dataIndex] : '#14b143';
                }
            ''' % ("'" + "','".join(df['color'].tolist()) + "'"))  # 生成正确数组格式
        ),
        yaxis_index=1,
        bar_width='60%',
        label_opts=opts.LabelOpts(is_show=False)
    )
    .set_global_opts(
        xaxis_opts=opts.AxisOpts(
            type_="category",
            axislabel_opts=opts.LabelOpts(is_show=False),
            splitline_opts=opts.SplitLineOpts(is_show=False)
        ),
        yaxis_opts=opts.AxisOpts(
            position="right",
            axislabel_opts=opts.LabelOpts(formatter=JsCode(
                "function(value){return value > 10000 ? (value/10000).toFixed(1)+'万' : value;}"))
        )
    )
)

# 组合图表布局
from pyecharts.charts import Grid

grid = (
    Grid(init_opts=opts.InitOpts(width="1200px", height="800px"))
    .add(
        overlap_kline,  # 使用已合并的K线均线图
        grid_opts=opts.GridOpts(
            pos_left="10%", 
            pos_right="8%", 
            height="65%",  # 主图高度65%
            pos_top="10%"
        )
    )
    .add(
        vol_bar,
        grid_opts=opts.GridOpts(
            pos_left="10%",
            pos_right="8%",
            height="15%",  # 成交量图高度15%
            pos_top="80%"  # 从80%位置开始
        )
    )
)

# 修改渲染对象为grid
grid.render("stock_kline.html") 

3. 结尾------这 K 线,有点意思!

一顿操作下来,我们终于用 pyecharts 画出了一个完整的 K 线图,包含了所有关键指标!

如果你是个数据分析师或者炒股爱好者,这样的 K 线图绝对是你的利器!

如果觉得今天的内容对你有帮助,顺手点赞+在看就是对花姐最大的支持!❤️

相关推荐
Mnxj2 分钟前
渐变边框设计
前端
我是谁的程序员4 分钟前
Flutter iOS真机调试报错弹窗:不受信任的开发者
后端
用户7678797737325 分钟前
由Umi升级到Next方案
前端·next.js
蓝宝石Kaze6 分钟前
使用 Viper 读取配置文件
后端
快乐的小前端6 分钟前
TypeScript基础一
前端
北凉温华7 分钟前
UniApp项目中的多服务环境配置与跨域代理实现
前端
源柒8 分钟前
Vue3与Vite构建高性能记账应用 - LedgerX架构解析
前端
aiopencode8 分钟前
Flutter 开发指南:安卓真机、虚拟机调试及 VS Code 开发环境搭建
后端
Danny_FD8 分钟前
常用 Git 命令详解
前端·github
zy_destiny9 分钟前
【非机动车检测】用YOLOv8实现非机动车及驾驶人佩戴安全帽检测
人工智能·python·算法·yolo·机器学习·安全帽·非机动车