【Python】解决使用 plt.savefig 保存图片时一片空白

本文介绍了在使用 matplotlib 的 plt.savefig 方法保存图片时遇到保存空白图片的问题及其解决方法。问题出现在 plt.show() 后调用了 plt.savefig(),导致保存的是新创建的空白图片。文章提供了两种解决方案:一种是在 plt.show() 之前调用 plt.savefig();另一种是通过获取当前图像句柄并在 plt.show() 后保存。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题

当使用如下代码保存使用 plt.savefig 保存生成的图片时,结果打开生成的图片却是一片空白。

import matplotlib.pyplot as plt

""" 一些画图代码 """

plt.show()
plt.savefig("filename.png")

原因

其实产生这个现象的原因很简单:在 plt.show() 后调用了 plt.savefig() ,在 plt.show() 后实际上已经创建了一个新的空白的图片(坐标轴),这时候你再 plt.savefig() 就会保存这个新生成的空白图片。


解决

知道了原因,就不难知道解决办法了,解决办法有两种:

  1. 在 plt.show() 之前调用 plt.savefig()

    import matplotlib.pyplot as plt
    
    """ 一些画图代码 """
    
    plt.savefig("filename.png")
    plt.show()
  2. 画图的时候获取当前图像(这一点非常类似于 Matlab 的句柄的概念):

    # gcf: Get Current Figure
    fig = plt.gcf()
    plt.show()
    fig1.savefig('tessstttyyy.png', dpi=100)
import numpy as np import matplotlib.pyplot as plt from scipy.interpolate import CubicSpline import random import time import platform ''' 设置字体 可视化出轨迹''' def set_chinese_font(): """自动检测系统并设置中文字体""" system = platform.system() # # 设置中文字体 (根据系统选择) if system == 'Windows': plt.rcParams['font.sans-serif'] = ['Microsoft YaHei', 'SimHei'] elif system == 'Darwin': # macOS plt.rcParams['font.sans-serif'] = ['PingFang SC', 'STHeiti'] else: # Linux plt.rcParams['font.sans-serif'] = ['WenQuanYi Micro Hei', 'Noto Sans CJK SC'] plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题 # D:\python310\lib\tkinter\__init__.py:839: UserWarning: Glyph 20687 (\N{CJK UNIFIED IDEOGRAPH-50CF}) missing from font(s) DejaVu Sans. # func(*args) # # 设置中文字体 (根据系统选择) # plt.rcParams['font.sans-serif'] = [ # 'Microsoft YaHei', # Windows # 'PingFang SC', # macOS # 'WenQuanYi Micro Hei' # Linux # ] # plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题 # 使用示例 set_chinese_font() def generate_human_like_trajectory(start_point, end_point, num_points=100, jitter_factor=0.3, speed_variation=0.5): """ 生成类似人类点击的平滑轨迹 :param start_point: 起始坐标 (x, y) :param end_point: 目标坐标 (x, y) :param num_points: 轨迹点数 :param jitter_factor: 轨迹抖动程度 (0-1) :param speed_variation: 速度变化程度 (0-1) :return: 轨迹点列表 [(x, y)] """ # 生成控制点(贝塞尔曲线控制点) control_points = [np.array(start_point)] # 在起点和终点之间添加2个随机控制点 for i in range(1, 3): t = i / 3 # 线性插值基础点 base_point = (1 - t) * np.array(start_point) + t * np.array(end_point) # 添加随机偏移 offset = np.random.normal(0, jitter_factor * np.linalg.norm(np.array(end_point) - np.array(start_point)) / 4, 2) control_points.append(base_point + offset) control_points.append(np.array(end_point)) # 生成三次样条曲线 t_vals = np.linspace(0, 1, len(control_points)) x_vals = [p[0] for p in control_points] y_vals = [p[1] for p in control_points] cs_x = CubicSpline(t_vals, x_vals, bc_type='natural') cs_y = CubicSpline(t_vals, y_vals, bc_type='natural') # 生成非均匀时间点(模拟人类速度变化) t_smooth = np.linspace(0, 1, num_points) speed_factors = np.cumsum(np.random.uniform(1 - speed_variation, 1 + speed_variation, num_points)) t_smooth = t_smooth * (speed_factors / np.max(speed_factors)) # 生成轨迹点 trajectory = [] for t in t_smooth: x = cs_x(t) y = cs_y(t) # 添加微小抖动(模拟人类手部颤动) x += random.gauss(0, 0.3) y += random.gauss(0, 0.3) trajectory.append((x, y)) return trajectory def plot_trajectory(trajectory, start_point, end_point): """ 绘制轨迹并验证平滑度 :param trajectory: 轨迹点列表 :param start_point: 起始点 :param end_point: 目标点 """ x_vals = [p[0] for p in trajectory] y_vals = [p[1] for p in trajectory] # 计算速度(变化率) dx = np.diff(x_vals) dy = np.diff(y_vals) speed = np.sqrt(dx**2 + dy**2) # 计算加速度 acceleration = np.diff(speed) # 15英寸宽,10英寸高 # plt.figure(figsize=(15, 10)) # plt.figure(figsize=(10, 8)) # 设置形尺寸和DPI # plt.figure(figsize=(10, 6), dpi=120) # 总像素尺寸 = (10*120) x (6*120) = 1200x720 # 创建宽屏表 (16:9比例) plt.figure(figsize=(16, 9), dpi=80) # 1280x720像素 # 轨迹 plt.subplot(2, 2, 1) plt.plot(x_vals, y_vals, 'b-', label='轨迹', linewidth=9 ) plt.plot(start_point[0], start_point[1], 'go', markersize=10, label='起点') plt.plot(end_point[0], end_point[1], 'ro', markersize=10, label='终点') plt.title('鼠标移动轨迹', fontsize=19) plt.xlabel('X 坐标') plt.ylabel('Y 坐标') plt.legend() plt.grid(True) plt.axis('equal') # 速度变化 plt.subplot(2, 2, 2) plt.plot(speed, 'g-') plt.title('轨迹速度变化') plt.xlabel('时间步长') plt.ylabel('速度 (像素/步)') plt.grid(True) # 加速度变化 plt.subplot(2, 2, 3) plt.plot(acceleration, 'r-') plt.title('轨迹加速度变化') plt.xlabel('时间步长') plt.ylabel('加速度') plt.grid(True) # 曲率 curvature = np.abs(np.diff(np.arctan2(dy, dx))) plt.subplot(2, 2, 4) plt.plot(curvature, 'm-') plt.title('轨迹曲率变化') plt.xlabel('时间步长') plt.ylabel('曲率 (弧度)') plt.grid(True) plt.tight_layout() plt.show() # 导出控制:保存片时使用savefig的dpi参数独立控制输出分辨率 plt.savefig('plt-output.png', dpi=300) # 高分辨率输出 # 多子协调:大尺寸形可容纳更多子,但需调整子间距 # plt.subplots_adjust(wspace=0.3, hspace=0.4) # 调整子间距 def find_font(): import tkinter as tk from tkinter import font root = tk.Tk() # 获取所有字体 all_fonts = sorted(font.families()) # 筛选中文支持字体 (根据系统不同) chinese_fonts = [f for f in all_fonts if "宋体" in f or "黑体" in f or "YaHei" in f or "PingFang" in f or "WenQuan" in f] print("支持中文的字体:", chinese_fonts) root.destroy() # 关闭临时窗口 # 示例使用 if __name__ == "__main__": # 设置起点和终点 start = (100, 100) target = (500, 400) # 生成轨迹 trajectory = generate_human_like_trajectory(start, target, num_points=150) # 绘制轨迹和分析 plot_trajectory(trajectory, start, target) # 模拟实际移动(可选) print("模拟移动中...") for x, y in trajectory: # 在实际应用中,这里会调用鼠标移动函数 # 例如:pyautogui.moveTo(x, y) time.sleep(0.01) # 模拟移动间隔 print("到达目标位置") # find_font() 为什么使用 plt.savefig('plt-output.png', dpi=300) # 高分辨率输出 导出的片是一片空白
最新发布
06-27
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值