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

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

相关推荐
赵大仁42 分钟前
微前端框架选型指南
前端·架构·前端框架
GISer_Jing43 分钟前
阿里云前端Nginx部署完,用ip地址访问却总访问不到,为什么?检查安全组是否设置u为Http(80)!
前端·nginx·阿里云
LingRannn6 小时前
【最新Python包管理工具UV的介绍和安装】
开发语言·python·uv
yuanjun04166 小时前
RTDETRv2 pytorch训练
人工智能·pytorch·python
杰克逊的日记6 小时前
什么是PyTorch
人工智能·pytorch·python
赵大仁6 小时前
微前端统一状态树实现方案
前端·前端框架
阿珊和她的猫7 小时前
钩子函数和参数:Vue组件生命周期中的自定义逻辑
前端·javascript·vue.js
勘察加熊人8 小时前
vue展示graphviz和dot流程图
前端·vue.js·流程图
软件2058 小时前
【登录流程图】
java·前端·流程图
后藤十八里8 小时前
Python格式化字符串的四种方法
开发语言·python·学习