Python绘图:如何将暗能量w演化图的x轴从e折叠N改为标度因子a?
解决标度因子a作为x轴的绘图问题
我之前处理宇宙学ODE建模的时候也碰到过一模一样的问题,给你拆解下错误原因和解决办法:
首先,TypeError: only size-1 arrays can be converted to Python scalars这个错误很明确:math.exp()只能处理单个数值,而你传入的t是numpy数组(因为求解ODE得到的时间点都是数组形式),所以直接用math库的函数就会报错。那为什么用np.exp()还是有问题?大概率是你没处理好数组的维度或者类型,给你几个具体的排查步骤:
1. 先确认t的类型和维度
不管你用的是scipy.integrate.odeint还是solve_ivp,求解后得到的时间点t必须是numpy数组(不是Python列表)。如果是列表,先转成数组:
import numpy as np # 假设你的t是列表形式 t = [0, 0.1, 0.2, ...] t_np = np.array(t) a = np.exp(t_np)
2. 确保a和x(w)的维度完全匹配
绘图时x轴和y轴的数组长度必须一致。比如你用solve_ivp的话,要通过t_eval生成等间隔的时间点,再获取对应的x值:
from scipy.integrate import solve_ivp # 定义你的耦合ODE系统 def dark_energy_ode(t, y): x, var1, var2 = y # x是w,var1/var2是其他耦合变量 # 这里填入你的导数表达式,替换成你的实际模型 dxdt = -0.5 * x * (1 + x) # 示例方程 dvar1dt = ... dvar2dt = ... return [dxdt, dvar1dt, dvar2dt] # 初始条件和求解区间(t=ln(a),比如从a=1到a=exp(10)) t_start, t_end = 0, 10 init_cond = [-1.0, 0.1, 0.5] # 初始w和其他变量 # 求解ODE,生成密集的时间点 sol = solve_ivp(dark_energy_ode, [t_start, t_end], init_cond, dense_output=True) t_eval = np.linspace(t_start, t_end, 1000) # 1000个采样点 y_sol = sol.sol(t_eval) x_sol = y_sol[0] # 提取w的演化数据 # 转换为标度因子a a = np.exp(t_eval) # 现在绘图就没问题了 import matplotlib.pyplot as plt plt.figure(figsize=(8, 6)) plt.plot(a, x_sol, linewidth=2) plt.xlabel('Scale factor $a$') plt.ylabel('Dark energy equation of state $w$') plt.xscale('log') # 重点!a是指数增长的,用对数轴能看清整个演化过程 plt.grid(alpha=0.3) plt.show()
3. 常见的坑要避开
- 如果用
odeint,注意它的返回顺序是y在前t在后:from scipy.integrate import odeint t_eval = np.linspace(t_start, t_end, 1000) y_sol = odeint(dark_energy_ode, init_cond, t_eval, tfirst=True) x_sol = y_sol[:, 0] # 提取第一列的w数据 a = np.exp(t_eval) - 不要手动循环计算
a,直接用np.exp()作用于整个数组,效率高且不会出错。
内容的提问来源于stack exchange,提问作者Brudalaxe
相关产品推荐
相关产品推荐

