☰
Python绘制K线图入门:从OHLC数据到mplfinance实战
2026/10/6 16:53:22 网站建设 项目流程

一直想自己动手把股票走势图画出来,又觉得K线图这玩意儿高不可攀?别急,这期内容就是来帮你把这块硬骨头啃下来的。咱们不聊那些虚头巴脑的理论,直接奔着“用代码把股票走势图变成一张张K线图”这个目标去。你看完这篇文章,至少能搞清楚K线图背后的数据逻辑,并且亲手用Python画出第一张像模像样的图。

这个系列我计划写成一个完整的实操流程,今天这第一篇先做整体概述,把我们接下来要走的路线图给捋清楚,重点解决“为什么要这么画”和“代码大概长什么样”这两个核心问题。不管你是刚接触Python的萌新,还是有点基础但一直没碰过金融数据可视化的同学,这篇都能帮你把底子打好。我保证,整个系列不会出现一堆看不懂的术语堆砌,每一步都能照着抄、照着改。

1. 内容整体设计与思路拆解

1.1 K线图到底在表达什么

先说点实在的。很多人打开炒股软件,看到满屏红红绿绿的柱子,第一反应是“这玩意儿到底想说啥”。其实K线图本质上就是一张“价格在单位时间内的四维快照”,这四维分别是开盘价、收盘价、最高价和最低价。我们常说的“开高低收”四个价格,就是画K线的全部数据基础。

用代码画K线图,说白了就是把这四个价格转换成图形元素的过程。你看一根K线,它其实包含两部分:中间那个粗粗的“实体”,以及上下两头细长的“影线”。实体部分告诉你开盘和收盘之间的博弈结果,影线则记录了这个时间段内价格冲到多高、又砸到多低。我习惯把实体比作“双方交战的战场”,影线则是“侦查兵跑出去留下的足迹”,这样理解起来会特别形象。

为什么要用代码来画,而不是直接用现成的图表软件?因为当你想批量分析几十只股票,或者想把自己的交易策略做成自动化盯盘工具时,手工截图和鼠标点击显然不现实。代码能让你从“看一张图”升级到“管一批图”,这才是程序员思维去看盘的正确姿势。

1.2 为什么用Python而不是其他工具

可能有人会问,Excel也能画K线图,为什么偏要用Python?我给的答案是:你要的是“流程化”和“可复现”,而不是“画一次图”。

Excel处理一两百个数据点还行,一旦你把某只股票五年、十年的日线数据全拉下来,那就是上千根K线,Excel光是渲染就够你等半天的。更重要的是,用Python处理后,你能把“数据获取”“数据处理”“图表绘制”变成一个自动化流水线。今天想分析茅台,明天想换宁德时代,只需要改一个股票代码变量,剩下的交给代码去跑。这种批处理和自动化的能力,是任何手动操作的工具都替代不了的。

而且Python在金融领域有天然的生态优势。处理表格数据有Pandas,画图有Matplotlib和专门为金融设计的mplfinance库,获取数据有Tushare、AkShare这些现成的接口。你要做的不是从零造轮子,而是把这些成熟的轮子组装成一台能跑的车。这就是我选择Python和mplfinance作为整个系列核心工具的原因。

2. 核心细节解析与实操要点

2.1 环境准备:这几个库一个都不能少

既然要动手写代码,先把环境搭好。你需要Python 3.8以上版本,然后安装下面这几个核心库:

  • Pandas:金融数据分析的基石,专门处理表格型数据。我们用到的OHLC数据(开盘价、最高价、最低价、收盘价)就是典型的表格数据。
  • Matplotlib:Python最老牌的可视化库,所有图表绘制的底层引擎。
  • mplfinance:基于Matplotlib开发的专业K线图库,专为金融数据设计,一行代码就能画出漂亮的K线图。

安装命令也不复杂,直接在终端里敲:

pip install pandas matplotlib mplfinance

如果你的网络环境不太稳定,可以加一个国内镜像源,速度会快很多。装好之后,你可以在Python交互环境里验证一下:

import mplfinance as mpf print(mpf.__version__)

能打印出版本号,说明环境就绪了。这里特别叮嘱一句,Pandas和mplfinance之间是存在版本兼容问题的,如果你后面遇到奇怪的报错,优先检查一下这两个库的版本是不是太老了。

2.2 数据从哪来:公开接口与本地文件两手准备

画K线图的第一步是拿到数据。市面上的数据源很多,我推荐新手用Tushare或者AkShare。这两个都是国内比较主流的Python金融数据接口,能直接获取A股的历史行情数据,而且是免费使用的。

Tushare的使用方式是注册一个Token,然后通过接口调用数据,这种方式适合有长期数据需求、并且希望数据格式稳定的用户。AkShare则不需要注册,直接调用函数就能拿到数据,说实话作为教学工具更友好一点。我用AkShare举个例子,获取一只股票的日线数据大概长这样:

import akshare as ak # 获取贵州茅台的历史行情数据 df = ak.stock_zh_a_hist(symbol="600519", period="daily", adjust="qfq") print(df.head())

这里面有一个细节需要特别注意:获取到的数据列名通常是中文(日期、开盘、收盘、最高、最低、成交量),而mplfinance要求数据列是英文(Open、High、Low、Close、Volume),且索引必须是日期格式。这个转换过程其实就是几行代码的事,但很多新手就卡在这里。我给你一个标准的清洗模板:

import pandas as pd # 假设df是从akshare获取的数据 df["日期"] = pd.to_datetime(df["日期"]) # 转日期格式 df = df.rename(columns={ "日期": "Date", "开盘": "Open", "最高": "High", "最低": "Low", "收盘": "Close", "成交量": "Volume" }) df = df.set_index("Date") # 将日期设置为索引 df = df[["Open", "High", "Low", "Close", "Volume"]]

这五列是画K线图的最低要求,缺一不可。之前有粉丝跑来跟我说,为什么我画图总是报错,就是因为他只拿了开高低收,没管成交量,结果mplfinance直接罢工。

如果你不想用网络接口,也可以自己手搓一份测试数据。我在系列文章里会经常用一组随机生成的数据做演示,这样读者不需要依赖外部接口,复制代码就能直接跑通:

import numpy as np import pandas as pd # 生成200个交易日的模拟数据 np.random.seed(42) dates = pd.date_range(start="2023-01-01", periods=200, freq="B") # B代表工作日 price = 100 + np.cumsum(np.random.randn(200) * 2) df = pd.DataFrame({ "Open": price, "High": price + np.random.rand(200) * 3, "Low": price - np.random.rand(200) * 3, "Close": price + np.random.randn(200), "Volume": np.random.randint(10000, 50000, 200) }, index=dates)

这套模拟数据特别适合学习和测试,你先跑通了流程,后面再换成真实行情,就只是换数据源的问题。

3. 实操过程与核心环节实现

3.1 第一张K线图:五步画出雏形

好了,到了最激动人心的环节,我们来画第一张图。核心代码其实简单到超乎你的想象,下面就是完整的示例:

import mplfinance as mpf import pandas as pd import numpy as np # 1. 准备模拟数据 np.random.seed(42) dates = pd.date_range(start="2023-01-01", periods=200, freq="B") price = 100 + np.cumsum(np.random.randn(200) * 2) df = pd.DataFrame({ "Open": price, "High": price + np.random.rand(200) * 3, "Low": price - np.random.rand(200) * 3, "Close": price + np.random.randn(200), "Volume": np.random.randint(10000, 50000, 200) }, index=dates) # 2. 调用mplfinance绘图 mpf.plot(df, type="candle", style="yahoo", title="My First K-Line Chart", ylabel="Price")

这个代码跑完,你会看到一个有红有绿的K线图弹出来。虽然代码很短,但里面藏着几个关键参数值得记住:type="candle"指定我们画的是蜡烛图(也就是K线图);style="yahoo"是内置配色方案,这个方案里红涨绿跌,符合国际惯例;title和ylabel只是给图表加上标题和纵轴标签。

这是不是和你想象的完全不一样?你可能会觉得,就这么几行代码就画完了?对,mplfinance的存在价值就是让你不必关心Matplotlib底层的那些坐标轴和线段绘制细节,把这些都抽象成了几行声明式的参数。但如果你只看这张图就觉得自己学会了,那还早得很。这张图太素了,既没有成交量,也没有均线,还不能跟其他股票作对比,实用性很低。我们接着往深处挖。

3.2 样式与配色:把图调成A股习惯的红涨绿跌

国内股民看习惯了红涨绿跌,而mplfinance默认的yahoo风格是绿涨红跌。如果你想把颜色换成我们熟悉的红涨绿跌,可以用make_marketcolors()函数来定制:

from mplfinance import make_marketcolors from mplfinance import make_mpf_style # 定制红涨绿跌的颜色 mc = make_marketcolors( up="red", # 上涨用红色 down="green", # 下跌用绿色 edge="inherit", # 边框颜色继承 wick="inherit", # 影线颜色继承 volume="inherit" # 成交量颜色继承 ) custom_style = make_mpf_style(marketcolors=mc) mpf.plot(df, type="candle", style=custom_style, title="A-share Style K-Line", ylabel="Price")

这里的up="red"和down="green"就是核心,把上涨和下跌对应的颜色一指派,整个图的气质就变了。除了颜色,你还可以通过style参数调整背景色、网格线样式等外观细节,这些都是让图表变得更专业的手段。

我个人的经验是,在代码里建立一个统一的风格配置模块,把所有定制都放在一起,这样后续画几十只股票的图时,能保证宏观风格完全一致,看起来非常整齐。这种细节往往决定一个数据项目成品的高级感。

3.3 叠加成交量与均线:让信息量翻倍

单看裸K线,信息量实在太少。在真正的行情软件里,K线图下面通常还会跟着一个成交量柱状图,图上还会叠加几条移动平均线。mplfinance对这两种场景的支持是内置的,不需要你额外去写Matplotlib绘图代码。

先看最直观的用法,只需要给plot函数加上两个参数:

mpf.plot( df, type="candle", style=custom_style, title="K-Line with Volume and MA", ylabel="Price", ylabel_lower="Volume", volume=True, # 是否显示成交量 mav=(5, 10, 20), # 是否显示均线,以及显示哪些周期 figratio=(16, 8), # 画布比例 figscale=1.2 # 画布缩放 )

volume=True会在K线图下方自动增加一个子图,用来显示每天成交量对应的柱状图。mav=(5, 10, 20)则是一次性画出5日、10日、20日三条移动平均线,这也是短线交易里比较常用的三个周期。

看到没,真正干活只需要几行代码,但每一行背后都有很深的讲究。比如mav这个参数,如果你是做中长线的,把周期改成(20, 60, 120)会更适合你的策略。参数的选择从来不是死的,它应该服务于你的分析目标。这一节跑完之后,你手里的K线图已经从“毛坯房”变成“精装修”了。

4. 常见问题与排查技巧实录

4.1 图表报错:每根柱子都是上吊线?索引和列名的坑

很多新手跑通基础代码后,会遇到一个现象:画出来的K线图,每根K线都变成一条竖线,实体非常小,几乎看不到红绿方块。这种情况几乎都是因为数据格式不对,常见的是日期没有被正确设置为索引。

mplfinance有个硬性要求:传入的数据框必须是DatetimeIndex索引,而且列名必须是Open、High、Low、Close、Volume这种英文格式。如果你的列名是开盘、收盘这种中文,或者索引还是从0开始的数字,画出来的图就是一根根“上吊线”。

排查思路很简单,在调用mpf.plot之前,先打印一下你的数据框看一下:

print(df.head()) print(df.index) print(df.columns)

确认索引是日期格式,确认列名是英文那五个单词。如果用的是我上面的清洗模板,大概率能一次通过。遇到问题时别急着怀疑代码,先用print把数据和mplfinance的预期“对齐”一下,往往问题一下子就清楚了。

4.2 换用真实数据后日期断档:周末和节假日的坑

用模拟数据画图很顺滑,但一换成真实数据,有些人就会发现图表上K线之间有很宽的间隙,像是中间少了一段似的。这个现象在日线数据上特别常见,原因是真实市场里周末和法定节假日是不交易的,数据中的日期是断续的。

当Pandas把这些稀疏的日期作为索引时,mplfinance默认会按照日期序号隔开K线之间的距离。比如你从周一到周五的数据是连续的,但下次开盘是下周一,中间会凭空多出两天空白,反映到图上就是一根根K线之间的距离不均等。

这个问题怎么解决?方法很简单,在plot函数里加上一个show_nontrading=False参数:

mpf.plot( df, type="candle", style=custom_style, show_nontrading=False, # 忽略非交易日,压缩日期间隙 volume=True, mav=(5, 10, 20) )

show_nontrading=False的作用就是忽略那些非交易日,让K线一根贴着一根排列,图面会变得紧凑很多。这个参数特别适合日线数据,如果你是画小时线或分钟线,则不需要关心这个,因为交易时段内本来就是连续的。

4.3 均线没出现?数据量不足的隐形边界

还有一个很隐蔽的问题,有些人在mav参数里填写了(5, 10, 20),但图上一根均线都看不到,或者只看到一部分均线。这个通常不是代码问题,而是数据量不足造成的。

均线本质上是移动平均,计算周期至少需要N个数据点。比如20日均线,你至少要累积20个有效交易日才能算出一个值,而且就算有了20个点,你图上也只能看到最新那一天对应的均线点。如果你的样本数据不足20个,那20日均线压根画不出来。

我当时自己做这个功能的时候,拿一批只有15天的数据去测试,结果5日均线出现了,10日和20日均线消失得无影无踪。折腾了半天才发现是数据量问题。所以建议你在数据预处理阶段就对长度做个判断,如果不到60个点,后面的60日均线就不用考虑了,省得画出来一张缺胳膊少腿的图。

4.4 中文字体显示成方框:Matplotlib的老大难

画图的时候,你会发现标题或者坐标轴上的中文注释全变成了一个个小方框,这在Matplotlib里是著名的历史难题——中文字体缺失。如果你不想让图表里的信息大打折扣,这一步必须处理。

通用的解决办法是手动指定中文字体。你可以先找到你系统上已有的中文字体名称,然后通过matplotlib.rcParams来全局设置:

import matplotlib.pyplot as plt # 以Windows系统为例 plt.rcParams["font.sans-serif"] = ["Microsoft YaHei"] # 解决负号显示异常 plt.rcParams["axes.unicode_minus"] = False

如果你用的是macOS,把Microsoft YaHei换成PingFang HK或者Arial Unicode MS。在Linux服务器上,则要提前安装中文字体包,然后指定字体路径。这个问题虽然说起来很简单,但在实际项目中耽误的时间不少,提前处理好,后面就不会被这种小问题反复打断思路。

5. 进阶方向预告与操作建议

5.1 多股对比:一次画出几只能源股的走势图

当你把单只股票的K线图跑通后,自然会想:能不能把好几只股票放在一张大图里对比?比如我想同时看中国石油、中国石化和中海油这三只股票的近三个月走势,如果一个个打开保存,效率实在太低了。这就是我们代码化看图的核心优势所在——批量处理。

思路其实很朴素:一个循环遍历股票列表,每只股票的数据都读取出来,然后逐一绘图并保存到本地目录。这个流程在后续文章中我会写一个超详细的版本。这里先给你一个预览,让你知道下一步长什么样:

stock_list = ["600028", "601857", "600938"] for code in stock_list: df = get_data_by_code(code) # 伪代码,具体实现后面文章展开 mpf.plot( df, type="candle", style=custom_style, title=f"{code} K-Line", savefig=f"./chart/{code}.png" )

savefig参数直接指定图片保存路径,不用每次都弹出一个窗口,这样就能实现无人值守的批量出图。你自己看盘的时候,只需打开文件夹,所有目标股票的K线图一览无余。

5.2 K线图上做标注:让关键信号一目了然

K线图画出来之后,你是不是还想在上面画一些标记,比如标出金叉位置、标出重要压力位?mplfinance提供了addplot接口,让你能在K线图之上继续叠加自定义元素。

我举个最简单的例子,在收盘价序列上叠加一条折线,显著标记出均线突破的关键点:

import mplfinance as mpf import pandas as pd # 用当前数据的收盘价做个示例 ap = mpf.make_addplot(df["Close"], color="blue", width=1.5) mpf.plot( df, type="candle", style=custom_style, addplot=ap, title="K-Line with Close Price Line" )

这段代码的作用是在K线图上面画出一条收盘价折线,方便你观察整体走势的连贯性。如果你理解了addplot的用法,后面想标注任何东西,比如“放量突破买入点”“MACD金叉点”,都可以通过往addplot列表里加元素来实现。这一块是深入自定义K线图的重要入口,我会在后面专门写一篇来讲各种花式标注。

5.3 给新手的三个建议

最后掏心窝子总结几句。第一,不要一开始就追求复杂的花活。先把我这篇里的模拟数据流程跑通,把K线图的原理和数据格式搞扎实,这是最省时间的捷径。第二,尽量早点换成真实行情数据实战。只有面对真实的涨跌停、除权除息、停牌复牌,你才会真正理解数据处理的细节有多重要。第三,把代码封装成函数,不要总是复制粘贴。写一个类似plot_kline(stock_code, start_date, end_date)的函数,后续所有分析都基于这个函数调用,能帮你省下大量重复劳动。

我现在写这个系列文章时,其实也在不断回头看自己最早期的代码。如果当时有人能明确告诉我“K线图的本质是OHLC数据到图形元素的映射,先跑通一个最小例子再追求丰富功能”,我应该能少走很多弯路。希望这一篇文章能把方向给大家指清楚,接下来的系列我们会一步步深入:下一期讲怎么用真实行情数据画出第一张有成交量、有均线的完整K线图,再下一期讲怎么把单张图变成批量出图的自动化脚本。咱们到时候接着聊。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询