【python学习】如何将所绘制的图(单张/多张)保存到文件夹,并用绘制实时时间命名图片

本文介绍使用Python进行批量绘图及保存的方法,包括利用matplotlib库绘图、使用os模块创建文件夹、通过for循环批量处理图片以及利用datetime模块按时间命名图片。

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


最近一直在做实验但在解决问题时总是兜兜转转又回到原点,因此只能记录一些零碎的知识,在此用学术的语言记录最为简单的知识。
下面以循序渐进的方式记录将图片保存到文件夹的过程,由需求促进代码进一步完善。在此以本人解决这个问题所思考的步骤记录下来,主要是经历了以下几个过程:

  1. 过程一:单纯实现将所绘制的图片保存到代码所在目录(plt.savefig()
  2. 过程二:我想创建一个文件夹存储所绘制的图片(if结构+OS模块
  3. 过程三:我需要处理多张图片,能不能批量存储这些图片,并且每张图片的命名都不同(for循环
  4. 过程四:我想记录绘制这些图片的时间,并且最好就是图片名后面有时间(datatime模块

总得来说,最后是实现批量绘制并存储多张以时间命名的图片在同一个文件夹中(当然也可以放在不同的文件夹)

基本存储(plt.savefig())

#基本存储
import matplotlib.pyplot as plt
x=[0,1,2,3,4,5]
y=[0,2,4,6,8,10]
plt.plot(x,y)#绘制图片
plt.savefig( 'exam.png')#存储图片时给图片命名,注意要放在plt.show()前
plt.show()

【输出结果】(会在代码所在目录直接存储图片)
在这里插入图片描述【缺点】当输出的图片非常多时,逐一命名与存储既麻烦又会造成目录非常不好看
因此,下面可以基本想到要创建一个文件夹来存放图片

创建文件夹并存储图片(if结构+OS模块)

#存储图片同一个文件夹中
import matplotlib.pyplot as plt
import os#注意要输入OS模块
x=[0,1,2,3,4,5]
y=[0,2,4,6,8,10]
plt.plot(x,y)
# 指定图片保存路径
figure_save_path = "file_fig"
if not os.path.exists(figure_save_path):
    os.makedirs(figure_save_path) # 如果不存在目录figure_save_path,则创建
plt.savefig(os.path.join(figure_save_path , 'exam.png'))#第一个是指存储路径,第二个是图片名字
plt.show()

【输出结果】(会在代码所在目录创建一个名字为“file_fig”的文件夹,并存储名字为’exam.png’的图片)
在这里插入图片描述在这里插入图片描述【缺点】
这里的图片与文件夹均只是针对一张图片,一个文件夹,如果我的图片非常多,而且是通过循环来绘制的,那么此时可以考虑同样利用循环给每张图片逐一命名存储在同一个文件夹或是逐一存储在不同文件夹(主要是利用遍历列表,先将名字放在列表中,然后结合循环逐一赋予/使用)

批量绘制图片+批量存储(for循环)

#批量绘制图片+批量存储
import matplotlib.pyplot as plt
import os
for i in range(0,3,1):
    x=[i,1,2,3,4,5]
    y=[0,2,4,6,8,10]
    name_list=["one","two","three"]#先创建名字列表,可以是用在图片命名,也可以用在文件夹命名
    plt.plot(x,y)
    # 指定图片保存路径
    figure_save_path = "files_fig_many"#这里创建了一个文件夹,如果依次创建不同文件夹,可以用name_list[i]
    if not os.path.exists(figure_save_path):
        os.makedirs(figure_save_path) # 如果不存在目录figure_save_path,则创建
    plt.savefig(os.path.join(figure_save_path , name_list[i]))#分别命名图片
    plt.show()

【输出结果】(实现在代码所在文件夹创建一个名为”files_fig_many“的文件夹,里面存储了三张不同名字的图片)
在这里插入图片描述这里图片的名字是事先建立了列表存起来的,如果对名字没有特别要求,可以考虑直接用数字列表会更方便
【可改进】
这里图片的命名可以考虑改进一下,一般时候我们会希望用时间记录输出结果,因此可以考虑给图片/文件夹名字加上实时的时间

图片/文件夹命名与所运行时间关联(datatime模块)

这里与实际运行时间关联主要是用到datatime模块,因此需要对前面的代码加上这个模块

#将图片存储在指定文件夹(附带创建文件夹)+用循环创建文件名
import matplotlib.pyplot as plt
import os
import datetime#注意要输入这个模块
for i in range(0,3,1):
    x=[i,1,2,3,4,5]
    y=[0,2,4,6,8,10]
    name_list=["one","two","three"]#先把图片名字存储成列表
    files_name=["file_1_","file_2_","file_3_"]#先把文件夹名字存储成列表
    plt.plot(x,y)
    mkfile_time = datetime.datetime.strftime(datetime.datetime.now(), '%Y%m%d%H%M%S')#这里是引用时间
    mkfile_time = files_name[i]+mkfile_time#注意这里在下面是用作文件夹名字的,里面也用了列表使每个文件夹的名字不一样
    # 指定图片保存路径
    figure_save_path = mkfile_time#给文件夹赋予名字
    if not os.path.exists(figure_save_path):
        os.makedirs(figure_save_path) # 如果不存在目录figure_save_path,则创建
    plt.savefig(os.path.join(figure_save_path , name_list[i]))#分别创建文件夹,分别储存命名图片
    plt.show()

【输出结果】(实现了创建三个名字各不相同且有实时时间的文件夹,且里面分别存储了一张图片)
在这里插入图片描述
在这里插入图片描述这里只举了给文件夹名字加了时间的例子,如果想给图片名字加时间,方法也是一样的

#将图片存储在指定文件夹(附带创建文件夹)+用循环创建文件名+如何将多幅图片储存在同一个文件夹
import matplotlib.pyplot as plt
import os
import datetime
for i in range(0,3,1):
    x=[i,1,2,3,4,5]
    y=[0,2,4,6,8,10]
    name_list=["one","two","three"]
    plt.plot(x,y)
    mkfile_time = datetime.datetime.strftime(datetime.datetime.now(), '%Y%m%d%H%M%S')
    # 指定图片保存路径
    figure_save_path = "exam"
    if not os.path.exists(figure_save_path):
        os.makedirs(figure_save_path) # 如果不存在目录figure_save_path,则创建
    plt.savefig(os.path.join(figure_save_path , name_list[i]+mkfile_time))#创建文件夹,储存有时间命名的多张图片
    plt.show()

【输出结果】(输出一个文件夹中存储着带有实时时间命名的多张图片)
在这里插入图片描述记录结束

<think>好的,我现在需要帮助用户解决如何用Python多张像拼接成单张图片保存的问题。用户提到可以使用PIL或matplotlib实现,所以我应该先考虑这两种库的方法。 首先,我应该回忆一下PIL库的相关功能。PIL的Image模块有处理像拼接的方法。拼接多张图片通常需要创建一个新的空白像,然后将每张图片粘贴到合适的位置。如果是水平或垂直拼接,可能需要计算新像的尺寸。例如,水平拼接的话,新像的宽度是各宽度之和,高度取最大的那个。垂直拼接则是高度相加,宽度取最大。不过用户可能希望自定义布局,比如2x2的网格,这时候需要根据行数和列数来计算位置。 然后,我应该考虑使用PIL的具体步骤。首先导入Image模块,然后打开所有图片,获取它们的尺寸。接着确定新像的尺寸,比如每张的大小相同的话,可以简单计算行和列的总尺寸。创建新像后,使用paste方法将每张粘贴到对应的位置。最后保存像。需要注意的是,如果图片尺寸不一致,可能需要调整或留白,或者统一缩放到相同尺寸。 接下来是matplotlib的方法。Matplotlib通常用于绘,但也可以用来组合多个子保存为一张图片。用户可能需要先创建子,调整子之间的间距,然后保存整个figure。不过如果已经有现成的图片文件,用matplotlib可能不太直接,可能需要将图片作为像添加到子中。或者,可以结合PIL和matplotlib,比如用matplotlib生成各个子保存为临时文件,再用PIL拼接。不过这可能比较复杂,可能不如直接用PIL方便。 另外,用户提到的参考引用[^2]提到位移信息已知,可能涉及像的对齐,但用户的问题似乎更关注简单的拼接,比如网格排列。因此,可能不需要复杂的特征点匹配,直接按位置排列即可。 可能的实现步骤: 1. 使用PIL的Image.open加载所有图片。 2. 确定每张图片的大小,假设所有图片尺寸相同,或者调整到相同尺寸。 3. 计算新画布的大小,例如2x2的网格,宽度为2*单宽度,高度为2*单高度。 4. 创建新Image对象,模式为RGB,大小合适。 5. 遍历图片列表,按行列位置计算左上角坐标,将图片粘贴到新画布上。 6. 保存像。 对于不同尺寸的图片,可能需要先调整大小。可以用thumbnail或resize方法统一尺寸。此外,处理RGBA模式时需要注意背景色,可能需要转换为RGB。 代码示例的大致结构可能如下: from PIL import Image import os # 加载图片 image_paths = ['1.jpg', '2.jpg', '3.jpg', '4.jpg'] images = [Image.open(path) for path in image_paths] # 调整图片尺寸一致 width, height = images[0].size for img in images: img = img.resize((width, height)) # 创建新画布 new_image = Image.new('RGB', (2*width, 2*height)) # 粘贴图片 new_image.paste(images[0], (0, 0)) new_image.paste(images[1], (width, 0)) new_image.paste(images[2], (0, height)) new_image.paste(images[3], (width, height)) # 保存 new_image.save('combined.jpg') 不过可能需要更通用的处理,比如处理任意数量的图片,自动计算行列数。例如,根据图片数量确定行数和列数,或者由用户指定。此外,处理图片列表的索引,循环粘贴。 对于matplotlib的方法,可以创建一个figure和多个subplot,然后在每个subplot中显示图片,最后保存整个figure。但需要注意matplotlib的默认设置可能会添加坐标轴等元素,需要关闭。例如: import matplotlib.pyplot as plt import matplotlib.image as mpimg fig, axes = plt.subplots(2, 2) for ax, img_path in zip(axes.flat, image_paths): img = mpimg.imread(img_path) ax.imshow(img) ax.axis('off') plt.subplots_adjust(wspace=0, hspace=0) plt.savefig('combined.png', bbox_inches='tight', pad_inches=0) plt.close() 这种方法可能会更简单,尤其是当图片数量适合子布局时。不过需要调整子之间的间距,避免边框干扰。 用户可能还需要考虑保存时的分辨率或格式问题,比如使用PIL时可以选择JPEG或PNG,而matplotlib保存图片可能会有不同的默认设置。此外,如果用户在没有形界面环境下运行,matplotlib可能需要设置后端为agg,如引用[^1]所述,即在导入pyplot之前执行import matplotlib; matplotlib.use('agg')。 因此,在回答中应该提供两种方法:使用PIL和matplotlib,分别说明步骤和代码示例,并提到无形界面时的注意事项。</think>[用户可见层] # 使用Python拼接多张像并保存单张图片的方法 ## 方法一:使用PIL库实现 **步骤说明:** 1. **加载图片**:使用`Image.open()`读取所有待拼接图片 2. **统一尺寸**(可选):建议将图片调整为相同尺寸,保证拼接整齐 3. **创建画布**:根据拼接布局计算新画布尺寸,例如2x2网格需要宽度=单宽度×2,高度=单高度×2 4. **定位粘贴**:按行列顺序将图片粘贴到画布对应位置 5. **保存结果**:使用`save()`方法输出最终像 **代码示例:** ```python from PIL import Image def combine_images(image_paths, rows=1, cols=1): # 加载所有图片 images = [Image.open(path) for path in image_paths] # 统一尺寸(以第一张为准) width, height = images[0].size for img in images: img = img.resize((width, height)) # 创建新画布 canvas = Image.new('RGB', (cols*width, rows*height)) # 拼接图片 for index, img in enumerate(images): x = (index % cols) * width # 列偏移量 y = (index // cols) * height # 行偏移量 canvas.paste(img, (x, y)) return canvas # 使用示例 combined = combine_images(['1.jpg', '2.jpg', '3.jpg', '4.jpg'], rows=2, cols=2) combined.save('combined_result.jpg') ``` **注意:** - 支持任意行列组合(如3x4网格) - 自动按加载顺序从左到右、从上到下排列 - 图片数量不足时会留白 ## 方法二:使用matplotlib实现 **步骤说明:** 1. **设置无界面模式**:在服务器等无形界面环境需先设置后端 2. **创建子网格**:使用`plt.subplots()`建立指定行列数的子 3. **隐藏坐标轴**:关闭所有子的坐标轴显示 4. **调整间距**:消除子之间的空白间隙 5. **保存结果**:使用`plt.savefig()`导出像 **代码示例:** ```python import matplotlib matplotlib.use('Agg') # 无形界面时必须设置 import matplotlib.pyplot as plt import matplotlib.image as mpimg def plot_combine(image_paths, rows=1, cols=1): fig, axes = plt.subplots(rows, cols, figsize=(10, 6)) # 处理单情况 if rows*cols == 1: axes = [axes] # 显示图片并关闭坐标轴 for ax, path in zip(axes.flat, image_paths): ax.imshow(mpimg.imread(path)) ax.axis('off') # 调整子间距 plt.subplots_adjust(wspace=0, hspace=0) plt.savefig('matplotlib_combined.jpg', bbox_inches='tight', dpi=300) plt.close() # 使用示例 plot_combine(['1.jpg', '2.jpg', '3.jpg', '4.jpg'], rows=2, cols=2) ``` **特性对比:** | 方法 | 优势 | 局限性 | |-------------|-------------------------------|---------------------------| | PIL | 处理速度快,适合大批量图片 | 需要手动调整布局参数 | | matplotlib | 自动布局,支持复杂子排列 | 内存消耗较大,输出速度较慢 | **常见问题处理:** 1. **图片尺寸不一致**:推荐先统一尺寸 ```python # 在PIL方法中添加尺寸统一代码 base_width = 800 for img in images: w_percent = base_width / float(img.size[0]) h_size = int(float(img.size[1]) * float(w_percent)) img = img.resize((base_width, h_size)) ``` 2. **透明背景处理**:转换RGBA模式为RGB ```python if img.mode == 'RGBA': img = img.convert('RGB') ```
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

electrochemjy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值