Scaling embedded matplotlib widget in qt application written in python problem
Question: I am writing a simple digital image processing program. To do this I have
embedded a mpl widget in my qt application. The user can perform some simple
analysis on the image such as box car filter, FFT etc. Every thing is working
fine until I would like to switch from displaying an image to displaying a
plot.

If I display a plot first, the axis are fine (see bottom plot in image). But
if I display an image first, followed by a plot (top plot in image), the scale
compresses.

<https://picasaweb.google.com/105163945296073520628/Temp> <\-- sorry I can't
post images yet

The code is hosted here <https://code.launchpad.net/~marrabld/pymi/trunk>

I am using imshow() to display the image. and plot(x,y) for the plots.

This is the main update method

    
    
    def updateImage(self):
        self.ui.mplWidget.canvas.PlotTitle = self.plotTitle
        self.ui.mplWidget.canvas.xtitle = self.xTitle
        self.ui.mplWidget.canvas.ytitle = self.yTitle
        #self.ui.mplWidget.canvas.ax.visible(False)
    
        self.ui.mplWidget.canvas.format_labels()
        if self.projectProperty == globals.IMAGE:
            if self.lastProjectProperty == globals.PLOT:
                self.myImage = imageFuncs.basic(self.imageFileName)
    
            self.imPlot = self.ui.mplWidget.canvas.ax.imshow(self.myImage.image,cmap=matplotlib.cm.gray,origin='upper')
    
        elif self.projectProperty == globals.PLOT:
    
            if self.lastProjectProperty == globals.IMAGE: # we need to reload the GUI
    
                self.ui.mplWidget.canvas.ax.hold(False) 
    
            self.ui.mplWidget.canvas.ax.plot(self.xData,self.yData)
    
        self.ui.mplWidget.canvas.draw()
    

And the mpl widget I am using

    
    
    #!/usr/bin/env python
    from PyQt4.QtCore import *
    from PyQt4.QtGui import *
    
    from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
    #from matplotlib.backends.backend_qt4 import NavigationToolbar2QT as NavigationToolbar
    from matplotlib.backend_bases import NavigationToolbar2
    
    from matplotlib.figure import Figure
    from matplotlib import rc
    
    import numpy as N
    
    class MyMplCanvas(FigureCanvas):
        def __init__(self, parent=None, width = 10, height = 12, dpi = 125, sharex = None, sharey = None):
    
                rc('text', usetex=True)
                rc('font', family='sans-serif')
                rc('legend',fontsize='small' )
                rc('legend',shadow='true')
    
                self.fig = Figure(figsize = (width, height), dpi=dpi, facecolor = '#FFFFFF')
    
                self.ax = self.fig.add_subplot(111, sharex = sharex, sharey = sharey)
                self.fig.subplots_adjust(left=0.15, bottom=0.15, right=0.9, top=0.9)
                self.fig.add_axes(yscale='symlog')
                self.xtitle=r"x-Axis"
                self.ytitle=r"y-Axis"
                self.PlotTitle = r"Title"
                self.grid_status = True
                self.xaxis_style = 'linear'
                self.yaxis_style = 'linear'
                #self.fig.yscale = 'log'
                self.format_labels()
                self.ax.hold(True)
                FigureCanvas.__init__(self, self.fig)
                #self.fc = FigureCanvas(self.fig)
                #FigureCanvas.setSizePolicy(self,
                 #       QSizePolicy.Expanding,
                  #      QSizePolicy.Expanding)
                FigureCanvas.updateGeometry(self)
    
        def format_labels(self):
                self.ax.set_title(self.PlotTitle)
                self.ax.title.set_fontsize(5)
                self.ax.set_xlabel(self.xtitle, fontsize = 4)
                self.ax.set_ylabel(self.ytitle, fontsize = 4)
                labels_x = self.ax.get_xticklabels()
                labels_y = self.ax.get_yticklabels()
    
                for xlabel in labels_x:
                        xlabel.set_fontsize(4)
                for ylabel in labels_y:
                        ylabel.set_fontsize(4)
                        ylabel.set_color('b')
    
        def sizeHint(self):
                w, h = self.get_width_height()
                return QSize(w, h)
    
        def minimumSizeHint(self):
                return QSize(10, 10)
    
        def sizeHint(self):
                w, h = self.get_width_height()
                return QSize(w, h)
    
        def minimumSizeHint(self):
                return QSize(10, 10)
    
    
    
    
        #mouseClick = pyqtProperty("QPoint",mouseClick,click)
    
    
    
    
    
    
    class mplWidget(QWidget):
        def __init__(self, parent = None):
                QWidget.__init__(self, parent)
                self.canvas = MyMplCanvas()
                #self.toolbar = MyNavigationToolbar(self.canvas, self.canvas, direction = 'v')
                self.hbox = QHBoxLayout()
                #self.hbox.addWidget(self.toolbar)
                self.hbox.addWidget(self.canvas)
                self.setLayout(self.hbox)
    
        def savePlot(self,filePath):
                self.canvas.fig.savefig(filePath)
    
        def setLegend(self,handle, label):
                self.canvas.fig.legend(handle,label,'upper right')
    
        def clearPlot(self):
                self.canvas.fig.clear()
    
                width = 10
                height = 12
                dpi = 125
                sharex = None
                sharey = None
    
                self.canvas.fig = Figure(figsize = (width, height), dpi=dpi, facecolor = '#FFFFFF')
    
                self.canvas.ax = self.canvas.fig.add_subplot(111, sharex = sharex, sharey = sharey)
                self.canvas.fig.subplots_adjust(left=0.15, bottom=0.15, right=0.9, top=0.9)
                self.canvas.fig.add_axes(yscale='symlog')
                self.canvas.xtitle=r"x-Axis"
                self.canvas.ytitle=r"y-Axis"
                self.canvas.PlotTitle = r"Title"
                self.canvas.grid_status = True
                self.canvas.xaxis_style = 'linear'
                self.canvas.yaxis_style = 'linear'
                #self.fig.yscale = 'log'
                self.canvas.format_labels()
                self.canvas.ax.hold(True)
    
                FigureCanvas.__init__(self.canvas, self.canvas.fig)
                #self.fc = FigureCanvas(self.fig)
                FigureCanvas.setSizePolicy(self,
                        QSizePolicy.Expanding,
                        QSizePolicy.Expanding)
                FigureCanvas.updateGeometry(self)
    

Any Help would be greatly appreciated.


Answer: you can use aspect parameter of imshow() to adjust the ratio between the
height & weight:

    
    
    from pylab import *
    a = np.zeros((100,10)) # height=100, weight=10
    subplot(211)
    imshow(a)  # ratio = 10
    subplot(212)
    imshow(a, aspect=0.1) # ratio = 1
    show()
    

but it will stretch the image.

or you can use xlim(), ylim() the set the range of x-y axis.

    
    
    imshow(a)
    xlim(-50,50)
    

EDIT:

imshow() will set the aspect property of axe to "equal". you need reset it
before calling plot():

    
    
    self.ui.mplWidget.canvas.ax.set_aspect("auto")
    self.ui.mplWidget.canvas.ax.plot(self.xData,self.yData)
    

