如何刷新嵌入在 PYQT4 中的 MatPlotlib?

Posted

技术标签:

【中文标题】如何刷新嵌入在 PYQT4 中的 MatPlotlib?【英文标题】:How do I refresh MatPlotlib embedded in PYQT4? 【发布时间】:2016-12-25 14:20:18 【问题描述】:

我正在尝试在选择新数据时重绘 PYQT 嵌入式 Matplotlib 图。它完美地绘制了第一个图。我尝试了许多我在网上看到的东西的变体,但无济于事。任何帮助深表感谢。

def mpl_plot(self, plot_page, replot = 0):  #Data stored in lists  

    if plot_page == 1:             #Plot 1st Page                        
        plt = self.mplwidget.axes                                
        fig = self.mplwidget.figure #Add a figure            


    if plot_page == 2:          #Plot 2nd Page
        plt = self.mplwidget_2.axes 
        fig = self.mplwidget_2.figure    #Add a figure

    if plot_page == 3:           #Plot 3rd Page
        plt = self.mplwidget_3.axes 
        fig = self.mplwidget_3.figure    #Add a figure    

    par1 = fig.add_subplot(1,1,1)
    par2 = fig.add_subplot(1,1,1)      

    #Add Axes
    ax1 = par1.twinx()        
    ax2 = par2.twinx()  

    ax2.spines["right"].set_position(("outward", 25))
    self.make_patch_spines_invisible(ax2)
    ax2.spines["right"].set_visible(True)  
    impeller = str(self.comboBox_impellers.currentText())  #Get Impeller
    fac_curves = self.mpl_factory_specs(impeller)    
    fac_lift = fac_curves[0]        
    fac_power = fac_curves[1]
    fac_flow = fac_curves[2]
    fac_eff = fac_curves[3]        
    fac_max_eff = fac_curves[4]
    fac_max_eff_bpd = fac_curves[5]
    fac_ranges = self.mpl_factory_ranges()
    min_range = fac_ranges[0]
    max_range = fac_ranges[1]

    #Plot Chart
    plt.hold(True)    #Has to be included for  multiple curves

    plt.plot(fac_flow, fac_lift, 'b', linestyle = "dashed", linewidth = 1)

    #plt.plot(flow,f_lift,'b.')  #Plot datapoints only

    #Plot Factory Power
    ax1.plot(fac_flow, fac_power, 'r', linestyle = "dashed", linewidth = 1)
    #ax1.plot(flow,f_power,'r.')    #Plot datapoints only

    ax2.plot(fac_flow, fac_eff, 'g', linestyle = "dashed", linewidth = 1)

    #Plot x axis minor tick marks
    minorLocatorx = AutoMinorLocator()        
    ax1.xaxis.set_minor_locator(minorLocatorx)
    ax1.tick_params(which='both', width= 0.5)
    ax1.tick_params(which='major', length=7)
    ax1.tick_params(which='minor', length=4, color='k')

    #Plot y axis minor tick marks
    minorLocatory = AutoMinorLocator()
    plt.yaxis.set_minor_locator(minorLocatory)
    plt.tick_params(which='both', width= 0.5)
    plt.tick_params(which='major', length=7)
    plt.tick_params(which='minor', length=4, color='k')
    #Make Border of Chart White


    #Plot Grid        
    plt.grid(b=True, which='both', color='k', linestyle='-') 

    #set shaded Area 
    plt.axvspan(min_range, max_range, facecolor='#9BE2FA', alpha=0.5)    #Yellow rectangular shaded area

    #Set Vertical Lines
    plt.axvline(fac_max_eff_bpd, color = '#69767A')


    bep = fac_max_eff * 0.90    

    bep_corrected = bep * 0.90  

    ax2.annotate('BEP', xy=(fac_max_eff_bpd, bep_corrected), xycoords='data',  
            xytext=(-50, 30), textcoords='offset points',
            bbox=dict(boxstyle="round", fc="0.8"),
            arrowprops=dict(arrowstyle="-|>",
                            shrinkA=0, shrinkB=10,
                            connectionstyle="angle,angleA=0,angleB=90,rad=10"),
                    )
    #Set Scales         
    plt.set_ylim(0,max(fac_lift) + (max(fac_lift) * 0.40))    #Pressure 
    #plt.set_xlim(0,max(fac_flow))

    ax1.set_ylim(0,max(fac_power) + (max(fac_power) * 0.40))     #Power
    ax2.set_ylim(0,max(fac_eff) + (max(fac_eff) * 0.40))    #Effiency


    # Set Axes Colors
    plt.tick_params(axis='y', colors='b')
    ax1.tick_params(axis='y', colors='r')
    ax2.tick_params(axis='y', colors='g')

    # Set Chart Labels        
    plt.set_xlabel("BPD")
    plt.set_ylabel("Feet" , color = 'b')
    #ax1.set_ylabel("BHP", color = 'r')
    #ax1.set_ylabel("Effiency", color = 'g')

    # Set tight layout
    fig = self.mplwidget.figure.tight_layout()
    fig = self.mplwidget_2.figure.tight_layout()
    fig = self.mplwidget_3.figure.tight_layout()

【问题讨论】:

【参考方案1】:

在嵌入 matplotlib 时,您应该使用面向对象的 API 而不是 pyplot。有关嵌入 PyQt4 的示例,请参阅here

要重绘绘图,请调用您的 FigureCanvas 对象的 draw() 方法。

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

fig = Figure()
ax = fig.add_subplot(111)
canvas = FigureCanvas(fig)
canvas.show()

canvas.draw()  # Redraw figure

【讨论】:

这是我第一次使用 matplotlib。我正在使用 Python xy 包和 QT 设计器。 Python xy 有一个用于 QT 的内置 MPL 小部件,这是我正在使用的。在我重新绘制之前对我来说效果很好:有什么方法可以重新绘制当前设置(pyplot)? 我对python xy不是很熟悉,但是从外观上看你可以通过self.mplwidget.figure访问该图,所以你应该可以调用self.mplwidget.figure.canvas.draw() 我实际上发现,在我写了这篇文章之后,它正在为主要情节工作,但是子情节仍然没有清除并继续相互绘制。有人对处理子图有什么建议吗?

以上是关于如何刷新嵌入在 PYQT4 中的 MatPlotlib?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 PyQt4 小部件中嵌入的 Axes3D (matplotlib) 中启用旋转?

在 PyQt4 的嵌入式 matplotlib 图中使用 ginput

如何按需刷新嵌入式 Google 数据洞察报告?

每当单击刷新按钮时,如何更新 iOS 应用程序包中的嵌入式 JSON 文件

PyQt4 中的 QThreading PyQtGraph PlotWidgets

Pygame和PyQt4如何集成?