Reputation: 3
I have a very simple panel, where you click a button and a plot is created (using matplotlib) and the plot is saved as a .png in my working folder.
Once the plot is created my panel shrinks in size. Does anyone know why this is?
Below is the code, and then screenshots of before and after the button is clicked.
import wx
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
class MyApp(wx.App):
def __init__(self):
super().__init__(clearSigInt=True)
self.InitFrame()
def InitFrame(self):
frame = MyFrame(parent=None, title='My Frame', pos = (100,100))
frame.Show()
class MyFrame(wx.Frame):
def __init__(self, parent, title, pos):
super().__init__(parent=parent, title=title, pos=pos)
self.OnInit()
def OnInit(self):
panel = MyPanel(parent=self)
class MyPanel(wx.Panel):
def __init__(self, parent):
super().__init__(parent=parent)
button = wx.Button(parent=self, label = "Create plot", pos = (20,80))
button.Bind(event=wx.EVT_BUTTON, handler=self.onSubmit)
def onSubmit(self,event):
ActivityDF = pd.DataFrame({
'Activity': ['A','B','C','D'],
'Count': [10,20,30,40]
})
fig, ax = plt.subplots(1)
ax.barh(ActivityDF['Activity'], ActivityDF['Count'])
fig.savefig('Figure.png',bbox_inches='tight', facecolor="None")
if __name__ == "__main__":
app = MyApp()
app.MainLoop()
Before button clicked After button clicked
Upvotes: 0
Views: 72
Reputation: 1436
Welcome to Stack Overflow.
First, your code is a little bit overcomplicated. There is no need to use so many classes.
Second, if you plan to use matplotlib with a GUI library then you need to import a backend so matplotlib works fine within the application you are writting.
Regarding why the panel is schrinking. I am not really sure. Perhaps an error when matplotlib tries to plot without the appropiate backend.
I simplified your code and added some comments to it.
import wx
import numpy as np
import matplotlib as mpl
## Import the matplotlib backend for wxPython
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
## Only one class is really needed in this case. There is no need to have
## a class for the App, a class for the frame and a class for the panel
class MyWin(wx.Frame):
def __init__(self, title, pos):
super().__init__(parent=None, title=title, pos=pos)
self.panel = wx.Panel(parent=self)
self.button = wx.Button(parent=self.panel, label='Create plot', pos=(20, 80))
self.button.Bind(wx.EVT_BUTTON, self.onSubmit)
def onSubmit(self, event):
x = np.arange(10)
y = np.arange(10)
## This is to work with matplotlib inside wxPython
## I prefer to use the object oriented API
self.figure = mpl.figure.Figure(figsize=(5, 5))
self.axes = self.figure.add_subplot(111)
self.canvas = FigureCanvas(self, -1, self.figure)
## This is to avoid showing the plot area. When set to True
## clicking the button show the canvas and the canvas covers the button
## since the canvas is placed by default in the top left corner of the window
self.canvas.Show(False)
self.axes.plot(x, y)
self.figure.savefig('Figure.png', bbox_inches='tight', facecolor='None')
if __name__ == '__main__':
app = wx.App()
win = MyWin('My Frame', (100, 100))
win.Show()
app.MainLoop()
Hope this helps.
Upvotes: 1