用Python绘制丝滑的K线图,优化版,文中有源码,拿来就能用,做量化的朋友千万别错过!🎉

前段时间写了一篇用 pyecharts 绘制 K 线图的文章,结果后台的朋友们一个个跑来留言------

"花姐,这个图咋不全屏?"

"成交量缩放有问题,咋整?"

"有没有更方便的封装方式?我想一行代码就搞定!"

好嘛,大家的愿望就是我改进的动力!💪 这不,花姐连夜优化了一版,并且封装成一个类,只要传入符合格式的 DataFrame 数据,一行代码搞定丝滑的 K 线图,完美支持全屏+缩放!🎉

🚀 准备好?先看看效果,然后咱们开整!

优化后的 K 线图,支持:

全屏展示 (再也不用担心小图看不清)

成交量缩放 (精准掌握市场动向)

更丝滑的交互体验

这是StockKlineChart.py文件内容,绘制K线图的类,拿来就能用👇

python 复制代码
import pandas as pd
from pyecharts.charts import Kline, Line, Bar, Grid
from pyecharts import options as opts
from pyecharts.commons.utils import JsCode

class StockKlineChart:
    def __init__(self, df: pd.DataFrame, stock_code: str):
        """
        初始化 K 线图表对象

        :param df: 股票数据 DataFrame(包含"日期","开盘","收盘","最低","最高","成交量")
        :param stock_code: 股票代码
        """
        self.df = df.sort_values("日期")  # 按日期排序,确保数据按时间顺序排列
        self.stock_code = stock_code  # 股票代码
        self.color_up = "#ef232a"  # 阳线(上涨)颜色
        self.color_down = "#14b143"  # 阴线(下跌)颜色
        self.ma_periods = [5, 10, 20]  # 移动平均线周期
        self.ma_colors = {5: "#FF0000", 10: "#0000FF", 20: "#00FF00"}  # 均线颜色

    def _prepare_data(self):
        """ 处理数据:提取 K 线数据、计算移动均线、设置成交量颜色 """
        self.dates = self.df['日期'].tolist()  # 提取日期列表
        self.kline_data = self.df[["开盘", "收盘", "最低", "最高"]].values.tolist()  # 提取 K 线数据

        # 计算移动平均线
        for period in self.ma_periods:
            self.df[f'MA{period}'] = (
                self.df['收盘']
                .rolling(window=period)
                .mean()
                .bfill()  # 处理 NaN 值(前向填充)
                .round(2)  # 保留两位小数
            )

        # 计算成交量颜色标记(1: 上涨, -1: 下跌)
        self.df['color'] = self.df.apply(
            lambda x: 1 if x['收盘'] >= x['开盘'] else -1,
            axis=1
        )
        self.df['index_vol'] = range(len(self.df))  # 给成交量数据添加索引

    def create_chart(self):
        """ 生成 K 线图表 """
        self._prepare_data()  # 处理数据

        # ================== K 线图配置 ==================
        kline = (
            Kline()
            .add_xaxis(self.dates)  # 设置 X 轴日期
            .add_yaxis(
                series_name="K线",  # K 线名称
                y_axis=self.kline_data,  # K 线数据(开盘、收盘、最低、最高)
                itemstyle_opts=opts.ItemStyleOpts(
                    color=self.color_up,  # 阳线颜色
                    color0=self.color_down  # 阴线颜色
                )
            )
            .set_global_opts(
                title_opts=opts.TitleOpts(
                    title="股票K线走势图",  # 图表标题
                    subtitle=f"股票代码:{self.stock_code}",  # 副标题
                    pos_left="left"  # 标题位置
                ),
                legend_opts=opts.LegendOpts(
                    is_show=True,  # 是否显示图例
                    pos_top=10,  # 图例位置(顶部)
                    pos_left="center"  # 居中对齐
                ),
                xaxis_opts=opts.AxisOpts(
                    type_="category",  # X 轴类型(类别)
                    axislabel_opts=opts.LabelOpts(rotate=0),  # X 轴标签角度
                    splitline_opts=opts.SplitLineOpts(is_show=True)  # 是否显示网格线
                ),
                yaxis_opts=opts.AxisOpts(
                    is_scale=True,  # Y 轴是否自适应缩放
                    splitarea_opts=opts.SplitAreaOpts(
                        is_show=True,  # 是否显示网格背景
                        areastyle_opts=opts.AreaStyleOpts(opacity=1)  # 设置透明度
                    )
                ),
                tooltip_opts=opts.TooltipOpts(
                    trigger="axis",  # 触发方式:鼠标悬浮时显示
                    axis_pointer_type="cross",  # 坐标轴指示器类型(十字指示)
                ),
                datazoom_opts=[
                    opts.DataZoomOpts(
                        is_show=False,  # 是否显示数据缩放控件
                        type_="inside",  # 缩放类型:内部滑动
                        xaxis_index=[0, 1],  # 作用于 X 轴
                        range_start=80,  # 初始显示范围
                        range_end=100
                    ),
                    opts.DataZoomOpts(
                        is_show=True,  # 显示滑动条缩放
                        xaxis_index=[0, 1],
                        type_="slider",
                        pos_top="100%",  # 位置:底部
                        range_start=80,
                        range_end=100
                    )
                ],
                # 坐标轴指示器
                axispointer_opts=opts.AxisPointerOpts(
                    is_show=True,
                    link=[{"xAxisIndex": "all"}],
                    label=opts.LabelOpts(background_color="#777")
                )
            )
        )

        # ================== 移动平均线配置 ==================
        line = Line().add_xaxis(self.dates)
        for period in self.ma_periods:
            line.add_yaxis(
                series_name=f"MA{period}",
                y_axis=self.df[f'MA{period}'].tolist(),
                is_smooth=True,  # 平滑曲线
                symbol="none",  # 取消数据点标记
                linestyle_opts=opts.LineStyleOpts(
                    color=self.ma_colors[period],  # 颜色
                    width=2  # 线宽
                ),
                label_opts=opts.LabelOpts(is_show=False)  # 隐藏数据标签
            )

        # 叠加 K 线和均线
        overlap_kline = kline.overlap(line)

        # ================== 成交量柱状图 ==================
        vol_bar = (
            Bar()
            .add_xaxis(self.dates)
            .add_yaxis(
                series_name="成交量",
                y_axis=self.df[['index_vol', '成交量', 'color']].values.tolist(),
                label_opts=opts.LabelOpts(is_show=False),  # 隐藏标签
                
            )
            .set_global_opts(
                xaxis_opts=opts.AxisOpts(
                    type_="category",
                    grid_index=1,
                    axislabel_opts=opts.LabelOpts(is_show=False),
                    axistick_opts=opts.AxisTickOpts(is_show=False),
                    splitline_opts=opts.SplitLineOpts(is_show=False)
                ),
                yaxis_opts=opts.AxisOpts(is_show=False),
                legend_opts=opts.LegendOpts(is_show=False),
                visualmap_opts=opts.VisualMapOpts(
                    is_show=False,
                    dimension=2,  # 颜色映射使用的维度(color)
                    series_index=4,  # 作用于第 5 个系列(成交量)
                    is_piecewise=True,  # 分段显示
                    pieces=[
                        {"value": 1, "color": self.color_up},  # 上涨颜色
                        {"value": -1, "color": self.color_down}  # 下跌颜色
                    ]
                )
            )
        )

        # ================== 组合图表 ==================
        grid = (
            Grid(init_opts=opts.InitOpts(
                width="98vw",
                height="95vh",
                animation_opts=opts.AnimationOpts(animation=False)  # 关闭动画
            ))
            .add(overlap_kline, grid_opts=opts.GridOpts(pos_top="10%", height="60%" ,pos_left="30px",pos_right="10px"))
            .add(vol_bar, grid_opts=opts.GridOpts(pos_top="73%", height="20%" ,pos_left="30px",pos_right="10px"))
        )

        return grid

    def render(self, file_path: str = "stock_kline.html"):
        """ 渲染并保存 K 线图 """
        chart = self.create_chart()
        chart.render(file_path)
        print(f"K 线图已保存为 {file_path}")

这是如何调用的方法👇 在StockKlineChart.py所在目录下新建一个main.py文件

python 复制代码
import akshare as ak
import StockKlineChart as skc

# 获取股票数据
df = ak.stock_zh_a_hist(
    symbol="000001",       # 股票代码
    period="daily",        # 日线数据
    start_date="20230101", # 起始日期
    end_date="20251201",   # 结束日期
    adjust="qfq"           # 前复权处理
)

# 创建 K 线图实例
stock_chart = skc.StockKlineChart(df=df, stock_code="000001")
stock_chart.render()

运行成功以后会在目录下生成一个stock_kline.html文件,用谷歌浏览器打开就能看到了。


🎯 结语

好了,文章基本上就写到这里了,对于Pyecharts配置有疑问的可以参考下这张图:

如果你也在用 pyecharts 做可视化,希望这篇文章能帮你少走点弯路!😆

顺手点赞+在看,就是对花姐最大的支持!❤️

相关推荐
大慕慕好懒7 分钟前
sqlilabs-Less之HTTP头部参数的注入——基础篇
前端·http·less
Fairy要carry15 分钟前
Prompt-Tuning 提示词微调
开发语言·python·prompt
nothingbutluck46420 分钟前
2025.4.15学习日记 CSS、CSS盒子模型
前端·css·学习
多多米100525 分钟前
Vue3项目自定义全局防抖节流
前端·javascript·vue.js·typescript
大樊子38 分钟前
小程序的生命周期
前端·小程序
Mintopia1 小时前
Nodejs第四天,身份认证
前端·javascript·node.js
Kagol1 小时前
🎉TinyVue v3.22.0 正式发布:支持深色模式、增加基于 UnoCSS 的图标库、支持更丰富的 TypeScript 类型声明
前端·vue.js·开源
天天扭码1 小时前
一分钟解决 | 高频面试题——找到字符串中所有字母异位词
前端·算法·面试
weixin_307779131 小时前
实现Azure Function安全地请求企业内部API返回数据
开发语言·python·云计算·azure