Embedding Basemap in a wx app

Dear ALL,

Greetings. Trying to develop a desktop application for interactive
mapping using wxPython and Matplotlib, I have been doing some
experiments with embedding maps generated by the Basemap module into a
wxPython frame.

Although there are many nice exemples of using Matplotlib graphs in
wxWpython and other GUI frontends, I could not find any examples of
doing this with the Basemap module.

As a quick start, I put together the the code below (adapted from one
of the examples available in the Matplotlib website):

···

--

#!/usr/bin/env python
import matplotlib
import matplotlib.pyplot

from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.backends.backend_wx import NavigationToolbar2Wx
from matplotlib.figure import Figure

from mpl_toolkits.basemap import Basemap

from wx import *

class CanvasFrame(Frame):
  def __init__(self):
    Frame.__init__(self,None,-1,
            'CanvasFrame',size=(550,350))

    self.SetBackgroundColour(NamedColor("WHITE"))

    self.figure = Figure()
    
    self.canvas = FigureCanvas(self, -1, self.figure)

    self.sizer = BoxSizer(VERTICAL)
    self.sizer.Add(self.canvas, 1, LEFT | TOP | GROW)
    self.SetSizer(self.sizer)
    self.Fit()

    self.add_toolbar() # comment this out for no toolbar
    
                # This functions plots the Basemap
    self.plot_map()
    
  def add_toolbar(self):
    self.toolbar = NavigationToolbar2Wx(self.canvas)
    self.toolbar.Realize()
    if Platform == '__WXMAC__':
      # Mac platform (OSX 10.3, MacPython) does not seem to cope with
      # having a toolbar in a sizer. This work-around gets the buttons
      # back, but at the expense of having the toolbar at the top
      self.SetToolBar(self.toolbar)
    else:
      # On Windows platform, default window size is incorrect, so set
      # toolbar width to figure width.
      tw, th = self.toolbar.GetSizeTuple()
      fw, fh = self.canvas.GetSizeTuple()
      # By adding toolbar in sizer, we are able to put it at the bottom
      # of the frame - so appearance is closer to GTK version.
      # As noted above, doesn't work for Mac.
      self.toolbar.SetSize(Size(fw, th))
      self.sizer.Add(self.toolbar, 0, LEFT | EXPAND)
    # update the axes menu on the toolbar
    self.toolbar.update()
    
  def plot_map(self):
    map = Basemap()
    map.drawcoastlines()
    map.drawcountries()
    map.drawmapboundary()
    map.fillcontinents(color='lime', lake_color='aqua')
    map.drawmapboundary(fill_color='aqua')
    matplotlib.pyplot.show()

class App(App):

  def OnInit(self):
    'Create the main window and insert the custom frame'
    frame = CanvasFrame()
    frame.Show(True)
    return True

app = App(0)
app.MainLoop()

--

Well, the above code works, but notice that after the Basemap plot is
displayed on a usual plotting window, *another*, blank, plotting
window appears! Can anyone figure out how to avoid that?

Another problem is that the instruction
"self.canvas.print_figure('test.png',dpi=100)", if used in place of
matplotlib.pyplot.show() method, has not effect and no figure is
written to disk.

Also, a call to method "self.canvas.draw()" has not effect, either.

Any hints?

Thanks in advance for any assistance you can provide.

With best regards,

--
Dr. Mauro J. Cavalcanti
Ecoinformatics Studio
P.O. Box 46521, CEP 20551-970
Rio de Janeiro, RJ, BRASIL
E-mail: maurobio@...287...
Web: http://studio.infobio.net
Linux Registered User #473524 * Ubuntu User #22717
"Life is complex. It consists of real and imaginary parts."

You are almost there. You need to create your own axes instance

    self.ax = self.figure.add_subplot(111)

and then pass this to your basemap

    map = Basemap(ax=self.ax)

after you have issued all your basemap commands, manually force a draw

  self.figure.canvas.draw()

and *do not* import pyplot or call pyplot.show()

JDH

···

On Wed, Nov 19, 2008 at 2:31 PM, Mauro Cavalcanti <maurobio@...287...> wrote:

Greetings. Trying to develop a desktop application for interactive
mapping using wxPython and Matplotlib, I have been doing some
experiments with embedding maps generated by the Basemap module into a
wxPython frame.