Specifying and saving a figure with exact size in pixels
假设我的图像尺寸为3841 x 7195像素。我想将图形的内容保存到磁盘,以得到我指定的确切大小(以像素为单位)的图像。
没有轴,没有标题。只是图像。我个人并不关心DPI,因为我只想指定图像在磁盘中的大小(以像素为单位)。
我读过其他线程,它们似乎都转换为英寸,然后以英寸为单位指定图形尺寸并以某种方式调整dpi。我想避免处理像素到英寸转换可能导致的精度损失。
我尝试过:
1 2 3 4 5 6 7 8 9 | w = 7195 h = 3841 fig = plt.figure(frameon=False) fig.set_size_inches(w,h) ax = plt.Axes(fig, [0., 0., 1., 1.]) ax.set_axis_off() fig.add_axes(ax) ax.imshow(im_np, aspect='normal') fig.savefig(some_path, dpi=1) |
没有运气(Python抱怨宽度和高度都必须低于32768(?))
从我所看到的一切来看,
需要说明的是:我正在寻找一种使用
Matplotlib不能直接处理像素,而是可以处理物理尺寸和DPI。如果要显示具有特定像素大小的图形,则需要知道显示器的DPI。例如,此链接将为您检测到该链接。
如果您具有3841x7195像素的图像,则监视器不太可能会那么大,因此您将无法显示该尺寸的图形(matplotlib要求该图形适合屏幕尺寸,如果您要求一个尺寸太大会缩小到屏幕尺寸)。让我们想象一下,您仅需要一个800x800像素的图像作为示例。这是在监视器(
1 | plt.figure(figsize=(800/my_dpi, 800/my_dpi), dpi=my_dpi) |
因此,您基本上只需将尺寸(英寸)除以DPI。
如果要保存特定大小的图形,则是另一回事。屏幕DPI不再那么重要了(除非您要求提供一个不适合屏幕的数字)。使用相同的800x800像素图形示例,我们可以使用
1 | plt.savefig('my_fig.png', dpi=my_dpi) |
要将其保存为8000x8000像素的图像,请使用10倍大的dpi:
1 | plt.savefig('my_fig.png', dpi=my_dpi * 10) |
请注意,并非所有后端都支持DPI的设置。在这里,使用PNG后端,但是pdf和ps后端将以不同的方式实现大小。另外,更改DPI和大小也会影响诸如fontsize之类的内容。较大的DPI将保持相同的字体和元素的相对大小,但是如果您想为较大的图形使用较小的字体,则需要增加物理尺寸而不是DPI。
回到您的示例,如果要保存3841 x 7195像素的图像,可以执行以下操作:
1 2 3 | plt.figure(figsize=(3.841, 7.195), dpi=100) ( your code ...) plt.savefig('myfig.png', dpi=1000) |
请注意,我使用100的数字dpi来适合大多数屏幕,但是用
根据您的代码,这对我有用,生成了一个93Mb png图像,带有彩色噪点和所需的尺寸:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import matplotlib.pyplot as plt import numpy w = 7195 h = 3841 im_np = numpy.random.rand(h, w) fig = plt.figure(frameon=False) fig.set_size_inches(w,h) ax = plt.Axes(fig, [0., 0., 1., 1.]) ax.set_axis_off() fig.add_axes(ax) ax.imshow(im_np, aspect='normal') fig.savefig('figure.png', dpi=1) |
我正在使用Linux Mint 13中Python 2.7库的最新PIP版本。
希望有帮助!
根据tiago接受的响应,这是一个小型通用函数,该函数将numpy数组导出到分辨率与该数组相同的图像:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import matplotlib.pyplot as plt import numpy as np def export_figure_matplotlib(arr, f_name, dpi=200, resize_fact=1, plt_show=False): """ Export array as figure in original resolution :param arr: array of image to save in original resolution :param f_name: name of file where to save figure :param resize_fact: resize facter wrt shape of arr, in (0, np.infty) :param dpi: dpi of your screen :param plt_show: show plot or not """ fig = plt.figure(frameon=False) fig.set_size_inches(arr.shape[1]/dpi, arr.shape[0]/dpi) ax = plt.Axes(fig, [0., 0., 1., 1.]) ax.set_axis_off() fig.add_axes(ax) ax.imshow(arr) plt.savefig(f_name, dpi=(dpi * resize_fact)) if plt_show: plt.show() else: plt.close() |
如tiago上次答复中所述,首先需要找到屏幕DPI,例如,可以在此处完成:http://dpi.lv
我在函数中添加了一个附加参数