用 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 线图绝对是你的利器!

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

相关推荐
大圣编程31 分钟前
Python中continue语句的用法是什么?
开发语言·前端·python
yuhaiqiang32 分钟前
随手 vibecoding 的浏览器插件已经 6000 多次下载,聊聊他的产品设计
前端·后端·面试
云烟成雨TD44 分钟前
LangFlow 1.x 系列【5】可视化编辑页面功能说明
人工智能·python·agent
之歆1 小时前
Vue商品详情与放大镜组件
前端·javascript·vue.js
再吃一根胡萝卜2 小时前
如何把小米 MiMo 接入 CodeBuddy,打造私有 Agent
前端
geovindu2 小时前
python: Functional Options Pattern
开发语言·后端·python·设计模式·惯用法模式·函数式选项模式
tryCbest3 小时前
Python 文件操作
服务器·python
负责的蛋挞3 小时前
异步HttpModule的实现方式
java·服务器·前端
涛声依旧-底层原理研究所3 小时前
Agent 长任务可靠性设计:实现暂停、恢复、续跑与崩溃重启的完整方案
人工智能·python·系统架构
AC赳赳老秦3 小时前
防火墙规则批量配置实战:OpenClaw 自动生成模板、批量下发与合规性校验全解析
java·开发语言·人工智能·python·github·php·openclaw