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")
关键修改点说明
- 避免全局画布复用:方法一中的
fig, ax = plt.subplots()会为每个日期创建全新的画布,彻底隔离不同日期的绘图内容;方法二中的plt.clf()会清空当前画布的所有元素。 - 显式关闭画布:方法一中的
plt.close(fig)不仅能避免叠加,还能释放内存,尤其当你处理大量日期数据时很有用。 - 面向对象绘图更可控:使用
ax.plot()替代全局的plt.plot(),可以精准控制当前绘图的轴,避免多子图场景下的混乱。
内容的提问来源于stack exchange,提问作者sanoj
相关产品推荐
相关产品推荐

