0

我在嵌入式 pyside 窗口中有一张来自 mpl_toolkits.basemap 的地图。当我调整窗口大小或使用 NavigationToolbar 中的缩放/平移按钮时,背景未正确更新。

这可能是什么原因?

当前代码是:

class geoDialog(QtGui.QDialog, Ui_mplDialog):
    def __init__(self, parent=None):
        super(geoDialog, self).__init__(parent)
        # Basic preparation for an embedded matplotlib
        self.setupUi(self)
        #self.fig = Figure(figsize=(600,600), dpi=72, facecolor=(1,1,1), edgecolor=(1,1,1))
        #self.fig = Figure(figsize=(5,8), dpi=72)
        self.fig = Figure()
        #self.setFixedSize(600, 600)
        #fig.set_picker(picker)
        self.canvas = FigureCanvas(self.fig)
        #self.verticalLayoutExtra = QtGui.QVBoxLayout()
        self.verticalLayout.addWidget(self.canvas)  
        #self.verticalLayoutExtra.addWidget(self.canvas)

        #self.ax = self.fig.add_axes([0.125,0.175,0.75,0.75]) #, axisbg='0.3')
        self.ax = self.fig.add_axes([0,0,1,1])
        self.ax.set_title('Geographical data')

        self.fig.set_frameon(False)
        #fig.set_alpha(self, alpha)

        #self.canvas.setSizePolicy(QtGui.QSizePolicy.Expanding,
        #                          QtGui.QSizePolicy.Expanding)
        #self.canvas.updateGeometry()

        #from matplotlib.pyplot import Scatter

        self.navigation_toolbar = NavigationToolbar(self.canvas, self)
        self.verticalLayout.addWidget(self.navigation_toolbar, 0)

        from mpl_toolkits.basemap import Basemap
        from geopy import geocoders

        #Draw cities
        gn = geocoders.Google()
        lats = []
        lons = []
        cities = []
        allEntities = session.query(Entity).all()
        #cities = ['Goirle, 5051','Neder Horst, 1394' , 'New Castle, NE1']
        for e in allEntities:
            if e.entityCity is not None:
                cities.append(str(e.country + ", " + e.entityCity + ", " + e.entityZipCode))

        for city in cities:
            print city
            place, (lat, lng) = gn.geocode(city)
            lats.append(lat)
            lons.append(lng)

        if len(cities) > 0:      
            llcrnrlatMin = min(lats) - 5
            urcrnrlatMax = max(lats) + 5
            llcrnrlonMin = min(lons) - 5
            urcrnrlonMax = max(lons) + 5

            ratio = (urcrnrlonMax - llcrnrlonMin) / (urcrnrlatMax - llcrnrlatMin) 
            print ratio, urcrnrlonMax, llcrnrlonMin, urcrnrlatMax, llcrnrlatMin
            if ratio > 1:
                urcrnrlatMax = urcrnrlatMax * (1 + (ratio - 1)/2)
                if urcrnrlatMax > 70: urcrnrlatMax = 70
                if urcrnrlatMax < -70: urcrnrlatMax = -70
                llcrnrlatMin = llcrnrlatMin * (1 - (ratio - 1)/2)
                if llcrnrlatMin > 70: llcrnrlatMin = 70
                if llcrnrlatMin < -70: llcrnrlatMin = -70
            else:
                urcrnrlonMax = urcrnrlonMax * (1 + (ratio - 1)/2)
                if urcrnrlonMax > 180: urcrnrlonMax = 179
                if urcrnrlonMax < -180: urcrnrlonMax = -179
                llcrnrlonMin = llcrnrlonMin * (1 - (ratio - 1)/2)
                if llcrnrlonMin > 180: llcrnrlonMin = 179
                if llcrnrlonMin < -180: llcrnrlonMin = -179
        else:
            llcrnrlatMin = 30
            urcrnrlatMax = 65
            llcrnrlonMin = -20
            urcrnrlonMax = 40     

        print urcrnrlonMax, llcrnrlonMin, urcrnrlatMax, llcrnrlatMin
        self.m = Basemap(projection='merc', llcrnrlat=llcrnrlatMin, urcrnrlat=urcrnrlatMax, \
                    llcrnrlon=llcrnrlonMin, urcrnrlon=urcrnrlonMax, resolution='i', ax=self.ax)        

        self.m.drawcoastlines()
        self.m.drawcountries()
        self.m.drawstates()
        self.m.fillcontinents(color='coral', lake_color='aqua')

        if len(cities) > 0:
            x,y = self.m(lons, lats)
            print x, y

            self.m.plot(x, y, 'bo', picker = True)
            # plot the names of those five cities.
            for name, xpt, ypt in zip(cities,x,y):
                self.ax.text(xpt+5000,ypt+5000,name)              

        self.m.drawmapboundary(fill_color='aqua') 
        self.updatesEnabled()

    def resizeEvent(self, event):
        print "resize"     
        #self.update()
        #self.canvas.update()
        frame.environmentGeneral_tab.setBackgroundRole(QPalette.Window)
        self.setBackgroundRole(QPalette.Window)
        self.update()
4

1 回答 1

0

试试下面的例子。我认为它可以满足您的需求。

from PyQt4.QtCore import *
from PyQt4.QtGui import *

import sys

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar
from matplotlib.figure import Figure

import numpy as np
from mpl_toolkits.basemap import Basemap
from datetime import datetime


class WorldMap( QDialog):
    def __init__( self, parent = None, flags=Qt.Window):        
        super( WorldMap, self ).__init__( parent, flags)

        self.resize(800, 600)
        self.gridLayout = QGridLayout(self)

        self.gridLayout.setObjectName("gridLayout")
        self.widgetPlot = QWidget()
        self.widgetPlot.setObjectName("widgetPlot")        
        self.figure = Figure()        
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas( self.figure )
        layout = QVBoxLayout()
        self.widgetPlot.setLayout(layout)
        layout.addWidget(self.canvas)        
        self.gridLayout.addWidget(self.widgetPlot, 0, 0, 1, 1)
        self.mpl_toolbar = NavigationToolbar(self.canvas, self, coordinates = False)
        self.gridLayout.addWidget(self.mpl_toolbar, 1, 0, 1, 1)        

        map = Basemap(projection='mill',lon_0=0, ax= self.axes)
        map.drawcoastlines()
        map.drawparallels(np.arange(-90,90,30),labels=[1,0,0,0])
        map.drawmeridians(np.arange(map.lonmin,map.lonmax+30,60),labels=[0,0,0,1])
        map.drawmapboundary(fill_color='aqua')
        map.fillcontinents(color='coral',lake_color='aqua')
        date = datetime.utcnow()
        CS=map.nightshade(date)
        self.canvas.draw()

def main():
    app = QApplication(sys.argv)    
    dialog = WorldMap(None)    
    sys.exit( dialog.exec_() )

if __name__ == "__main__":    
    main()
于 2013-01-17T19:18:35.407 回答