You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python谐波模式CSV分析绘图时图像重叠问题求助

解决Matplotlib绘图重叠问题的方案

这个问题我之前也碰到过!根源是Matplotlib默认会在**当前活跃的画布(Figure)和轴(Axes)**上继续绘图,如果不主动重置画布,不同日期的内容就会叠加在一起。下面给你两种可靠的解决思路,结合你的谐波检测场景来修改代码:

方法一:每次循环创建独立画布(推荐)

使用面向对象的绘图方式,在处理每个日期的数据时,新建一个专属的画布和轴对象,确保每个日期的图表完全独立。

修改后的示例代码

import pandas as pd
import matplotlib.pyplot as plt
# 假设你的谐波检测函数是这两个
from your_harmonic_module import detect_gartley, detect_butterfly

# 读取CSV数据
df = pd.read_csv("your_trade_data.csv")
# 获取所有唯一日期
unique_dates = df["date"].unique()

for date in unique_dates:
    # 筛选当日数据
    daily_data = df[df["date"] == date].sort_values("time")
    
    # 检测谐波模式
    gartley_patterns = detect_gartley(daily_data)
    butterfly_patterns = detect_butterfly(daily_data)
    
    # 关键:为当前日期创建全新的画布和轴
    fig, ax = plt.subplots(figsize=(12, 6))
    
    # 绘制当日价格走势
    ax.plot(daily_data["time"], daily_data["price"], label="价格曲线", color="#2c3e50", linewidth=1.5)
    
    # 标记Gartley模式
    if gartley_patterns:
        for idx, pattern in enumerate(gartley_patterns):
            # 绘制模式连线
            pattern_time_points = [pattern["A_time"], pattern["B_time"], pattern["C_time"], pattern["D_time"]]
            pattern_price_points = [pattern["A_price"], pattern["B_price"], pattern["C_price"], pattern["D_price"]]
            ax.plot(pattern_time_points, pattern_price_points, color="#e74c3c", linestyle="--", label=f"Gartley 模式 {idx+1}")
            # 标记关键点位
            ax.scatter(pattern["X_time"], pattern["X_price"], color="#c0392b", marker="^", s=120, zorder=5)
            ax.scatter(pattern["D_time"], pattern["D_price"], color="#e74c3c", marker="*", s=180, zorder=5)
    
    # 标记Butterfly模式
    if butterfly_patterns:
        for idx, pattern in enumerate(butterfly_patterns):
            pattern_time_points = [pattern["A_time"], pattern["B_time"], pattern["C_time"], pattern["D_time"]]
            pattern_price_points = [pattern["A_price"], pattern["B_price"], pattern["C_price"], pattern["D_price"]]
            ax.plot(pattern_time_points, pattern_price_points, color="#27ae60", linestyle="--", label=f"Butterfly 模式 {idx+1}")
            ax.scatter(pattern["X_time"], pattern["X_price"], color="#229954", marker="v", s=120, zorder=5)
            ax.scatter(pattern["D_time"], pattern["D_price"], color="#27ae60", marker="*", s=180, zorder=5)
    
    # 设置图表样式
    ax.set_title(f"谐波模式检测 - {date}", fontsize=14, pad=15)
    ax.set_xlabel("交易时间", fontsize=12)
    ax.set_ylabel("价格", fontsize=12)
    ax.legend(loc="upper left", bbox_to_anchor=(1, 1))
    ax.grid(alpha=0.3, linestyle=":")
    plt.tight_layout()  # 自动调整布局,避免标签被截断
    
    # 保存并关闭当前画布(核心!防止复用)
    plt.savefig(f"{date}_harmonic_patterns.png", dpi=150, bbox_inches="tight")
    plt.close(fig)

方法二:每次绘图前清空画布

如果不想重构为面向对象方式,也可以在每次绘图前清空当前画布的内容,适合简单的绘图场景:

for date in unique_dates:
    # 筛选数据、检测模式...
    
    # 清空当前画布的所有内容
    plt.clf()
    
    # 后续绘图代码(和你原来的plt.plot/plt.scatter一致)
    plt.plot(daily_data["time"], daily_data["price"])
    # 标记模式...
    
    plt.savefig(f"{date}_patterns.png")

关键修改点说明

  1. 避免全局画布复用:方法一中的fig, ax = plt.subplots()会为每个日期创建全新的画布,彻底隔离不同日期的绘图内容;方法二中的plt.clf()会清空当前画布的所有元素。
  2. 显式关闭画布:方法一中的plt.close(fig)不仅能避免叠加,还能释放内存,尤其当你处理大量日期数据时很有用。
  3. 面向对象绘图更可控:使用ax.plot()替代全局的plt.plot(),可以精准控制当前绘图的轴,避免多子图场景下的混乱。

内容的提问来源于stack exchange,提问作者sanoj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 17:02:40