user1352331
user1352331

Reputation: 91

Adding a gridded subplot to WxPython GUI (Matplotlib)

I'm developing a simple demonstration GUI for a multi-lateral ultrasonic rangefinder. A device captures ultrasonic signals from several different sensors, performs time of flight processing on these signals, then uses the range information of detected targets to localize an object in 2D cartesian coordinates.

I'd like to create a wxPython GUI, which uses matplotlib to display each of the sensors signals and plot the target locations. I've found some example code which has roughly the same layout that I'd like to have, and have removed some of the code's unnecessary components. The python code is below:

import sys,os,csv
import numpy as N
import wx
import matplotlib
from matplotlib.figure import Figure
from matplotlib.backends.backend_wxagg import \
    FigureCanvasWxAgg as FigCanvas, \
    NavigationToolbar2WxAgg as NavigationToolbar
class FinalProject(wx.Frame):
    title = ' Ultrasound Demo '
    def __init__(self):
        wx.Frame.__init__(self, None, -1, self.title)
        self.create_menu()
        self.create_status_bar()
        self.create_main_panel()
    def create_menu(self):
        self.menubar = wx.MenuBar()
        menu_file = wx.Menu()
        m_expt = menu_file.Append(-1, "&Save plot\tCtrl-S", "Save plot to file")
        self.Bind(wx.EVT_MENU, self.on_save_plot, m_expt)
        menu_file.AppendSeparator()
        m_exit = menu_file.Append(-1, "E&xit\tCtrl-X", "Exit")
        self.Bind(wx.EVT_MENU, self.on_exit, m_exit)
        self.menubar.Append(menu_file, "&File")
        self.SetMenuBar(self.menubar)
    def create_main_panel(self):
        self.panel = wx.Panel(self)
        self.dpi = 100
        self.fig = Figure((9.5, 5.0), dpi=self.dpi)
        self.canvas = FigCanvas(self.panel, -1, self.fig)
#        self.axes1 = self.fig.add_subplot2grid((2,2), (0,0))
        self.axes1 = self.fig.add_subplot(2,1,1)
#        self.axes2 = self.fig.add_subplot2grid((2,2), (1,0))
        self.axes2 = self.fig.add_subplot(2,1,2)

        self.toolbar = NavigationToolbar(self.canvas)
        self.vbox = wx.BoxSizer(wx.VERTICAL)
        self.vbox.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.vbox.AddSpacer(10)
        self.hbox = wx.BoxSizer(wx.HORIZONTAL)
        flags = wx.ALIGN_LEFT | wx.ALL | wx.ALIGN_CENTER_VERTICAL
        self.panel.SetSizer(self.vbox)
        self.vbox.Fit(self)
    def create_status_bar(self):
        self.statusbar = self.CreateStatusBar()
    def on_draw_button1(self, event):
        self.axes1.clear()
        self.axes2.clear()
        i = N.arange(0,4,1)
        q = i
        w = N.arange(-4,0,1)
        self.axes1.plot(q,i,'red')
        self.axes2.plot(w,i,'yellow')
        self.canvas.draw()
    def on_draw_button2(self, event):
        self.axes1.clear()
        self.axes2.clear()
        a = [0,1,2,3,4,]
        b = [5.5,4.5,3.5,2.5,1.5]
        c = [7.5,2.5,4,6.8,10.6]
        self.axes1.plot(b,a,'purple')
        self.axes2.plot(c,a,'black')
        self.canvas.draw()
    def on_save_plot(self, event): 
        file_choices = "PNG (*.png)|*.png"
        dlg = wx.FileDialog(
            self, 
            message="Save plot as...",
            defaultDir=os.getcwd(),
            defaultFile="plot.png",
            wildcard=file_choices,
            style=wx.SAVE)

        if dlg.ShowModal() == wx.ID_OK:
            path = dlg.GetPath()
            self.canvas.print_figure(path, dpi=self.dpi)
            self.flash_status_message("Saved to %s" % path)

    def on_exit(self, event):
        self.Destroy()
if __name__ == '__main__':
    app = wx.PySimpleApp()
    app.frame = FinalProject()
    app.frame.Show()
    app.MainLoop()
    del app

So, this code would be useful for displaying two captured signals, and it's relatively easy to add additional subplots, provided they exist on a symmetrical grid, but what I would like to do is add a third subplot to the right of these two plots which spans the height of both.

To be clear what I would like to do is add a third subplot to the right of the existing plots the height of which is equal to the current canvas height.

Reading through the matplotlib documentation it looks like the appropriate function to do this would be plt.subplot2grid(). Unfortunately I get errors when I attempt to use this function to define the current subplots (the code I attempted to use is commented out below:

self.axes1 = self.fig.add_subplot2grid((2,2), (0,0)))

Has anyone else attempted this? Any ideas on where I might be going wrong?

Thanks!

Upvotes: 1

Views: 1900

Answers (1)

pelson
pelson

Reputation: 21849

Sounds like you have already figured out something to do what you wanted.

To be explicit, there is nothing specific about the fact that you are using WX python in this example - essentially the question boils down to how one would go about adding an axes to a figure which has the same height as two other axes.

This can be done very simply with:

import matplotlib.pyplot as plt
ax1 = plt.subplot(2, 2, 1)
ax2 = plt.subplot(2, 2, 3)
ax3 = plt.subplot(1, 2, 2)
plt.show()

HTH

Upvotes: 1

Related Questions