WX中的数学文本

演示如何将数学文本转换为wx.Bitmap,以便在wxPython的各种控件中显示。

  1. import matplotlib
  2. matplotlib.use("WxAgg")
  3. from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
  4. from matplotlib.backends.backend_wx import NavigationToolbar2Wx
  5. from matplotlib.figure import Figure
  6. import numpy as np
  7. import wx
  8. IS_GTK = 'wxGTK' in wx.PlatformInfo
  9. IS_WIN = 'wxMSW' in wx.PlatformInfo

This is where the “magic” happens.

  1. from matplotlib.mathtext import MathTextParser
  2. mathtext_parser = MathTextParser("Bitmap")
  3. def mathtext_to_wxbitmap(s):
  4. ftimage, depth = mathtext_parser.parse(s, 150)
  5. return wx.Bitmap.FromBufferRGBA(
  6. ftimage.get_width(), ftimage.get_height(),
  7. ftimage.as_rgba_str())
  1. functions = [
  2. (r'$\sin(2 \pi x)$', lambda x: np.sin(2*np.pi*x)),
  3. (r'$\frac{4}{3}\pi x^3$', lambda x: (4.0/3.0)*np.pi*x**3),
  4. (r'$\cos(2 \pi x)$', lambda x: np.cos(2*np.pi*x)),
  5. (r'$\log(x)$', lambda x: np.log(x))
  6. ]
  7. class CanvasFrame(wx.Frame):
  8. def __init__(self, parent, title):
  9. wx.Frame.__init__(self, parent, -1, title, size=(550, 350))
  10. self.figure = Figure()
  11. self.axes = self.figure.add_subplot(111)
  12. self.canvas = FigureCanvas(self, -1, self.figure)
  13. self.change_plot(0)
  14. self.sizer = wx.BoxSizer(wx.VERTICAL)
  15. self.add_buttonbar()
  16. self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
  17. self.add_toolbar() # comment this out for no toolbar
  18. menuBar = wx.MenuBar()
  19. # File Menu
  20. menu = wx.Menu()
  21. m_exit = menu.Append(wx.ID_EXIT, "E&xit\tAlt-X", "Exit this simple sample")
  22. menuBar.Append(menu, "&File")
  23. self.Bind(wx.EVT_MENU, self.OnClose, m_exit)
  24. if IS_GTK or IS_WIN:
  25. # Equation Menu
  26. menu = wx.Menu()
  27. for i, (mt, func) in enumerate(functions):
  28. bm = mathtext_to_wxbitmap(mt)
  29. item = wx.MenuItem(menu, 1000 + i, " ")
  30. item.SetBitmap(bm)
  31. menu.Append(item)
  32. self.Bind(wx.EVT_MENU, self.OnChangePlot, item)
  33. menuBar.Append(menu, "&Functions")
  34. self.SetMenuBar(menuBar)
  35. self.SetSizer(self.sizer)
  36. self.Fit()
  37. def add_buttonbar(self):
  38. self.button_bar = wx.Panel(self)
  39. self.button_bar_sizer = wx.BoxSizer(wx.HORIZONTAL)
  40. self.sizer.Add(self.button_bar, 0, wx.LEFT | wx.TOP | wx.GROW)
  41. for i, (mt, func) in enumerate(functions):
  42. bm = mathtext_to_wxbitmap(mt)
  43. button = wx.BitmapButton(self.button_bar, 1000 + i, bm)
  44. self.button_bar_sizer.Add(button, 1, wx.GROW)
  45. self.Bind(wx.EVT_BUTTON, self.OnChangePlot, button)
  46. self.button_bar.SetSizer(self.button_bar_sizer)
  47. def add_toolbar(self):
  48. """Copied verbatim from embedding_wx2.py"""
  49. self.toolbar = NavigationToolbar2Wx(self.canvas)
  50. self.toolbar.Realize()
  51. # By adding toolbar in sizer, we are able to put it at the bottom
  52. # of the frame - so appearance is closer to GTK version.
  53. self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND)
  54. # update the axes menu on the toolbar
  55. self.toolbar.update()
  56. def OnChangePlot(self, event):
  57. self.change_plot(event.GetId() - 1000)
  58. def change_plot(self, plot_number):
  59. t = np.arange(1.0, 3.0, 0.01)
  60. s = functions[plot_number][1](t)
  61. self.axes.clear()
  62. self.axes.plot(t, s)
  63. self.canvas.draw()
  64. def OnClose(self, event):
  65. self.Destroy()
  66. class MyApp(wx.App):
  67. def OnInit(self):
  68. frame = CanvasFrame(None, "wxPython mathtext demo app")
  69. self.SetTopWindow(frame)
  70. frame.Show(True)
  71. return True
  72. app = MyApp()
  73. app.MainLoop()

下载这个示例