为什么try循环不能从Matplotlib mathtext捕获ParseException?

qeeaahzv  于 2023-03-30  发布在  其他
关注(0)|答案(1)|浏览(118)

wxPython 4.2.0 x Matplotlib 3.6.0
我正在开发一个GUI,用户可以在textctrl中编写一个图形标题,然后将此标题设置在一个图形上并显示该图形。
我现在的问题是,我不明白为什么try循环不能捕捉到当标题是错误的数学文本时发生的ParseException。
我的问题的简化代码是:

import matplotlib.pyplot as plt
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
import wx

class MyApp(wx.App):
    def OnInit(self):
        self.frame = MainFrame(parent=None, title="Test")
        self.frame.Show()
        return True

class MainFrame(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, None, -1, title=title)
        fig = plt.figure()
        fig.suptitle('$$')
        try:
            self.canvas = FigureCanvas(self, 0, fig)
        except:
            self.canvas = FigureCanvas(self, 0, plt.figure())
        plt.close()
        hbox = wx.BoxSizer(wx.HORIZONTAL)
        hbox.Add(self.canvas)
        self.SetSizer(hbox)

if __name__ == "__main__":
    app = MyApp()
    app.MainLoop()

出现以下错误:

Traceback (most recent call last):
...
    raise exc.with_traceback(None)
pyparsing.exceptions.ParseException: Expected end of text, found '$'  (at char 0), (line:1, col:1)

The above exception was the direct cause of the following exception:
...
...
ValueError:
$$
^
Expected end of text, found '$'  (at char 0), (line:1, col:1)

try循环应该能捕捉到这个,对吗?
例如,我使用了set_parse_math(False)方法,这样错误就不会发生,但是,我想知道这段代码有什么问题。

ccgok5k5

ccgok5k51#

我根据以下讨论找到了解决方案:
Validate MathText string at runtime
下面是我的工作代码:

import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
import wx

mpl.use('Agg') # important

class MyApp(wx.App):
    def OnInit(self):
        self.frame = MainFrame(parent=None, title="Test")
        self.frame.Show()
        return True

class MainFrame(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, None, -1, title=title)
        self.Maximize()
        self.fig = plt.figure()
        self.fig.add_subplot()
        self.canvas = FigureCanvas(self, 0, self.fig)
        hbox = wx.BoxSizer(wx.HORIZONTAL)
        hbox.Add(self.canvas)
        self.txtctrl = wx.TextCtrl(self)
        self.txtctrl.Bind(wx.EVT_TEXT, self.on_text)
        hbox.Add(self.txtctrl)
        self.SetSizer(hbox)
        plt.close()

    def verif_fig_text(self):
        self.Freeze()
        self.canvas.figure = plt.figure()
        ax = self.canvas.figure.add_subplot() # needed to insert x_label
        self.canvas.draw() # needed to get self.canvas.renderer attr
        valid_txt = True
        try:
            txt = ax.set_xlabel(self.txtctrl.GetValue()) 
            # insert x_label is the only mean to verif correct math text
            txt._get_layout(self.canvas.renderer)
            # indeed _get_layout() doesnt work with lot of stuff - found on Valid Mathtext string at runtime StackOverflow
        except:
            valid_txt = False # can't do much here, by adding anything else, the exception occurs outside the try loop
        plt.close()
        self.Thaw()
        return valid_txt
    
    def on_text(self, event):
        if self.verif_fig_text():
            self.fig.suptitle(self.txtctrl.GetValue())
        else:
            self.fig.suptitle('Wrong math text')
        self.canvas.figure = self.fig
        self.canvas.draw()
        plt.close()


if __name__ == "__main__":
    app = MyApp()
    app.MainLoop()

事实上,当有一个wx.EVT_TEXT时,我将一个新的(临时的)图设置为self.canvas。在这个图上,我添加一个子图,然后用textctrl值设置xlabel值,我使用_get_layout()方法检查文本是否是正确的数学文本,如果是,我将此文本设置为初始图的标题,并将其设置回self.canvas.draw()之前的self.canvas.figure

相关问题