Skip to main content
 首页 » 编程设计

python之在用 python 问题编写的 qt 应用程序中缩放嵌入式 matplotlib 小部件

2025年05月04日13lautakyan007

我正在编写一个简单的数字图像处理程序。为此,我在我的 qt 应用程序中嵌入了一个 mpl 小部件。用户可以对图像执行一些简单的分析,例如 box car filter、FFT 等。在我想从显示图像切换到显示绘图之前,一切都运行良好。

如果我先显示一个图,则轴很好(请参见图像中的底部图)。但是,如果我先显示图像,然后显示绘图(图像中的顶部绘图),则比例会压缩。

https://picasaweb.google.com/105163945296073520628/Temp <-- 抱歉我还不能发布图片

代码托管在这里 https://code.launchpad.net/~marrabld/pymi/trunk

我正在使用 imshow() 来显示图像。和 plot(x,y) 用于绘图。

这是主要的更新方法

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() 

还有我正在使用的mpl小部件

#!/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) 

任何帮助将不胜感激。

请您参考如下方法:

您可以使用 imshow() 的 aspect 参数来调整高度和重量之间的比例:

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() 

但它会拉伸(stretch)图像。

或者你可以使用 xlim(), ylim() 来设置 x-y 轴的范围。

imshow(a) 
xlim(-50,50) 

编辑:

imshow() 会将 ax 的 aspect 属性设置为“equal”。你需要在调用 plot() 之前重置它:

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