如何在其他Tk控件中使用matplotlib的mathtext渲染?

4 投票
1 回答
1600 浏览
提问于 2025-04-17 20:49

我知道 matplotlib 可以很方便地显示数学表达式,比如说:

txt=Text(x,y,r'$\frac{1}{2}')

这样可以在 x,y 的位置显示出 1/2 的分数。不过,我想要的不是把文字放在 x,y 的位置,而是想把渲染好的字符串放到一个单独的 Tk 应用程序里(比如一个输入框或下拉框)。我该怎么从 matplotlib 的 mathtext 中获取这个渲染好的字符串,然后放到我的 Tk 组件里呢?当然,如果有其他方法可以把 latex 字符串渲染到我的 Tk 组件里,而不使用 matplotlib,我也很欢迎,因为看起来 matplotlib 已经完成了大部分工作。

1 个回答

3

我在文档里找不到相关的信息,网上也没找到,不过我通过阅读mathtext的源代码找到了答案。那个例子是把图像保存到文件里。

from matplotlib.mathtext import math_to_image
math_to_image("$\\alpha$", "alpha.png", dpi=1000, format='png')

你可以使用ByteIO,这样可以把数据保存在内存中,而不是保存成文件。或者你可以直接从numpy数组渲染图像,这个数组是通过data.as_array()返回的,下面的代码示例也使用了cmap来控制打印出来的数学表达式的颜色。

from matplotlib.mathtext import MathTextParser
from matplotlib.image import imsave
parser =  MathTextParser('bitmap')
data, someint = parser.parse("$\\alpha$", dpi=1000)
imsave("alpha.png",data.as_array(),cmap='gray')

更新

这是一个完整的TkInter示例,基于Tkinter文档中的Hello World!例子,正如你所要求的。这段代码使用了PIL库。

import tkinter as tk
from matplotlib.mathtext import math_to_image
from io import BytesIO
from PIL import ImageTk, Image

class Application(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.pack()
        self.createWidgets()



    def createWidgets(self):

        #Creating buffer for storing image in memory
        buffer = BytesIO()

        #Writing png image with our rendered greek alpha to buffer
        math_to_image('$\\alpha$', buffer, dpi=1000, format='png')

        #Remoting bufeer to 0, so that we can read from it
        buffer.seek(0)

        # Creating Pillow image object from it
        pimage= Image.open(buffer)

        #Creating PhotoImage object from Pillow image object
        image = ImageTk.PhotoImage(pimage)

        #Creating label with our image
        self.label = tk.Label(self,image=image)

        #Storing reference to our image object so it's not garbage collected,
        # as TkInter doesn't store references by itself
        self.label.img = image

        self.label.pack(side="bottom")
        self.QUIT = tk.Button(self, text="QUIT", fg="red",
                                            command=root.destroy)
        self.QUIT.pack(side="top")

root = tk.Tk()
app = Application(master=root)
app.mainloop()

撰写回答