求助:如何正确绘制100维向量随时间步的变化曲线?
问题分析与解决方案
第一次绘图失败的原因
你的consensus_dynamic函数设计为接收单个时间值t,但第一次调用时传入了整个t数组(100个时间点)。此时-t*L会被广播为三维张量,而scipy.linalg.expm仅能处理二维矩阵,最终得到的x_t维度不符合plt.plot的要求——plt.plot(t, y)要求y的形状为(len(t), n_features),直接传数组t得到的x_t形状混乱,导致绘图错误。
循环方式的正确性
你用循环逐个计算每个时间步的向量是正确的,最终得到的steps是包含100个100维向量的列表,转换成numpy数组后形状为(100, 100),此时plt.plot(t, steps)会自动把每一行作为一条曲线,对应100个元素随时间的变化,和你预期的效果一致。
优化代码
可以用列表推导式简化循环,或者修改函数支持批量处理时间点,提升效率:
方式1:简化循环(推荐)
import numpy as np from scipy import csgraph, linalg import matplotlib.pyplot as plt def consensus_dynamic(x_0, t): L = csgraph.laplacian(Last_adj) x_t = np.dot(linalg.expm(-t * L), x_0) return x_t x_0 = np.arange(100) t = np.logspace(-2.5, 1.5, 100) # 用列表推导式替代for循环,更简洁 steps = np.array([consensus_dynamic(x_0, ti) for ti in t]) fig, ax = plt.subplots() ax.set_xscale('log') ax.plot(t, steps) plt.show()
方式2:批量处理时间点(避免循环)
如果想避免循环,可以修改函数,对每个时间点单独计算矩阵指数,再批量相乘:
def consensus_dynamic_batch(x_0, t_array): L = csgraph.laplacian(Last_adj) # 对每个时间点计算expm,得到形状为(len(t_array), 100, 100)的数组 exp_matrices = np.array([linalg.expm(-t * L) for t in t_array]) # 批量和x_0相乘,得到形状为(len(t_array), 100)的结果 x_t = np.dot(exp_matrices, x_0) return x_t x_t = consensus_dynamic_batch(x_0, t) fig, ax = plt.subplots() ax.set_xscale('log') ax.plot(t, x_t) plt.show()
结果验证
两种方式得到的结果和你循环版本一致,都能生成100条曲线,对应每个向量元素随时间的变化,符合预期效果。
内容的提问来源于stack exchange,提问作者Dada
相关产品推荐
相关产品推荐

