0

I have a 2x2 FlexGridSizer in a panel and I want to insert four different matplotlib figures with their own toolbars at the same time.

I have seen many links related and working examples embedding one figure, but as I am a begginer with wxPython and OOP I get quite confuse when testing some codes and trying to merge them with mine.

Here is a piece of the page class of a wx.Notebook where I want to put the figures

class Pagina(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)

        self.boton_descargar = wx.Button(self, -1, label=u"Descargar")
        self.boton_desconectar = wx.Button(self, -1, label=u"Desconectar")

        sizer = wx.BoxSizer(wx.VERTICAL)
        subsizer1 = wx.BoxSizer(wx.HORIZONTAL)
        subsizer2 = wx.FlexGridSizer(rows=2, cols=2)

        sizer.Add(subsizer1, 0, wx.EXPAND | wx.ALL, 0)
        sizer.Add(subsizer2, 1, wx.EXPAND | wx.ALL, 0)
        sizer.Add(self.boton_desconectar, 0, wx.ALIGN_RIGHT | wx.RIGHT, 10)
        subsizer1.Add(self.boton_descargar, 0, wx.ALL, 10)

        self.Bind(wx.EVT_BUTTON, self.onClick_descargar, self.boton_descargar)
        self.Bind(wx.EVT_BUTTON, self.onClick_desconectar, self.boton_desconectar)

        self.SetSizer(sizer)

    def onClick_descargar(self, event):
        HiloDescarga()

    def onClick_desconectar(self, event):
        pass

HiloDescarga is actually a thread launched to download some text lines, process data and plotting this way (the fourth figure is the same thing):

import matplotlib.pyplot as plt

line, = plt.plot(range(len(x)), x, '-', linewidth=1)
line, = plt.plot(range(len(x)), f, 'y-', linewidth=1)
plt.xlabel('x')
plt.ylabel('y')
plt.title(r'title1')
plt.grid()
plt.figure()

line, = plt.plot(range(len(y)), y, 'r-', linewidth=1)
line, = plt.plot(range(len(y)), g, 'y-', linewidth=1)
plt.xlabel('x')
plt.ylabel('y')
plt.title(r'title2')
plt.grid()
plt.figure()

line, = plt.plot(range(len(z)), z, 'g-', linewidth=1)
line, = plt.plot(range(len(z)), h, 'y-', linewidth=1)
plt.xlabel('x')
plt.ylabel('y')
plt.title(r'title3')
plt.grid()

plt.show()

so the figures are just popping in separated windows. If you could give me a snippet or at least some orientation, perhaps a few changes to the plotting code, I don't know. Any help is welcomed.

1 Answer 1

2

You just have to follow the examples where they embed one Figure, but instead instantiate several members for each of the figures you want to create. Here is a quick example:

import matplotlib
matplotlib.use('WXAgg')
from matplotlib.figure import Figure
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
import wx


class MyFrame(wx.Frame):
    def __init__(self, parent, nbFigures=4):
        super(MyFrame, self).__init__(parent)
        sizer = wx.BoxSizer(wx.VERTICAL)
        self.figs = [Figure(figsize=(2,1)) for _ in range(nbFigures)]
        self.axes = [fig.add_subplot(111) for fig in self.figs]
        self.canvases = [FigureCanvas(self, -1, fig) for fig in self.figs]
        for canvas in self.canvases:
            sizer.Add(canvas, 0, wx.ALL, 5)
        self.SetSizer(sizer)

app = wx.App()
frm = MyFrame(None)
frm.Show()
app.MainLoop()

enter image description here

I've saved the instances of each figure in the array self.figs and each instances of the axes on each figure in self.axes

Hope that puts you in the right tracks

Sign up to request clarification or add additional context in comments.

2 Comments

I'm gonna give this a try in a minute. I have one doubt though. Is it a good idea to start a new thread for the plotting task? My standalone plotting script takes a while to do it.
Sorry, can't really help you with that

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.