正如标题所述,我正试图将fig分转换为PIL.Image分.目前,我可以先将fig保存到磁盘,然后使用Image.open()打开该文件,但这个过程比预期的要长,我希望通过跳过本地保存步骤,速度会快一点.

以下是我目前掌握的情况:

# build fig
figsize, dpi = self._calc_fig_size_res(img_height)
fig = plt.Figure(figsize=figsize)
canvas = FigureCanvas(fig)
ax = fig.add_subplot(111)
ax.imshow(torch.from_numpy(S).flip(0), cmap = cmap)
fig.subplots_adjust(left = 0, right = 1, bottom = 0, top = 1)
ax.axis('tight'); ax.axis('off')

# export
fig.savefig(export_path, dpi = dpi)

# open image as PIL object
img = Image.open(export_path)

我在构建fig后try 过这样做(在导出阶段之前):

pil_img = Image.frombytes('RGB', canvas.get_width_height(), canvas.tostring_rgb())

但它并没有显示整个图像.它看起来像是左上角的一个片段,但它可能只是数据的一个奇怪的表示形式——我正在处理 spectral 图,所以图像相当抽象.

推荐答案

编辑#2

PIL.Image.frombytes('RGB', 
fig.canvas.get_width_height(),fig.canvas.tostring_rgb())

与下面的35/40ms相比,大约需要2ms.

这是迄今为止我能找到的最快的方法.


我今天也一直在看这个.

在matplotlib文档中,savefig函数具有以下功能.

sdu,传递的附加参数是可选的

这一定意味着它在保存之前已经是一个pil图像,但我看不到它.

你可以跟着这个

Matplotlib: save plot to numpy array

将其放入numpy数组,然后

比尔.形象fromarray(数组)

您可能需要使用数组[:,:,::-1]将通道从BGR反转为RGB

编辑:

到目前为止,我已经测试了每种方法.

import io
    
def save_plot_and_get():
    fig.savefig("test.jpg")
    img = cv2.imread("test.jpg")
    return PIL.Image.fromarray(img)
    
def buffer_plot_and_get():
    buf = io.BytesIO()
    fig.savefig(buf)
    buf.seek(0)
    return PIL.Image.open(buf)
    
def from_canvas():
    lst = list(fig.canvas.get_width_height())
    lst.append(3)
    return PIL.Image.fromarray(np.fromstring(fig.canvas.tostring_rgb(),dtype=np.uint8).reshape(lst))

后果

%timeit save_plot_and_get()

每个回路35.5 ms±148µs(7次运行的平均值±标准偏差,每个10个回路)

%timeit save_plot_and_get()

每个回路35.5 ms±142µs(7次运行的平均值±标准偏差,每个10个回路)

%timeit buffer_plot_and_get()

每个回路40.4 ms±152µs(7次运行的平均值±标准偏差,每个10个回路)

Python-3.x相关问答推荐

为什么vs code返回错误—LocaleError:int对象没有属性where,但相同的代码运行在Google Colab上没有任何问题''''

将数据帧扩展为矩阵索引

regexp多重前瞻行为的解释

无法导入名称';核心';来自部分初始化的模块';tensorflow_datasets';(很可能是由于循环导入)

如何强调您正在寻求以 pandas 数据帧的另一列为条件的差异?

使用 iloc 或 loc 对多列进行过滤

Sunburst 折线图可视化

根据按不同列中的值分组的平均值划分 DataFrame

在 python pandas 中设置条件和分配新值

根据另一列值对多个数据框列进行分组

在 jupyter notebook 的单元格中使用 sudo

有没有更好的方法来判断一个数字是否是两个数字的范围

创建一个可旋转的 3D 地球

pythondecorator中的变量范围

如何将numpy数组图像转换为字节?

使用 Tensorflow 2.0 在 MNIST 上实现自定义神经网络?

try 在 Windows 10 高 DPI 显示器上解决模糊的 tkinter 文本 + zoom ,但担心我的方法不是 Pythonic 或不安全

我可以替换 Python 中对象的现有方法吗?

如何创建一个永远在其上运行滚动协程的事件循环?

为什么某些代码在 Python2 中是确定性的,而在 Python 3 中是非确定性的?