basemap OO usage within Qt

Hello,

I'm trying to follow the basemap examples in using basemap as a
matplotlib widget within a Qt-based application. Taking the example
code
    simpletest_oo.py
and modifying it to target QtAgg instead, I only get the lat/long lines,
as in the attached .png. The original example does draw all of the
continent lines and country boundaries correctly on my system.

I'm using matplotlib and basemap svn of 25 Apr 2006; the same results
were produced with 0.87.2 / 0.8.2 .

If anyone can see something obvious that I'm leaving out, I would really
appreciate a hint as to why the continents, countries, etc. are not
getting drawn.

Thank you!
Glen Mabey

######## justaplot_designer.py

from qt import *
from mplwidget import *

class Form1(QDialog):
    def __init__(self,parent = None,name = None,modal = 0,fl = 0):
        QDialog.__init__(self,parent,name,modal,fl)

        Form1Layout = QVBoxLayout(self,11,6,"Form1Layout")

        self.matplotlibWidget = MatplotlibWidget(self,"matplotlibWidget")
        Form1Layout.addWidget(self.matplotlibWidget)

        self.resize(QSize(322,222).expandedTo(self.minimumSizeHint()))
        self.clearWState(Qt.WState_Polished)

######## basemap_simpletest_oo_qt.py

basemap_qt.png

···

#####################################
# pylab-free version of simpletest.py
#####################################

# set backend to QtAgg.
import matplotlib
matplotlib.use('QtAgg')
from matplotlib.backends.backend_qt import FigureCanvasQT as FigureCanvas

from matplotlib.toolkits.basemap import Basemap
from matplotlib.figure import Figure
from matplotlib.mlab import meshgrid
import matplotlib.numerix as nx
import matplotlib.cm as cm

from matplotlib.mlab import load

import justaplot_designer

class PlotWin( justaplot_designer.Form1 ):
    def __init__(self,parent = None,name = None,modal = 0,fl = 0):
        justaplot_designer.Form1.__init__( self, parent, name, modal, fl )

# read in topo data (on a regular lat/lon grid)
# longitudes go from 20 to 380.
etopo = nx.array(load('etopo20data.gz'),'d')
lons = nx.array(load('etopo20lons.gz'),'d')
lats = nx.array(load('etopo20lats.gz'),'d')
# create figure.
plot_window = PlotWin()
# create axes instance, leaving room for colorbar at bottom.
ax = plot_window.matplotlibWidget.axes
# create Basemap instance for Robinson projection.
# set 'ax' keyword so pylab won't be imported.
m = Basemap(projection='robin',lon_0=0.5*(lons[0]+lons[-1]),ax=ax)
# reset figure size to have same aspect ratio as map.
# fig will be 8 inches wide.
# (don't use createfigure, since that imports pylab).
#fig.set_figsize_inches((8,m.aspect*8.))
# make filled contour plot.
x, y = m(*meshgrid(lons, lats))
cs = m.contourf(x,y,etopo,30,cmap=cm.jet)
# draw coastlines.
m.drawcoastlines()
# draw a line around the map region.
m.drawmapboundary()
# draw parallels and meridians.
m.drawparallels(nx.arange(-60.,90.,30.),labels=[1,0,0,0],fontsize=10)
m.drawmeridians(nx.arange(0.,420.,60.),labels=[0,0,0,1],fontsize=10)
# add a title.
ax.set_title('Robinson Projection')
# add a colorbar.
#cax = fig.add_axes([0.125, 0.05, 0.75, 0.05],frameon=False)
#fig.colorbar(cs, cax=cax, tickfmt='%d', orientation='horizontal',clabels=cs.levels[::3])
# save image (width 800 pixels with dpi=100 and fig width 8 inches).
plot_window.matplotlibWidget.draw()
plot_window.show()
plot_window.exec_loop()

Glen W. Mabey wrote:

Hello,

I'm trying to follow the basemap examples in using basemap as a
matplotlib widget within a Qt-based application. Taking the example
code
    simpletest_oo.py
and modifying it to target QtAgg instead, I only get the lat/long lines,
as in the attached .png. The original example does draw all of the
continent lines and country boundaries correctly on my system.

I'm using matplotlib and basemap svn of 25 Apr 2006; the same results
were produced with 0.87.2 / 0.8.2 .

If anyone can see something obvious that I'm leaving out, I would really
appreciate a hint as to why the continents, countries, etc. are not
getting drawn.

Thank you!
Glen Mabey

Glen: I can't run your example, since I don't have all the dependencies (such as mplwidget and justaplot_designer). However, I can run the simpletest.py example using QtAgg and the continents display as expected, so I don't think it is a Qt issue. But, you probably already knew that - sorry I can't be of more help.

-Jeff

···

--
Jeffrey S. Whitaker Phone : (303)497-6313
Meteorologist FAX : (303)497-6449
NOAA/OAR/PSD R/PSD1 Email : Jeffrey.S.Whitaker@...259...
325 Broadway Office : Skaggs Research Cntr 1D-124
Boulder, CO, USA 80303-3328 Web : http://tinyurl.com/5telg

Oh, whoops. I thought I had everything in there. Here it is, in a
single file:

···

On Wed, Apr 26, 2006 at 01:43:30PM -0600, Jeff Whitaker wrote:

Glen W. Mabey wrote:
>Hello,
>
>I'm trying to follow the basemap examples in using basemap as a
>matplotlib widget within a Qt-based application. Taking the example
>code
> simpletest_oo.py
>and modifying it to target QtAgg instead, I only get the lat/long lines,
>as in the attached .png. The original example does draw all of the
>continent lines and country boundaries correctly on my system.
>
>I'm using matplotlib and basemap svn of 25 Apr 2006; the same results
>were produced with 0.87.2 / 0.8.2 .
>
>If anyone can see something obvious that I'm leaving out, I would really
>appreciate a hint as to why the continents, countries, etc. are not
>getting drawn.
>
>Thank you!
>Glen Mabey
>
>

Glen: I can't run your example, since I don't have all the dependencies
(such as mplwidget and justaplot_designer).

#################
import matplotlib
matplotlib.use('QtAgg')

from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg as FigureCanvas

class MatplotlibWidget( FigureCanvas ):
    """Ultimately, this is a QWidget (as well as a FigureCanvasAgg, etc.)."""
    def __init__( self, parent=None, name=None ):
        self.init_parent = parent
        self.init_name = name

        if self.init_parent:
            # slightly more robust behavior here would be to check to make sure parent is a QWidget ...
            bgc = self.init_parent.backgroundBrush().color()
            bgcolor = float(bgc.red())/255.0, float(bgc.green())/255.0, float(bgc.blue())/255.0
            #bgcolor = "#%02X%02X%02X" % (bgc.red(), bgc.green(), bgc.blue()) Equivalent to above line

        self.fig = Figure( dpi=100, facecolor=bgcolor, edgecolor=bgcolor )
        self.axes = self.fig.add_subplot(111)

        # We want the axes cleared every time plot() is called
        self.axes.hold(False)

        # Apparently the FigureCanvas class has neither a name nor a label attribute.
        FigureCanvas.__init__(self, self.fig)
        self.reparent( self.init_parent, qt.QPoint(0, 0))
        self.axes.set_label( self.init_name )

        self.setMinimumSize( 100, 100 )
        self.setSizePolicy( qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding )
        self.updateGeometry()

import qt

class PlotWin( qt.QDialog ):
    def __init__( self, parent=None, name=None, modal=0, fl=0 ):
        qt.QDialog.__init__(self,parent,name,modal,fl)

        Form1Layout = qt.QVBoxLayout(self,11,6,"Form1Layout")

        self.matplotlibWidget = MatplotlibWidget(self,"matplotlibWidget")
        Form1Layout.addWidget(self.matplotlibWidget)

        self.resize(qt.QSize(322,222).expandedTo(self.minimumSizeHint()))
        self.clearWState(qt.Qt.WState_Polished)

from matplotlib.toolkits.basemap import Basemap
from matplotlib.figure import Figure
from matplotlib.mlab import meshgrid
import matplotlib.numerix as nx
import matplotlib.cm as cm

from matplotlib.mlab import load

# read in topo data (on a regular lat/lon grid)
# longitudes go from 20 to 380.
etopo = nx.array(load('etopo20data.gz'),'d')
lons = nx.array(load('etopo20lons.gz'),'d')
lats = nx.array(load('etopo20lats.gz'),'d')
# create figure.
plot_window = PlotWin()
# create axes instance, leaving room for colorbar at bottom.
ax = plot_window.matplotlibWidget.axes
# create Basemap instance for Robinson projection.
# set 'ax' keyword so pylab won't be imported.
m = Basemap(projection='robin',lon_0=0.5*(lons[0]+lons[-1]),ax=ax)
# reset figure size to have same aspect ratio as map.
# fig will be 8 inches wide.
# (don't use createfigure, since that imports pylab).
#fig.set_figsize_inches((8,m.aspect*8.))
# make filled contour plot.
x, y = m(*meshgrid(lons, lats))
cs = m.contourf(x,y,etopo,30,cmap=cm.jet)
# draw coastlines.
m.drawcoastlines()
# draw a line around the map region.
m.drawmapboundary()
# draw parallels and meridians.
m.drawparallels(nx.arange(-60.,90.,30.),labels=[1,0,0,0],fontsize=10)
m.drawmeridians(nx.arange(0.,420.,60.),labels=[0,0,0,1],fontsize=10)
# add a title.
ax.set_title('Robinson Projection')
# add a colorbar.
#cax = fig.add_axes([0.125, 0.05, 0.75, 0.05],frameon=False)
#fig.colorbar(cs, cax=cax, tickfmt='%d', orientation='horizontal',clabels=cs.levels[::3])
# save image (width 800 pixels with dpi=100 and fig width 8 inches).
plot_window.matplotlibWidget.draw()
plot_window.show()
plot_window.exec_loop()

#####################

If I was more familiar with some of the other GUI backends, I would try
a similar setup with them.

I think I'm following fairly closely the suggestions posted to this
mailing list regarding the use of OO matplotlib with basemap: passing
the 'ax' to Basemap().

Yet, it seems that the call to drawmapboundary() resets the entire axis.
If it is commented out, then everything else works. With it, only the
boundary, parallels, and meridians are shown.

I'm continuing to look into this ... Thanks for your reply.

Glen

Glen W. Mabey wrote:

  

Glen W. Mabey wrote:
    

Hello,

I'm trying to follow the basemap examples in using basemap as a
matplotlib widget within a Qt-based application. Taking the example
code
   simpletest_oo.py
and modifying it to target QtAgg instead, I only get the lat/long lines,
as in the attached .png. The original example does draw all of the
continent lines and country boundaries correctly on my system.

I'm using matplotlib and basemap svn of 25 Apr 2006; the same results
were produced with 0.87.2 / 0.8.2 .

If anyone can see something obvious that I'm leaving out, I would really
appreciate a hint as to why the continents, countries, etc. are not
getting drawn.

Thank you!
Glen Mabey

Glen: I can't run your example, since I don't have all the dependencies (such as mplwidget and justaplot_designer).
    
Oh, whoops. I thought I had everything in there. Here it is, in a
single file:

....(snipped)....

I think I'm following fairly closely the suggestions posted to this
mailing list regarding the use of OO matplotlib with basemap: passing
the 'ax' to Basemap().

Yet, it seems that the call to drawmapboundary() resets the entire axis.
If it is commented out, then everything else works. With it, only the
boundary, parallels, and meridians are shown.

I'm continuing to look into this ... Thanks for your reply.

Glen
  
Glen: That works for me - a small window pops up and I see the continents and the topo field. I'm using the latest svn matplotlib and basemap.

-Jeff

···

On Wed, Apr 26, 2006 at 01:43:30PM -0600, Jeff Whitaker wrote:

--
Jeffrey S. Whitaker Phone : (303)497-6313
Meteorologist FAX : (303)497-6449
NOAA/OAR/PSD R/PSD1 Email : Jeffrey.S.Whitaker@...259...
325 Broadway Office : Skaggs Research Cntr 1D-124
Boulder, CO, USA 80303-3328 Web : http://tinyurl.com/5telg

Jeff:

Could you tell me what versions of Qt and Python you're using? I'm on
Python 2.4.3 with Qt 3.3.3, on AMD x86-64.

I'll give it a try on Qt 3.3.6 here shortly ...

Glen

···

On Wed, Apr 26, 2006 at 02:32:39PM -0600, Jeff Whitaker wrote:

Glen: That works for me - a small window pops up and I see the
continents and the topo field. I'm using the latest svn matplotlib and
basemap.

Glen W. Mabey wrote:

···

On Wed, Apr 26, 2006 at 02:32:39PM -0600, Jeff Whitaker wrote:
  

Glen: That works for me - a small window pops up and I see the continents and the topo field. I'm using the latest svn matplotlib and basemap.
    
Jeff:

Could you tell me what versions of Qt and Python you're using? I'm on
Python 2.4.3 with Qt 3.3.3, on AMD x86-64.

I'll give it a try on Qt 3.3.6 here shortly ...

Glen
  
Glen: Python 2.4.3, qt 3.3.5, pyqt 3.15 on macos x ppc (using x11, not aqua).

-Jeff

--
Jeffrey S. Whitaker Phone : (303)497-6313
Meteorologist FAX : (303)497-6449
NOAA/OAR/PSD R/PSD1 Email : Jeffrey.S.Whitaker@...259...
325 Broadway Office : Skaggs Research Cntr 1D-124
Boulder, CO, USA 80303-3328 Web : http://tinyurl.com/5telg