顶顶顶顶顶顶顶
import pandas as pdfrom pyecharts.charts import Kline, Line, Bar, Gridfrom pyecharts import options as optsfrom 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 = # 移动平均线周期 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 = ( 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=,# 作用于 X 轴 range_start=80,# 初始显示范围 range_end=100 ), opts.DataZoomOpts( is_show=True,# 显示滑动条缩放 xaxis_index=, 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.tolist(), is_smooth=True,# 平滑曲线 symbol="none",# 取消数据点标记 linestyle_opts=opts.LineStyleOpts( color=self.ma_colors,# 颜色 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}")
好嘛,大家的愿望就是我改进的动力!这不,花姐连夜优化了一版,并且封装成一个类,只要传入符合格式的 DataFrame 数据,一行代码搞定丝滑的 K 线图,完美支持全屏+缩放!准备好?先看看效果,然后咱们开整!self.df = df.sort_values("日期")# 按日期排序,确保数据按时间顺序排列 self.stock_code = stock_code# 股票代码 self.color_up = "#ef232a"# 阳线(上涨)颜色 self.color_down = "#14b143"# 阴线(下跌)颜色 self.ma_periods = # 移动平均线周期 self.ma_colors = {5: "#FF0000", 10: "#0000FF", 20: "#00FF00"}# 均线颜色
来看看如何使用Python实现丝滑绘制K线图吧前段时间写了一篇用 pyecharts 绘制 K 线图的文章,结果朋友们一个个跑来留言——“花姐,这个图咋不全屏?”“成交量缩放有问题,咋整?”“有没有更方便的封装方式?我想一行代码就搞定!”好嘛,大家的愿望就是我改进的动力!这不,花姐连夜优化了一版,并且封装成一个类,只要传入符合格式的 DataFrame 数据,一行代码搞定丝滑的 K 线图,完美支持全屏+缩放!准备好?先看看效果,然后咱们开整!http://www.kdocs.cn/api/v3/office/copy/bTJ3Q3pWTWNsM25iZlVOcnQzRFlJdEFySit6WjFScWN1dFpITEpHUTZlNnB4VU9yd244dlNjL2VsRVJuZmVWUmdBOE1CcHBZcDV0dTJ1V3VhMDJnRVlHdTJVQnUydS9ZcDV4bTFEYU1jYlNTT2twdjhMMUFPMnpkQkdiVnhJK1FtMEN4RmhPWU9lQzFlT0kyZlJMYVE5SG9OdU44N0RXN2UxTFpPRzJIOTF3SXRRQnBEOEZQcTh5Q2FwellLOERzWkFsbVpKMmN4QzgrbzN6LzdTbXJjSnNkem0rUFd1blJhZ1EyMFNGUE5wN3NURlZSRkFIS3VJTWphZzRiTkVHTlNiSWxGb1VsNFJzPQ==/attach/object/f8e898c37635ef1d8653c45f18eea69df081406b? 优化后的 K 线图,支持:✅ 全屏展示(再也不用担心小图看不清)✅ 成交量缩放(精准掌握市场动向)✅ 更丝滑的交互体验这是StockKlineChart.py文件内容,绘制K线图的类,拿来就能用
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180import pandas as pdfrom pyecharts.charts import Kline, Line, Bar, Gridfrom pyecharts import options as optsfrom 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 = # 移动平均线周期 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 = ( 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=,# 作用于 X 轴 range_start=80,# 初始显示范围 range_end=100 ), opts.DataZoomOpts( is_show=True,# 显示滑动条缩放 xaxis_index=, 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.tolist(), is_smooth=True,# 平滑曲线 symbol="none",# 取消数据点标记 linestyle_opts=opts.LineStyleOpts( color=self.ma_colors,# 颜色 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}")
http://www.kdocs.cn/api/v3/office/copy/bTJ3Q3pWTWNsM25iZlVOcnQzRFlJdEFySit6WjFScWN1dFpITEpHUTZlNnB4VU9yd244dlNjL2VsRVJuZmVWUmdBOE1CcHBZcDV0dTJ1V3VhMDJnRVlHdTJVQnUydS9ZcDV4bTFEYU1jYlNTT2twdjhMMUFPMnpkQkdiVnhJK1FtMEN4RmhPWU9lQzFlT0kyZlJMYVE5SG9OdU44N0RXN2UxTFpPRzJIOTF3SXRRQnBEOEZQcTh5Q2FwellLOERzWkFsbVpKMmN4QzgrbzN6LzdTbXJjSnNkem0rUFd1blJhZ1EyMFNGUE5wN3NURlZSRkFIS3VJTWphZzRiTkVHTlNiSWxGb1VsNFJzPQ==/attach/object/f8e898c37635ef1d8653c45f18eea69df081406b?
页:
[1]