如何在循环中更新绘图?对比solve()与inv()求解耗时可视化
实现实时更新的线性求解耗时对比绘图
要在循环中实时更新对比np.linalg.inv()和np.linalg.solve()的耗时绘图,需要开启matplotlib的交互模式,同时维护每次循环的测试数据,逐步更新图表内容。以下是修改后的完整可运行代码:
import numpy as np from datetime import datetime import matplotlib.pyplot as plt # 开启matplotlib交互模式,支持动态更新 plt.ion() # 初始化存储数据的列表 n_values = [] inv_times = [] solve_times = [] # 创建绘图画布和坐标轴 fig, ax = plt.subplots(figsize=(10, 6)) # 初始化两条曲线,后续更新数据 inv_line, = ax.plot([], [], 'bo-', label='inv() + 矩阵乘法') solve_line, = ax.plot([], [], 'rs-', label='solve()') # 设置坐标轴和图表属性 ax.set_xlabel('矩阵规模 n') ax.set_ylabel('求解耗时 (秒)') ax.set_title('numpy inv() vs solve() 线性系统求解耗时对比') ax.legend() ax.grid(True) # 测试不同规模的矩阵 for n in (100, 200, 500, 1000, 2000, 5000, 10000): A = np.random.randn(n, n) B = np.ones((n, 1)) # 注意:原代码中np.linalg.inv(A)*B是元素-wise乘法,正确的矩阵乘法应该用@ # 求解 using INV FNC start_time = datetime.now() Xi = np.linalg.inv(A) @ B end_time = datetime.now() inv_duration = (end_time - start_time).total_seconds() # 求解 using SOLVE FNC start_time2 = datetime.now() Xs = np.linalg.solve(A, B) end_time2 = datetime.now() solve_duration = (end_time2 - start_time2).total_seconds() # 打印耗时 print(f'Duration of INV FNC for n={n}: {inv_duration:.4f} 秒') print(f'Duration of SOLVE FNC for n={n}: {solve_duration:.4f} 秒') # 更新数据列表 n_values.append(n) inv_times.append(inv_duration) solve_times.append(solve_duration) # 更新曲线数据 inv_line.set_data(n_values, inv_times) solve_line.set_data(n_values, solve_times) # 自动调整坐标轴范围,避免数据超出显示区域 ax.relim() ax.autoscale_view() # 刷新图表并短暂暂停,让系统完成渲染 plt.draw() plt.pause(0.01) # 循环结束后关闭交互模式,保持图表显示 plt.ioff() plt.show()
关键说明:
- 交互模式开启:
plt.ion()是动态更新的核心,它让matplotlib不再阻塞程序执行,允许实时刷新图表。 - 数据维护:用三个列表分别记录矩阵规模、
inv()的耗时、solve()的耗时,每次循环后追加新数据。 - 曲线更新:预先创建线条对象,每次循环仅更新线条的
x和y数据,比每次重新绘图更高效。 - 时间转换:将
datetime返回的时间差(timedelta对象)转换为总秒数,方便绘图时的数值展示和坐标轴缩放。 - 矩阵乘法修正:原代码中的
np.linalg.inv(A)*B是元素级乘法,这不符合线性系统求解的逻辑,正确的矩阵乘法应该使用@运算符,否则得到的结果是错误的,耗时测试也失去意义。
内容的提问来源于stack exchange,提问作者walkingwhale
相关产品推荐
相关产品推荐

