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

本文介绍了解决使用Matplotlib库保存图片为空白的问题。主要原因是调用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)


另一种解决方法

在用python中的matplotlib 画图时,show()函数总是要放在最后,且它阻止命令继续往下运行,直到1.0.1版本才支持多个show()的使用。
想在显示图像后继续运行相关的处理命令,或者显示一副图像后关闭它,再显示第二幅图像。如下办法:

首先搜索到:
plt.close() will close current instance.
plt.close(2) will close figure 2
plt.close(plot1) will close figure with instance plot1
plt.close('all') will close all fiures
Found here.
Remember that plt.show() is a blocking function, so in the example code you used above,plt.close() isn't being executed until the window is closed, which makes it redundant.
You can use plt.ion() at the beginning of your code to make it non-blocking, although this has other implications.

搜索到:http://matplotlib.org/faq/usage_faq.html#what-is-interactive-mode

总结如下例子:
import matplotlib.pyplot as plt
import time
plt.ion() #开启interactive mode
x = np.linspace(0, 50, 1000)
plt.figure(1) # 创建图表1
plt.plot(x, np.sin(x))
plt.draw()
time.sleep(5)
plt.close(1)
plt.figure(2) # 创建图表2
plt.plot(x, np.cos(x))
plt.draw()
time.sleep(5)
print 'it is ok'

如果不需要关闭图表1,去掉plt.close(1),如果不需要redraw the current figure,那也可以去掉plt.draw()



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、付费专栏及课程。

余额充值