Python和Matplotlib无法绘图问题的解决方案

258 阅读2分钟

如果你在使用 Python 和 Matplotlib 时遇到无法绘图的问题,可能是由几个常见的原因引起的。以下是一些常见的问题及其解决方案:

a4.png

1、 问题背景

在试图开发一个应用程序时,用户在输入值并按下按钮后,试图绘制图形,但是绘图失败。简化后的代码如下所示:

from numpy import arange, sin, pi
import matplotlib
matplotlib.use('WXAgg')
​
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.backends.backend_wx import NavigationToolbar2Wx
from matplotlib.figure import Figure
​
import wx
​
class Input_Panel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        # Input variables
        self.button = wx.Button(self, label="Go")
​
        # Set sizer for the panel content
        self.sizer = wx.GridBagSizer(1, 1)
        self.sizer.Add(self.button, (1, 2), (3, 6), flag=wx.EXPAND)
        self.SetSizer(self.sizer)
​
class Output_Panel_Var(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        # Output variables
        self.tittle = wx.StaticText(self, label="OUTPUTS:")
        self.font = wx.Font(12, wx.DECORATIVE, wx.BOLD, wx.NORMAL)
        self.tittle.SetFont(self.font)
        self.lblt = wx.StaticText(self, label="t:")
        self.resultt = wx.StaticText(self, label="", size=(100, -1))
        self.lbls = wx.StaticText(self, label="s:")
        self.results = wx.StaticText(self, label="", size=(100, -1))
​
        # Set sizer for the panel content
        self.sizer = wx.GridBagSizer(2, 2)
        self.sizer.Add(self.tittle, (1, 3))
        self.sizer.Add(self.lblt, (3, 1))
        self.sizer.Add(self.resultt, (3, 2))
        self.sizer.Add(self.lbls, (4, 1))
        self.sizer.Add(self.results, (4, 2))
        self.SetSizer(self.sizer)
​
class Output_Panel_Fig(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.sizer)
​
    def draw(self,t,s):
        self.axes.plot(t, s)
​
​
class Main_Window(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title = title, pos = (0, 0), size = wx.DisplaySize())
​
        # Set variable panels
        self.main_splitter = wx.SplitterWindow(self)
        self.out_splitter = wx.SplitterWindow(self.main_splitter)
        self.inputpanel = Input_Panel(self.main_splitter)
        self.inputpanel.SetBackgroundColour('#c4c4ff')
        self.outputpanelvar = Output_Panel_Var(self.out_splitter)
        self.outputpanelvar.SetBackgroundColour('#c2f1f5')
        self.outputpanelfig = Output_Panel_Fig(self.out_splitter)
        self.main_splitter.SplitVertically(self.inputpanel, self.out_splitter)
        self.out_splitter.SplitHorizontally(self.outputpanelvar, self.outputpanelfig)
​
        # Set event handlers
        self.inputpanel.button.Bind(wx.EVT_BUTTON, self.OnButton)      
​
    def OnButton(self, e):
        t = arange(0.0, 1.0, 0.01)
        s = sin(2 * pi * t)
        #self.outputpanelvar.resultt.SetLabel('%.5f' % t)
        #self.outputpanelvar.resultt.SetLabel('%.5f' % s)
        self.outputpanelfig.draw(t,s)
​
def main():
    app = wx.App(False)
    frame = Main_Window(None, "T-Matrix Codes GUI")
    frame.Show()
    app.MainLoop()
if __name__ == "__main__" :
    main()

如果直接绘制 t 和 s 的值,则绘图正常,但在按下按钮后,绘图失败。

2、 解决方案

解决方案是在 Output_Panel_Fig 类中的 draw 方法中添加 self.canvas.draw(),以便在绘制完图形后刷新绘图面板。

class Output_Panel_Fig(wx.Panel):
    def __init__(self, parent):
        ...
​
    def draw(self,t,s):
        self.axes.plot(t, s)
​
        self.canvas.draw()

完整代码如下:

from numpy import arange, sin, pi
import matplotlib
matplotlib.use('WXAgg')
​
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.backends.backend_wx import NavigationToolbar2Wx
from matplotlib.figure import Figure
​
import wx
​
class Input_Panel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        # Input variables
        self.button = wx.Button(self, label="Go")
​
        # Set sizer for the panel content
        self.sizer = wx.GridBagSizer(1, 1)
        self.sizer.Add(self.button, (1, 2), (3, 6), flag=wx.EXPAND)
        self.SetSizer(self.sizer)
​
class Output_Panel_Var(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        # Output variables
        self.tittle = wx.StaticText(self, label="OUTPUTS:")
        self.font = wx.Font(12, wx.DECORATIVE, wx.BOLD, wx.NORMAL)
        self.tittle.SetFont(self.font)
        self.lblt = wx.StaticText(self, label="t:")
        self.resultt = wx.StaticText(self, label="", size=(100, -1))
        self.lbls = wx.StaticText(self, label="s:")
        self.results = wx.StaticText(self, label="", size=(100, -1))
​
        # Set sizer for the panel content
        self.sizer = wx.GridBagSizer(2, 2)
        self.sizer.Add(self.tittle, (1, 3))
        self.sizer.Add(self.lblt, (3, 1))
        self.sizer.Add(self.resultt, (3, 2))
        self.sizer.Add(self.lbls, (4, 1))
        self.sizer.Add(self.results, (4, 2))
        self.SetSizer(self.sizer)
​
class Output_Panel_Fig(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.sizer)
​
    def draw(self,t,s):
        self.axes.plot(t, s)
​
        self.canvas.draw()
​
​
class Main_Window(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title = title, pos = (0, 0), size = wx.DisplaySize())
​
        # Set variable panels
        self.main_splitter = wx.SplitterWindow(self)
        self.out_splitter = wx.SplitterWindow(self.main_splitter)
        self.inputpanel = Input_Panel(self.main_splitter)
        self.inputpanel.SetBackgroundColour('#c4

如果上述方法都不能解决问题,仔细检查运行代码时的错误消息。错误消息通常会提供为什么 Matplotlib 无法绘图的线索。你可以根据错误消息进行具体的 Google 搜索,查找解决方案。

如果在解决 Matplotlib 绘图问题时还有其他疑问,可以提供更具体的代码和错误信息,以便进一步诊断和解决问题。