如何刷新使用Python(x,y)QT Designer Matplotlib小部件创建的子图?

时间:2016-08-19 17:05:45

标签: python python-2.7 matplotlib matplotlib-widget

我在Python(x,y)包中使用QT附带的MPL小部件。我试图用新数据刷新或重绘我的情节。方法fig.canvas.draw()仅刷新主图。子图是我的问题所在。之前的子图和与它们相关的所有内容(轴刻度,注释等)都保留在图表上。当我刷新时,新的子图数据被绘制在旧数据上,造成了相当大的混乱。与主图相关联的所有内容都会正确重绘。我尝试了所有我想要尝试的东西,包括clf和cla。如何使用Python(x,y)中包含的QT MPL Widget刷新子图?

这是我的代码:

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    

    if replot == 1:

        #self.mplwidget_2.figure.clear()          

        print replot

    par1 = fig.add_subplot(111)
    par2 = fig.add_subplot(111)      


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



    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]
    #bep = fac_ranges[2]
    #Plot Chart
    plt.hold(False)    #Has to be included for  multiple curves
    #Plot Factory Pressure
    plt.plot(fac_flow, fac_lift, 'b', linestyle = "dashed", linewidth = 1)



    #Plot Factory Power
    ax1.plot(fac_flow, fac_power, 'r', linestyle = "dashed", linewidth = 1)       
    ax2.plot(fac_flow, fac_eff, 'g', linestyle = "dashed", linewidth = 1)


    #Move spines
    ax2.spines["right"].set_position(("outward", 25))
    self.make_patch_spines_invisible(ax2)
    ax2.spines["right"].set_visible(True)  
    #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 MARKER   *** Can change marker style if needed
    bep = fac_max_eff * 0.90     #bep is 90% of maximum efficiency point

    bep_corrected = bep * 0.90   # We knock off another 10% to place the arrow correctly on chart

    ax2.annotate('BEP', xy=(fac_max_eff_bpd, bep_corrected), xycoords='data',   #Subtract 2.5 shows up correctly on chart
            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')

    #To redraw plot


    fig.canvas.draw()

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    

    if replot == 1:

        #self.mplwidget_2.figure.clear()          

        print replot

    par1 = fig.add_subplot(111)
    par2 = fig.add_subplot(111)      


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



    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]
    #bep = fac_ranges[2]
    #Plot Chart
    plt.hold(False)    #Has to be included for  multiple curves
    #Plot Factory Pressure
    plt.plot(fac_flow, fac_lift, 'b', linestyle = "dashed", linewidth = 1)



    #Plot Factory Power
    ax1.plot(fac_flow, fac_power, 'r', linestyle = "dashed", linewidth = 1)       
    ax2.plot(fac_flow, fac_eff, 'g', linestyle = "dashed", linewidth = 1)


    #Move spines
    ax2.spines["right"].set_position(("outward", 25))
    self.make_patch_spines_invisible(ax2)
    ax2.spines["right"].set_visible(True)  
    #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 MARKER   *** Can change marker style if needed
    bep = fac_max_eff * 0.90     #bep is 90% of maximum efficiency point

    bep_corrected = bep * 0.90   # We knock off another 10% to place the arrow correctly on chart

    ax2.annotate('BEP', xy=(fac_max_eff_bpd, bep_corrected), xycoords='data',   #Subtract 2.5 shows up correctly on chart
            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')

    #To redraw plot


    fig.canvas.draw()

1 个答案:

答案 0 :(得分:1)

从示例中不清楚如何创建self.mpl_widget.axes。它没有被使用,如下所述,绘制到轴实例的旧引用可能会导致问题。

因为根本没有使用mpl_widget.axes,我建议不要在轴上保留参考。然后在示例中使用twinx是不正确的。以下可能有效:

if plot_page == 1:             #Plot 1st Page
    widget = self.mplwidget
if plot_page == 2:          #Plot 2nd Page
    widget = self.mplwidget_3
if plot_page == 3:           #Plot 3rd Page
    widget = self.mplwidget_3
if replot == 1:
    widget.figure.clear()
ax1 = widget.figure.add_subplot(111)
ax2 = ax1.twinx()

...

widget.figure.canvas.draw()

另一个问题是self.mpl_widgetXX.axes已分配给plt,下面示例plt中的self.mpl_widgetXX.axes用于绘制新数据。由于ax1未更新为包含新创建的轴实例之一,因此示例代码将绘制到旧轴,从而可能导致问题中描述的效果。 您只应使用ax2widget.figure进行绘图和勾选设置,并使用public static void main(String[] args) { int[] array = {1, 2, 2, 3, 3, 4, 5, 5, 3, 4, 3, 4, 6, 6, 1, 3, 3, 3}; Arrays.sort(array); List<Integer> list = new ArrayList<>(); for (int x : array) { list.add(x); } for (int i = 0; i < list.size(); i++) { System.out.print(list.get(i) + " "); } System.out.println(); System.out.println("\nDuplicate element(s)"); Integer last = null; Iterator<Integer> it = list.iterator(); while (it.hasNext()){ Integer n = it.next(); if (n.equals(last)){ System.out.print(n + " "); it.remove(); } last = n; } System.out.println(); System.out.println("\nDuplicate element(s) removed"); for (int i = 0; i < list.size(); i++) { System.out.print(list.get(i) + " "); } System.out.println(); } 来访问数字实例。