Search code examples
python-2.7matplotlibmatplotlib-widget

How do I refresh MatPlotlib embedded in PYQT4?


I'm trying to make the PYQT embedded Matplotlib plot redraw when new data is selected. It draws the first plots perfectly. I've tried variations of many things that I've seen online to no avail. Any help is much appreciated.

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

Solution

  • You should use the object-oriented API instead of pyplot when embedding matplotlib. For an example of embedding in PyQt4 see here

    To redraw the plot, call the draw() method of your FigureCanvas object.

    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