在 wxpython GUI 中嵌入 matplotlib 图的大小调整问题
sizing problems embedding matplotlib figure in wxpython GUI
我有一些生成绘图的代码。这段代码是使用 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()
我希望相框可以比现在大一倍。此外,当我 运行 这段代码时,显示似乎变大了,但随后又调整为默认大小,我不喜欢很快。我猜这有一个简单的解决方案,但我似乎找不到。 None 我为其他问题找到的答案解决了我的问题。
我认为建议不要使用 pyplot。对于 wxPython,我也喜欢使用 sized_controls,它隐藏了一些 sizer 的东西,但如果你需要它仍然可以让你控制,同时它们符合平台 UI 指南。
使用 sizer 时,当你添加一些东西时,你需要告诉容器调用 Layout/Fit 来告诉它自己调整到新的 children。
您可能还想查看 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()
我有一些生成绘图的代码。这段代码是使用 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()
我希望相框可以比现在大一倍。此外,当我 运行 这段代码时,显示似乎变大了,但随后又调整为默认大小,我不喜欢很快。我猜这有一个简单的解决方案,但我似乎找不到。 None 我为其他问题找到的答案解决了我的问题。
我认为建议不要使用 pyplot。对于 wxPython,我也喜欢使用 sized_controls,它隐藏了一些 sizer 的东西,但如果你需要它仍然可以让你控制,同时它们符合平台 UI 指南。
使用 sizer 时,当你添加一些东西时,你需要告诉容器调用 Layout/Fit 来告诉它自己调整到新的 children。
您可能还想查看 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()