【问题标题】:Convert matplotlib AxesImage to PIL PhotoImage, how to plot a matplotlib result in Tkinter将 matplotlib AxesImage 转换为 PIL PhotoImage,如何在 Tkinter 中绘制 matplotlib 结果
【发布时间】:2013-09-04 00:12:22
【问题描述】:

我正在尝试执行以下操作:

  1. 使用 matplotlib 包创建带有imshow() 的绘图,它提供matplotlib.image.AxesImage
  2. matplotlib.image.AxesImage 转换为PIL.ImageTk.PhotoImage
  3. 将此PIL.ImageTk.PhotoImage 用作 TkInter 画布上的图像

如何在不保存任何图像的情况下完成上述操作?

在参考了一篇帖子后,我尝试使用以下代码直接对我的数据进行颜色编码:

from Tkinter import *
from PIL import ImageTk,Image
import numpy as np
from pylab import cm
root=Tk()
canvas = Canvas(root)
canvas.pack(expand = YES, fill = BOTH)    
x = np.linspace(0, 2 * np.pi, 120)
y = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1)
myarray = np.sin(x) + np.cos(y)
image1 = Image.fromarray(np.uint8(cm.gist_earth(myarray)*255))
test = canvas.create_image(10,10,image = image1)
#canvas.itemconfig(test, image=nextimage)    
mainloop()

上面的代码给出了错误

TclError: image "<PIL.Image.Image image mode=RGBA size=120x100 at 0x2DC01E8>" doesn't exist

可能是什么问题?

【问题讨论】:

  • -你能避免步骤2和3,直接在canvas Tkinter中使用fig吗?请参阅link1 -Else 您可以将 savefig 的输出重定向到缓冲区,请参阅:link2
  • @Katsu 请参考我的更新

标签: python matplotlib tkinter python-imaging-library


【解决方案1】:

您必须创建并清空ImageTk.PhotoImage 实例,然后将Image 实例中的内容粘贴到那里。

如果您正在读取AxesImage 对象(由imshow 返回),您可以先将其数据传输到Image,然后粘贴到PhotoImage

这是一个示例(请注意,您实际上需要在网格上计算 myarray):

from Tkinter import *
from PIL import Image, ImageTk
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
root=Tk()
canvas = Canvas(root)
canvas.pack(expand = YES, fill = BOTH)
x = np.linspace(0, 2*np.pi, 400)
y = np.linspace(0, 2*np.pi, 400)
X, Y = np.meshgrid(x, y, copy=False)
myarray = np.cos(X) + np.cos(Y)

im_plt = plt.imshow(myarray)

image1 = Image.fromarray(np.uint8( im_plt.get_cmap()(im_plt.get_array())*255))
im = ImageTk.PhotoImage('RGB', image1.size)
im.paste(image1)
test = canvas.create_image(0, 0, image=im)
mainloop()

这将导致类似:

【讨论】:

  • 我可以将 imshow 生成的 matplotlib.image.AxesImage 也粘​​贴到这个 PhotoImage 上吗?
  • 我可以通过像这样buf = io.BytesIO() plt.savefig(buf, format = 'png') buf.seek(0) image11 = Image.open(buf) im = ImageTk.PhotoImage('RGBA',(120,100)) im.paste(image11) 使用 BytesIO 来做到这一点,有没有办法直接粘贴??
  • @lok​​esh 我已经更新了答案...可以直接将内容从imshow传递到Image,然后粘贴到PhotoImage
  • @lok​​esh 我还没玩够现在告诉你......但我相信有一个捷径可以避免这种情况
  • 结果不匹配。 PhotoImage 不同,imshow 绘图不同尝试分别绘图检查差异
猜你喜欢
  • 1970-01-01
  • 2019-02-11
  • 2017-12-13
  • 1970-01-01
  • 2021-04-09
  • 2023-03-25
  • 1970-01-01
  • 2019-12-27
  • 2018-09-06
相关资源
最近更新 更多