在wxpython GUI中嵌入matplotlib图的问题

时间:2015-02-05 23:13:41

标签: python matplotlib wxpython

我有一些生成情节的代码。这段代码是使用pylab的交互模式编写的,但此时我需要重新编写代码,以便将绘图嵌入到我的wxPython GUI中。问题是,这个数字显示出一个小的默认大小,我似乎无法改变。框架可以手动调整大小,然后一切看起来都很好。

这是一个演示基本问题的简单示例:

import wx
import matplotlib
import matplotlib.pyplot as plt
import numpy as np


class CanvasPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.figure = self.fake_depthplot()                                                               
        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)
        self.Fit()
        # these print statements give me a number like (1600, 1600)
        # however, when I use the wxpython inspector, it shows that the actual display size is MUCH smaller
        print self.Size 
        print self.canvas.Size

    def fake_depthplot(self):
        main_plot = plt.figure(1, figsize=(10, 8))
        main_plot.add_axes([0, 0, 1, 1])

        x1 = np.linspace(0.0, 5.0)
        x2 = np.linspace(0.0, 2.0)

        y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
        y2 = np.cos(2 * np.pi * x2)

        plt.subplot(4, 2, 1)
        plt.plot(x1, y1, 'ko-')
        plt.title('A tale of 2 subplots')
        plt.ylabel('Damped oscillation')

        plt.subplot(2, 1, 2)
        plt.plot(x2, y2, 'r.-')
        plt.xlabel('time (s)')
        plt.ylabel('Undamped')

        return main_plot


if __name__ == "__main__":
    app = wx.PySimpleApp()
    fr = wx.Frame(None, title='test')
    panel = CanvasPanel(fr)                                                                                                         
    if '-i' in sys.argv:
        import wx.lib.inspection
        wx.lib.inspection.InspectionTool().Show()
    fr.Show()
    app.MainLoop()

我希望这个帧可能是目前的两倍。此外,当我运行此代码时,显示器似乎闪烁为更大,但然后它调整到默认值我不喜欢很快。我猜这有一个简单的解决方案,但我似乎无法找到它。我找到的其他问题的答案都没有解决我的问题。

1 个答案:

答案 0 :(得分:1)

我认为建议不要使用pyplot。使用wxPython我也喜欢使用sizes_controls,它隐藏了一些sizer的东西,但是如果你需要它仍然可以控制它,同时它们符合平台UI指南。

使用sizer添加某些东西时,您需要告诉容器调用Layout / Fit来告诉它调整自己适应新的孩子。

您可能还想查看mpl示例: http://matplotlib.org/examples/user_interfaces/index.html

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import wx
import wx.lib.sized_controls as sc

import matplotlib as mpl
mpl.use('WXAgg')
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas

import numpy as np


class CanvasPanel(sc.SizedPanel):
    def __init__(self, parent):
        super(CanvasPanel, self).__init__(parent)
        self.figure = mpl.figure.Figure(figsize=(10, 8), dpi=75,
                                        facecolor='white', edgecolor='white')

        self.fake_depthplot()                                                               
        self.canvas = FigureCanvas(self, -1, self.figure)

        # these print statements give me a number like (1600, 1600)
        # however, when I use the wxpython inspector, it shows that the actual display size is MUCH smaller
        print(self.Size)
        print(self.canvas.Size)

    def fake_depthplot(self):
        main_plot = self.figure
        main_plot.add_axes([0, 0, 1, 1])

        x1 = np.linspace(0.0, 5.0)
        x2 = np.linspace(0.0, 2.0)

        y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
        y2 = np.cos(2 * np.pi * x2)

        plt = main_plot.add_subplot(4, 2, 1)
        plt.plot(x1, y1, 'ko-')
        plt.title.set_text('A tale of 2 subplots')
        plt.set_ylabel('Damped oscillation')

        plt = main_plot.add_subplot(2, 1, 2)
        plt.plot(x2, y2, 'r.-')
        plt.set_xlabel('time (s)')
        plt.set_ylabel('Undamped')


if __name__ == "__main__":
    app = wx.App()
    fr = sc.SizedFrame(None, title='test')
    print(fr.Size)
    pane = fr.GetContentsPane()
    panel = CanvasPanel(pane)
    fr.Fit()
    import sys
    if '-i' in sys.argv:
        import wx.lib.inspection
        wx.lib.inspection.InspectionTool().Show()
    fr.Show()
    app.MainLoop()