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

Matplotlib中dpi参数无法提升图像分辨率问题求助

洛伦兹吸引子视频分辨率不一致问题排查

我用Python绘制洛伦兹吸引子轨迹生成视频,先逐帧保存图像再合成。默认图像分辨率差,尝试用plt.savefig的dpi参数提升后,部分视频仍有低分辨率帧(已排除YouTube压缩,上传前就存在)。

问题代码

# lorenzAttractorTrace() 接收视频帧数和系统参数s、r、b,默认值为已知可生成预期结果的参数
# 图像会保存到目标目录,之后需用命令行运行ffmpeg合成视频,命令如下:
# ffmpeg -start_number 0 -framerate 60 -i graph%01d.png video.webm

def lorenzAttractorTrace(frames, s=10, r=28, b=2.667, clean=False, rotation=False):
    # 清空目标目录
    clearDirectory()

    # 计算洛伦兹系统的点数组
    # 放在主循环外只计算一次,避免重复计算占用内存
    dt = 0.01
    numSteps = frames

    xyzs = np.empty((numSteps+1, 3))  # 多留一个位置存初始值
    xyzs[0] = (0., 1., 1.05)  # 设置初始值
    for i in range(numSteps):
        xyzs[i + 1] = xyzs[i] + lorenz(xyzs[i],s,r,b) * dt

    # 根据clean参数决定第一帧的样式
    if clean == True:
        # 主循环外绘制第一帧
        ax = plt.figure().add_subplot(projection='3d')
        ax.plot(*xyzs[0].T, lw=0.5)
        ax.set_xlabel("X Axis")
        ax.set_ylabel("Y Axis")
        ax.set_zlabel("Z Axis")
        ax.grid(None)
        ax.axis('off')
        plt.savefig('./Images for simulation/graph'+str(0)+'.png')
        plt.close('all')
    else:
        # 主循环外绘制第一帧
        ax = plt.figure().add_subplot(projection='3d')
        ax.plot(*xyzs[0].T, lw=0.5)
        ax.set_xlabel("X Axis")
        ax.set_ylabel("Y Axis")
        ax.set_zlabel("Z Axis")
        ax.set_title("Lorenz Attractor")
        plt.savefig('./Images for simulation/graph'+str(0)+'.png')
        plt.close('all')
    
    # 非旋转视频
    if rotation == False:
        frame = 1
        while frame < numSteps:
            ax = plt.figure().add_subplot(projection='3d')
            ax.plot(*xyzs[:frame].T, lw=0.5) # 绘制从xyzs[0]到xyzs[frame]的轨迹
            ax.set_xlabel("X Axis")
            ax.set_ylabel("Y Axis")
            ax.set_zlabel("Z Axis")
            plt.xlim((-25,25))
            plt.ylim((-30,35))
            ax.set_zlim(0,60)
            if clean == True:
                ax.grid(None)
                ax.axis('off')
            else:
                ax.set_title("Lorenz Attractor")
            plt.savefig('./Images for simulation/graph'+str(frame)+'.png', dpi=300) # 指定dpi提升分辨率
            plt.close('all')
            frame = frame + 1
    # 旋转视频,使用ax.view_init()设置视角
    else:
        frame = 1
        angle = 0
        while frame < numSteps:
            ax = plt.figure().add_subplot(projection='3d')
            ax.plot(*xyzs[:frame].T, lw=0.5) # 绘制从xyzs[0]到xyzs[frame]的轨迹
            ax.set_xlabel("X Axis")
            ax.set_ylabel("Y Axis")
            ax.set_zlabel("Z Axis")
            plt.xlim((-25,25))
            plt.ylim((-30,35))
            ax.set_zlim(0,60)
            ax.view_init(30,angle)
            if clean == True:
                ax.grid(None)
                ax.axis('off')
            else:
                ax.set_title("Lorenz Attractor")
            plt.savefig('./Images for simulation/graph'+str(frame)+'.png', dpi=300) # 指定dpi提升分辨率
            plt.close('all')
            frame = frame + 1
            angle = angle + 1

问题原因与解决办法

核心问题

第一帧(frame=0)的plt.savefig没有添加dpi=300参数,导致这帧图像是默认分辨率,而后续帧都设置了高分辨率。合成视频时如果包含这帧,就会出现部分帧模糊的情况。另外需确认clearDirectory()是否彻底清空旧文件,避免残留低分辨率图像。

修复步骤

  1. 给第一帧添加dpi参数:修改两个分支的plt.savefig,加上dpi=300:
    # clean=True分支
    plt.savefig('./Images for simulation/graph'+str(0)+'.png', dpi=300)
    # clean=False分支
    plt.savefig('./Images for simulation/graph'+str(0)+'.png', dpi=300)
    
  2. 统一全局dpi设置(可选):创建figure时直接指定dpi=300,无需每次保存都加参数:
    ax = plt.figure(dpi=300).add_subplot(projection='3d')
    
  3. 验证目录清空逻辑:确保clearDirectory()能删除目标目录下所有旧图像,比如用以下实现:
    import os
    
    def clearDirectory():
        dir_path = './Images for simulation/'
        for filename in os.listdir(dir_path):
            if filename.endswith('.png'):
                os.remove(os.path.join(dir_path, filename))
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 17:41:04