Reputation: 3190
I have some code that generates a plot. This code was written using pylab's interactive mode, but at this point I need to re-write the code so that I can embed the plot into my wxPython GUI. The problem is, the figure shows up squished down into a small default size that I can't seem to change. The frame can be manually resized and then everything looks good.
Here is a simple example that demonstrates the basic problem:
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()
I'd like for the frame to be maybe twice as large as it is currently. Also, when I run this code, the display seems to flash into existence as larger, but then it resizes to the default I don't like very quickly. I'm guessing this has a simple solution, but I can't seem to find it. None of the answers I have found for other questions fix my problem.
Upvotes: 0
Views: 1137
Reputation: 2096
I believe the recommendation is not to use pyplot. With wxPython I also like to use the sized_controls, which hide some of the sizer stuff, but still give you control if you need it and at the same time they comply with the platform UI guidelines.
With sizers when you add something you need to tell the container to call Layout/Fit to tell it to adjust itself to the new children.
You might also want to check out the mpl examples: 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()
Upvotes: 1