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

本文探讨了在使用matplotlib库时,如何避免plt.savefig()保存为空白图片的问题。问题出现的原因是在plt.show()之后调用了plt.savefig(),此时会保存一个新的空白图片。文章提供了两种解决方案:一种是在plt.show()之前调用plt.savefig();另一种是通过获取当前图像的方式进行保存。

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

原文链接: http://blog.youkuaiyun.com/u010099080/article/details/52912439


问题


当使用如下代码保存使用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的句柄的概念)


import matplotlib.pyplot as plt

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

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



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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值