コード例 #1
0
class MatplotlibPlot:
    """ Class encapsulating a matplotlib plot"""

    def __init__(self, parent = None, dpi = 100, size = (5,5)):
        """ Class initialiser """

        self.dpi = dpi
        self.figure = Figure(size, dpi = self.dpi)
        self.canvas = FigureCanvas(self.figure)
        self.canvas.setParent(parent)

        # Create the navigation toolbar, tied to the canvas
        self.toolbar = NavigationToolbar(self.canvas, parent)
        self.canvas.show()
        self.toolbar.show()

        # Reset the plot landscape
        self.figure.clear()

    def plotMultiPixel(self, info, data):
        """ Generate multi-pixel plot """

        # Tabula Rasa
        self.figure.clear()
        rows = math.ceil(math.sqrt(info['nbeams']))

	    # Display a subplot per beam (randomly for now)
        for i in range(info['nbeams']):
            ax = self.figure.add_subplot(rows, rows, i)
            ax.plot(data[:,512,i])
            
        

    def updatePlot(self):
        self.canvas.draw()
コード例 #2
0
class MatplotlibPlot:
    """ Class encapsulating an matplotlib plot"""
    def __init__(self, parent=None, dpi=100, size=(5, 4)):
        """ Class initialiser """

        self.dpi = dpi
        self.figure = Figure(size, dpi=self.dpi)
        self.canvas = FigureCanvas(self.figure)
        self.canvas.setParent(parent)

        # Create the navigation toolbar, tied to the canvas
        self.toolbar = NavigationToolbar(self.canvas, parent)
        self.canvas.show()
        self.toolbar.show()

    def plotCurve(self,
                  data,
                  xAxisRange=None,
                  yAxisRange=None,
                  xLabel="",
                  yLabel=""):
        """ Plot the data as a curve"""

        # clear the axes and redraw the plot anew
        self.figure.clear()
        self.axes = self.figure.add_subplot(111)
        self.axes.grid(True)
        self.axes.plot(range(np.size(data)), data)

        if xAxisRange is not None:
            self.xAxisRange = xAxisRange
            self.axes.xaxis.set_major_formatter(
                ticker.FuncFormatter(
                    lambda x, pos=None: '%.2f' % self.xAxisRange[x]
                    if 0 <= x < len(xAxisRange) else ''))
            for tick in self.axes.xaxis.get_ticklabels():
                tick.set_rotation(15)

        if yAxisRange is not None:
            self.yAxisRange = yAxisRange
            self.axes.xaxis.set_major_formatter(
                ticker.FuncFormatter(
                    lambda x, pos=None: '%.1f' % self.yAxisRange[y]
                    if 0 <= y < len(yAxisRange) else ''))
            for tick in self.axes.yaxis.get_ticklabels():
                tick.set_rotation(15)

        self.axes.xaxis.set_label_text(xLabel)
        self.axes.yaxis.set_label_text(yLabel)
        self.canvas.draw()
コード例 #3
0
ファイル: processFolding.py プロジェクト: jintaoluo/MDSM
class MatplotlibPlot:
    """ Class encapsulating an matplotlib plot"""
    def __init__(self, parent = None, dpi = 100, size = (5,4)):
        """ Class initialiser """

        self.dpi = dpi
        self.figure = Figure(size, dpi = self.dpi)
        self.canvas = FigureCanvas(self.figure)
        self.canvas.setParent(parent)

        # Create the navigation toolbar, tied to the canvas
        self.toolbar = NavigationToolbar(self.canvas, parent)
        self.canvas.show()
        self.toolbar.show()

    def plotCurve(self, data, xAxisRange = None, yAxisRange = None, xLabel = "", yLabel = ""):
        """ Plot the data as a curve"""

        # clear the axes and redraw the plot anew
        self.figure.clear()
        self.axes = self.figure.add_subplot(111)        
        self.axes.grid(True)
        self.axes.plot(range(np.size(data)), data)

        if xAxisRange is not None:        
            self.xAxisRange = xAxisRange
            self.axes.xaxis.set_major_formatter(ticker.FuncFormatter(
                       lambda x, pos=None: '%.2f' % self.xAxisRange[x] if 0 <= x < len(xAxisRange) else ''))
            for tick in self.axes.xaxis.get_ticklabels():
                  tick.set_rotation(15)

        if yAxisRange is not None:        
            self.yAxisRange = yAxisRange
            self.axes.xaxis.set_major_formatter(ticker.FuncFormatter(
                       lambda x, pos=None: '%.1f' % self.yAxisRange[y] if 0 <= y < len(yAxisRange) else ''))
            for tick in self.axes.yaxis.get_ticklabels():
                  tick.set_rotation(15)

        self.axes.xaxis.set_label_text(xLabel)
        self.axes.yaxis.set_label_text(yLabel)
        self.canvas.draw()
コード例 #4
0
class MatplotlibPlot:
    """ Class encapsulating an matplotlib plot """
    def __init__(self, parent=None, dpi=100, size=(5, 4)):
        """ Class initialiser """

        self.dpi = dpi
        self.figure = Figure(dpi=self.dpi)
        self.canvas = FigureCanvas(self.figure)
        self.canvas.setParent(parent)

        # Create the navigation toolbar, tied to the canvas
        self.toolbar = NavigationToolbar(self.canvas, parent)
        self.canvas.show()
        self.toolbar.show()

    def plotCurve(self,
                  data,
                  numCurves=1,
                  labels=None,
                  xAxisRange=None,
                  yAxisRange=None,
                  xLabel="",
                  yLabel=""):
        """ Normal plots """

        self.figure.clear()
        self.axes = self.figure.add_subplot(111)
        self.axes.grid(True)

        # Set empty labels if non defined
        if labels is None:
            labels = ['' for i in range(numImages)]

        # Place all plots in axes
        for i in range(numCurves):
            self.axes.plot(data[:, i], label=labels[i])
            self.axes.set_xlim((0, len(data[:, i])))

        # Final touches
        self.axes.xaxis.set_label_text(xLabel)
        self.axes.yaxis.set_label_text(yLabel)
        self.canvas.draw()

    def subplotCurve(self,
                     data,
                     numPlots=1,
                     labels=None,
                     xAxisRange=None,
                     yAxisRange=None,
                     xLabel="",
                     yLabel=""):
        """ Subplot mode """

        self.figure.clear()

        # Set empty labels if non defined
        if labels is None:
            labels = ['' for i in range(numImages)]

        if numPlots == 1:
            ax = self.figure.add_subplot(111)
            ax.plot(data[:])
            ax.set_xlabel(xLabel)
            ax.set_ylabel(yLabel)
            ax.set_title(labels[0])
            ax.grid(True)
        else:
            # Plot each image
            num_rows = ceil(sqrt(numPlots))
            for i in range(numPlots):
                ax = self.figure.add_subplot(num_rows, num_rows, i + 1)
                ax.plot(data[:, i])
                ax.set_xlim((0, len(data[:, i])))
                ax.set_xlabel(xLabel)
                ax.set_ylabel(yLabel)
                ax.set_title(labels[i])
                ax.grid(True)

        # Final touches
        self.figure.tight_layout()
        self.canvas.draw()

    def plotImage(self,
                  data,
                  numImages=1,
                  labels=None,
                  xAxisRange=None,
                  yAxisRange=None,
                  xLabel="",
                  yLabel=""):
        """ Image plot """

        self.figure.clear()
        self.axes = self.figure.add_subplot(111)

        # Show image
        im = self.axes.imshow(data, origin='lower', aspect='auto')

        # Final touches
        self.axes.xaxis.set_label_text(xLabel)
        self.axes.yaxis.set_label_text(yLabel)
        self.figure.colorbar(im)
        self.canvas.draw()

    def subplotImage(self,
                     data,
                     numImages=1,
                     labels=None,
                     xAxisRange=None,
                     yAxisRange=None,
                     xLabel="",
                     yLabel=""):
        """ Image subplot """

        # Clear figure
        self.figure.clear()

        # Set empty labels if non defined
        if labels is None:
            labels = ['' for i in range(numImages)]

        # Plot each image
        num_rows = ceil(sqrt(numImages))
        for i in range(numImages):
            ax = self.figure.add_subplot(num_rows, num_rows, i + 1)
            im = ax.imshow(data[:, :, i], origin='lower', aspect='auto')
            ax.set_xlabel(xLabel)
            ax.set_ylabel(yLabel)
            ax.set_title(labels[i])

        # Final touches
        self.figure.tight_layout()
        self.canvas.draw()
コード例 #5
0
class plothistogram(QFrame):
   def __init__(self, parent):
      print "__init__()"       # DEBUG
      QFrame.__init__(self)
      
      self.parent=parent
      #self.setModal(False)

      self.data1=self.parent.y1   # get plotted y values from solutions plot
      self.data2=self.parent.y2   # get plotted y values from parameter plot
      self.nbins=50               # default=50 bins
      self.parameter=self.parent.parent.parametersComboBox.currentText()
      self.data=self.parent.y2    # set histogram to solver parameter data

      #print "self.data = ", self.data   # DEBUG

      # Create canvas for plotting
      self.rim=0.1
      self.fig = Figure((5, 4), dpi=100)
      self.canvas = FigureCanvas(self.fig)
      self.canvas.setParent(self)
      self.fig.subplots_adjust(left=self.rim, right=1.0-self.rim, top=1.0-self.rim, bottom=self.rim)  # set a small rim

      self.mpl_toolbar = NavigationToolbar(self.canvas, self)
      self.mpl_toolbar.show()   # first hide the toolbar
      
      self.ax=self.fig.add_subplot(111)
      
      self.createWidgets()
      self.createLayout()
      self.connectSignals()
      self.setLabels()
      self.plot()
      
   def createWidgets(self):
      #print "createWidgets()"     # DEBUG
      
      self.closeButton=QPushButton("Close")
      self.closeButton.setToolTip("close this plotwindow")
      self.closeButton.show()

      self.histogramBinSpin=QSpinBox()            # spinbox for histogram binsize
      self.histogramBinSpin.setToolTip("Number of bins to histogram into")
      self.histogramBinSpin.setMinimum(5)
      #self.histogramBinSpin.setMaximum(150)        # set a maximum of 150 (reasonable?)
      self.histogramBinSpin.setSingleStep(10)       # allow only stepping by 10
      self.histogramBinSpin.setMaximumWidth(120)
      self.histogramBinSpin.setMinimumHeight(25)
      self.histogramBinSpin.setValue(self.nbins)
      self.histogramBinSpin.show()
      self.histogramBinLabel=QLabel("Bins")
      
      self.normedCheckBox=QCheckBox()
      self.normedCheckLabel=QLabel("Normalize")
      self.normedCheckBox.setToolTip("Normalize histogram")
      self.normedCheckBox.show()
      #self.dpi = 100
      
      self.dataComboBox=QComboBox()
      self.dataComboBox.addItem(self.parent.parent.parmValueComboBox.currentText())
      self.dataComboBox.addItem(self.parent.parent.parametersComboBox.currentText())
      self.dataComboBox.setMaximumWidth(120)
      self.dataComboBox.setMinimumHeight(25)
      self.dataComboBox.setCurrentIndex(1)

   def createLayout(self):
      #print "createLayout()"      # DEBUG
      
      self.normedLayout=QHBoxLayout()
      self.normedLayout.addWidget(self.normedCheckBox)
      self.normedLayout.addWidget(self.normedCheckLabel)
      self.buttonLayout=QVBoxLayout()
      self.plotLayout=QVBoxLayout()
      self.mainLayout=QHBoxLayout()
      self.buttonLayout.addLayout(self.normedLayout)
      #self.buttonLayout.addWidget(self.normedCheckBox)
      #self.buttonLayout.addWidget(self.normedCheckLabel)
      self.buttonLayout.addWidget(self.histogramBinSpin)
      self.buttonLayout.addWidget(self.dataComboBox)
      self.buttonLayout.insertStretch(-1)
      self.buttonLayout.addWidget(self.closeButton)
      self.plotLayout.addWidget(self.canvas)
      self.plotLayout.addWidget(self.mpl_toolbar)
      self.mainLayout.addLayout(self.buttonLayout)
      self.mainLayout.addLayout(self.plotLayout)
      
      self.setLayout(self.mainLayout)

   def setLabels(self):
      self.ax.xlabel="Bin"
      self.ax.ylabel="N"
      
   def setTitle(self):
      #=self.parent.parametersComboBox.currentText()
      #self.ax.xlabel=self.parmValueComboBox.currentText()
      #self.ax.xlabel="Bin No."
      #self.ax.ylabel="n"
      self.ax.title=self.parent.parent.parametersComboBox.currentText()
      
   def connectSignals(self):
      self.connect(self.closeButton, SIGNAL('clicked()'), SLOT('close()'))
      self.connect(self.histogramBinSpin, SIGNAL('valueChanged(int)'), self.on_changeBinSpin)      
      self.connect(self.normedCheckBox, SIGNAL('stateChanged(int)'), self.on_normedCheckBox)
      self.connect(self.dataComboBox, SIGNAL('currentIndexChanged(int)'), self.on_data)
      
   def on_changeBinSpin(self):
      self.nbins=self.histogramBinSpin.value()      
      # create histogram
      #n, bins = np.histogram(self.data, self.histogramBinSpin.value(), normed=self.normedCheckBox.isChecked())
      #hist, bins=np.histogram(self.data, self.nbins, normed=self.normedCheckBox.isChecked())
      
      #print "len(bins) = ", len(bins), " len(n) = ", len(n)
      
      #self.ax.plot(bins[1:], n, color='red')
      #self.canvas.draw()
      #self.ax.legend()
      #self.fig.draw_idle()        # redraw (preferably when idle)
      self.plot()

   def on_normedCheckBox(self):
      self.plot()

   def on_data(self):
      print "on_data()"       # DEBUG
      if self.dataComboBox.currentText()==self.parent.parent.parametersComboBox.currentText():
          self.data=self.data2
      else:
          self.data=self.data1
      self.plot()

   def plot(self):
      self.fig.delaxes(self.ax)            # delete all axes first
      self.ax=self.fig.add_subplot(111)
      
      n, bins = np.histogram(self.data, self.histogramBinSpin.value(), normed=self.normedCheckBox.isChecked())

      self.xmin=bins[1]
      self.xmax=bins[len(bins)-1]
      self.ax.bar(bins[1:], n, color='blue', width=(self.xmax-self.xmin)/len(bins))
      self.canvas.draw()
コード例 #6
0
class MatplotlibPlot:
    """ Class encapsulating a matplotlib plot"""
    def __init__(self, parent = None, dpi = 100, size = (5,5)):
        """ Class initialiser """

        self.dpi = dpi
        self.figure = Figure(size, dpi = self.dpi)
        self.canvas = FigureCanvas(self.figure)
        self.canvas.setParent(parent)

        # Create the navigation toolbar, tied to the canvas
        self.toolbar = NavigationToolbar(self.canvas, parent)
        self.canvas.show()
        self.toolbar.show()

        # Reset the plot landscape
        self.figure.clear()
        self.nSubplot=0

    def resetSubplots(self):
        self.nSubplot=0

    def plotCurve(self, data, xAxisRange = None, yAxisRange = None, xLabel = "", yLabel = "", title="", label="", plotLog=False, nSubplots=1, hold=False):
        """ Plot the data as a curve"""

        if len(data) != 0:
            # Plan what dimensions the grid will have if there are to be subplots
            # Attempt to be roughly square but give preference to vertical stacking
            nSubplots_v = np.ceil(np.sqrt(nSubplots))
            nSubplots_h = np.ceil(float(nSubplots)/nSubplots_v)

            yAxisRange=np.array(yAxisRange)
            if yAxisRange is not None:
                auto_scale_y = False
                if plotLog:
                    data[data==0] = 1
                    yAxisRange[yAxisRange==0] = 1
                    data= 10*np.log(data)
                    yAxisRange = 10*np.log(yAxisRange)
            else:
                auto_scale_y = True

            # draw the new plot
            if self.nSubplot < nSubplots:
                self.axes = self.figure.add_subplot(nSubplots_v, nSubplots_h, self.nSubplot+1, label=label, title=title, ylim=yAxisRange) #subplots start from 1        
                self.axes.grid(True)
            #if plotLog:
            #    self.axes.semilogy(range(np.size(data)), data, scaley=auto_scale_y)
            #else:
            #    self.axes.plot(range(np.size(data)), data, scaley=auto_scale_y)
            self.axes.plot(range(np.size(data)), data, scaley=auto_scale_y)

            #if xAxisRange is not None:        
            #    self.xAxisRange = xAxisRange
            #    self.axes.xaxis.set_major_formatter(ticker.FuncFormatter(
            #               lambda x, pos=None: '%.2f' % self.xAxisRange[x] if 0 <= x < len(xAxisRange) else ''))
            #    for tick in self.axes.xaxis.get_ticklabels():
            #          tick.set_rotation(15)

            #if yAxisRange is not None:        
            #    self.yAxisRange = yAxisRange
            #    self.axes.xaxis.set_major_formatter(ticker.FuncFormatter(
            #               lambda x, pos=None: '%.1f' % self.yAxisRange[y] if 0 <= y < len(yAxisRange) else ''))
            #    for tick in self.axes.yaxis.get_ticklabels():
            #          tick.set_rotation(15)

            self.axes.xaxis.set_label_text(xLabel)
            self.axes.yaxis.set_label_text(yLabel)

            # Increment the subplot number ready for the plot method to be called again.
            # Count modulo number of subplots so that nSubplots=1 is the same as having a
            # single shared axis.
            # Skip this step if hold is set, in which case the next plot will be overlaid with the current one
            if not hold:
                self.nSubplot = (self.nSubplot + 1)

    def plotNewCurve(self, data, xAxisRange=None, yAxisRange=None, xLabel="", yLabel="", plotLog=False):
        # Clear the plot
        self.figure.clear()
        # Start from a new set of subplots
        self.nSubplot = 0
        self.plotCurve(self, data, xAxisRange=xAxisRange, yAxisRange=yAxisRange, xLabel=xLabel, yLabel=yLabel, plotLog=plotLog)

    def updatePlot(self):
        self.canvas.draw()
コード例 #7
0
ファイル: beamPlotter.py プロジェクト: jintaoluo/MDSM
class MatplotlibPlot:
    """ Class encapsulating an matplotlib plot """

    def __init__(self, parent = None, dpi = 100, size = (5,4)):
        """ Class initialiser """

        self.dpi = dpi
        self.figure = Figure(dpi = self.dpi)
        self.canvas = FigureCanvas(self.figure)
        self.canvas.setParent(parent)

        # Create the navigation toolbar, tied to the canvas
        self.toolbar = NavigationToolbar(self.canvas, parent)
        self.canvas.show()
        self.toolbar.show()

    def plotCurve(self, data, numCurves = 1, labels = None, xAxisRange = None, yAxisRange = None, xLabel = "", yLabel = ""):
        """ Normal plots """

        self.figure.clear()
        self.axes = self.figure.add_subplot(111)        
        self.axes.grid(True)

        # Set empty labels if non defined
        if labels is None:
            labels = ['' for i in range(numImages)]

        # Place all plots in axes
        for i in range(numCurves):
            self.axes.plot(data[:,i], label=labels[i])
            self.axes.set_xlim((0, len(data[:,i])))

        # Final touches
        self.axes.xaxis.set_label_text(xLabel)
        self.axes.yaxis.set_label_text(yLabel)
        self.canvas.draw()

    def subplotCurve(self, data, numPlots = 1, labels = None, xAxisRange = None, yAxisRange = None, xLabel = "", yLabel = ""):
        """ Subplot mode """

        self.figure.clear()
  
        # Set empty labels if non defined
        if labels is None:
            labels = ['' for i in range(numImages)]

        if numPlots == 1:
            ax = self.figure.add_subplot(111)
            ax.plot(data[:])
            ax.set_xlabel(xLabel)
            ax.set_ylabel(yLabel)
            ax.set_title(labels[0])   
            ax.grid(True)         
        else:
            # Plot each image
            num_rows = ceil(sqrt(numPlots))
            for i in range(numPlots):
                ax = self.figure.add_subplot(num_rows, num_rows, i + 1)
                ax.plot(data[:,i])
                ax.set_xlim((0, len(data[:,i])))
                ax.set_xlabel(xLabel)
                ax.set_ylabel(yLabel)
                ax.set_title(labels[i])
                ax.grid(True)

        # Final touches
        self.figure.tight_layout()
        self.canvas.draw()


    def plotImage(self, data, numImages = 1, labels = None, xAxisRange = None, yAxisRange = None, xLabel = "", yLabel = ""):
        """ Image plot """

        self.figure.clear()
        self.axes = self.figure.add_subplot(111)        

        # Show image
        im = self.axes.imshow(data, origin='lower', aspect='auto')
    
        # Final touches
        self.axes.xaxis.set_label_text(xLabel)
        self.axes.yaxis.set_label_text(yLabel)
        self.figure.colorbar(im)
        self.canvas.draw()

    def subplotImage(self, data, numImages = 1, labels = None, xAxisRange = None, yAxisRange = None, xLabel = "", yLabel = ""):
        """ Image subplot """

        # Clear figure
        self.figure.clear()

        # Set empty labels if non defined
        if labels is None:
            labels = ['' for i in range(numImages)]

        # Plot each image
        num_rows = ceil(sqrt(numImages))
        for i in range(numImages):
            ax = self.figure.add_subplot(num_rows, num_rows, i + 1)        
            im = ax.imshow(data[:,:,i],  origin='lower', aspect='auto')            
            ax.set_xlabel(xLabel)
            ax.set_ylabel(yLabel)
            ax.set_title(labels[i])

        # Final touches
        self.figure.tight_layout()
        self.canvas.draw()
コード例 #8
0
class MatplotlibWidget(QtGui.QWidget):
    """ This subclass of QtWidget will manage the widget drawing; name matches the class in the *_ui.py file"""

    # Global colors dictionary
    colors_dict = {
        "Discharge": "b",
        "Subsurface Flow": "g",
        "Impervious Flow": "SteelBlue",
        "Infiltration Excess": "SeaGreen",
        "Initial Abstracted Flow": "MediumBlue",
        "Overland Flow": "RoyalBlue",
        "PET": "orange",
        "AET": "DarkOrange",
        "Average Soil Root zone": "Gray",
        "Average Soil Unsaturated Zone": "DarkGray",
        "Snow Pack": "PowderBlue",
        "Precipitation": "SkyBlue",
        "Storage Deficit": "Brown",
        "Return Flow": "Aqua",
        "Water Use": "DarkCyan",
        "Discharge + Water Use": "DarkBlue"
    }

    def __init__(self, parent=None):
        super(MatplotlibWidget, self).__init__(parent)

        # create object scope variables for watertxt data plot; used by radio buttons and span selector
        self.watertxt_data = None
        self.parameter = None
        self.color_str = None
        self.axes_text = None
        self.axes_radio = None
        self.parent = parent

        # create figure
        self.figure = Figure()

        # create canvas and set some of its properties
        self.canvas = FigureCanvas(self.figure)
        self.canvas.setParent(parent)
        self.canvas.setSizePolicy(QtGui.QSizePolicy.Expanding,
                                  QtGui.QSizePolicy.Expanding)
        self.canvas.updateGeometry()
        self.canvas.setFocusPolicy(QtCore.Qt.StrongFocus)
        self.canvas.setFocus()

        # set up axes and its properties
        self.ax = self.figure.add_subplot(111)
        self.ax.grid(True)

        # create toolbar
        self.matplotlib_toolbar = NavigationToolbar(
            self.canvas, parent)  # the matplotlib toolbar object

        # create the layout
        self.layout = QtGui.QVBoxLayout()

        # add the widgets to the layout
        self.layout.addWidget(self.matplotlib_toolbar)
        self.layout.addWidget(self.canvas)

        # set the layout
        self.setLayout(self.layout)

    #-------------------------------- WATER.txt Parameter Plot ------------------------------------

    def setup_watertxt_plot(self):
        """ Setup the watertxt plot """

        self.clear_watertxt_plot()

        # set up axes and its properties
        self.axes = self.figure.add_subplot(111)
        self.axes.grid(True)

        # create radio buttons
        self.axes_radio = self.figure.add_axes(
            [0.01, 0.02, 0.10, 0.15]
        )  # [left, bottom, width, height] = fractions of figure width and height
        self.figure.subplots_adjust(bottom=0.2)
        self.radio_buttons = RadioButtons(ax=self.axes_radio,
                                          labels=("Span On", "Span Off"),
                                          active=1,
                                          activecolor="r")
        self.radio_buttons.on_clicked(self.toggle_selector)

        # create SpanSelector; invisble at first unless activated with toggle selector
        self.span_selector = SpanSelector(self.axes,
                                          self.on_select_axes,
                                          'horizontal',
                                          useblit=True,
                                          rectprops=dict(alpha=0.5,
                                                         facecolor='red'))
        self.span_selector.visible = False

    def plot_watertxt_parameter(self, watertxt_data, name):
        """ Plot a parameter from a WATER.txt file """

        self.reset_watertxt_plot()

        self.dates = watertxt_data["dates"]
        self.watertxt_data = watertxt_data
        self.parameter = watertxt.get_parameter(watertxt_data, name=name)

        assert self.parameter is not None, "Parameter name {} is not in watertxt_data".format(
            name)

        self.axes.set_title("Parameter: {}".format(self.parameter["name"]))
        self.axes.set_xlabel("Date")
        ylabel = "\n".join(wrap(self.parameter["name"], 60))
        self.axes.set_ylabel(ylabel)

        # get proper color that corresponds to parameter name
        self.color_str = self.colors_dict[name.split('(')[0].strip()]

        # plot parameter
        self.axes.plot(self.dates,
                       self.parameter["data"],
                       color=self.color_str,
                       label=self.parameter["name"],
                       linewidth=2)

        # legend; make it transparent
        handles, labels = self.axes.get_legend_handles_labels()
        legend = self.axes.legend(handles, labels, fancybox=True)
        legend.get_frame().set_alpha(0.5)
        legend.draggable(state=True)

        # show text of mean, max, min values on graph; use matplotlib.patch.Patch properies and bbox
        text = "mean = {:.2f}\nmax = {:.2f}\nmin = {:.2f}".format(
            self.parameter["mean"], self.parameter["max"],
            self.parameter["min"])

        patch_properties = {
            "boxstyle": "round",
            "facecolor": "wheat",
            "alpha": 0.5
        }

        self.axes_text = self.axes.text(0.05,
                                        0.95,
                                        text,
                                        transform=self.axes.transAxes,
                                        fontsize=14,
                                        verticalalignment="top",
                                        horizontalalignment="left",
                                        bbox=patch_properties)

        # use a more precise date string for the x axis locations in the toolbar and rotate labels
        self.axes.fmt_xdata = mdates.DateFormatter("%Y-%m-%d")

        # rotate and align the tick labels so they look better; note that self.figure.autofmt_xdate() does not work because of the radio button axes
        for label in self.axes.get_xticklabels():
            label.set_ha("right")
            label.set_rotation(30)

        # draw the plot
        self.canvas.draw()

    def on_select_helper(self, xmin, xmax):
        """ Helper for on_select methods """

        # convert matplotlib float dates to a datetime format
        date_min = mdates.num2date(xmin)
        date_max = mdates.num2date(xmax)

        # put the xmin and xmax in datetime format to compare
        date_min = datetime.datetime(date_min.year, date_min.month,
                                     date_min.day, date_min.hour,
                                     date_min.minute)
        date_max = datetime.datetime(date_max.year, date_max.month,
                                     date_max.day, date_max.hour,
                                     date_max.minute)

        # find the indices that were selected
        indices = np.where((self.dates >= date_min) & (self.dates <= date_max))
        indices = indices[0]

        # get the selected dates and values
        selected_dates = self.dates[indices]
        selected_values = self.parameter["data"][indices]

        # compute simple stats on selected values
        selected_values_mean = nanmean(selected_values)
        selected_value_max = np.nanmax(selected_values)
        selected_value_min = np.nanmin(selected_values)

        return selected_dates, selected_values, selected_values_mean, selected_value_max, selected_value_min

    def on_select_axes(self, xmin, xmax):
        """ A select handler for SpanSelector that updates axes with the new x and y limits selected by user """

        selected_dates, selected_values, selected_values_mean, selected_value_max, selected_value_min = self.on_select_helper(
            xmin, xmax)

        # plot the selected values and update plots limits and text
        self.axes.plot(selected_dates, selected_values, self.color_str)
        self.axes.set_xlim(selected_dates[0], selected_dates[-1])
        self.axes.set_ylim(selected_values.min(), selected_values.max())

        text = 'mean = %.2f\nmax = %.2f\nmin = %.2f' % (
            selected_values_mean, selected_value_max, selected_value_min)
        self.axes_text.set_text(text)

        # draw the updated plot
        self.canvas.draw()

    def toggle_selector(self, radio_button_label):
        """ 
        A toggle radio buttons for the matplotlib SpanSelector widget.
        """

        if radio_button_label == "Span On":
            self.span_selector.visible = True
            self.matplotlib_toolbar.hide()

        elif radio_button_label == "Span Off":
            self.span_selector.visible = False
            self.matplotlib_toolbar.show()
            self.plot_watertxt_parameter(watertxt_data=self.watertxt_data,
                                         name=self.parameter["name"])

    def clear_watertxt_plot(self):
        """ Clear the plot axes """

        self.figure.clear()
        self.canvas.draw()

    def reset_watertxt_plot(self):
        """ Clear the plot axes """

        self.axes.clear()
        self.canvas.draw()
        self.axes.grid(True)

    #-------------------------------- WATER.txt Parameter Comparison Plot ------------------------------------

    def setup_watertxtcmp_plot(self):
        """ Setup the watertxt plot """

        self.clear_watertxtcmp_plot()

        # set up axes and its properties
        self.axes1 = self.figure.add_subplot(211)
        self.axes2 = self.figure.add_subplot(212, sharex=self.axes1)

        self.axes1.grid(True)
        self.axes2.grid(True)

    def plot_watertxtcmp_parameter(self, watertxt_data1, watertxt_data2,
                                   filename1, filename2, name):
        """ Plot a parameter from a WATER.txt file """

        self.reset_watertxtcmp_plot()

        dates = watertxt_data1["dates"]

        parameter1 = watertxt.get_parameter(watertxt_data=watertxt_data1,
                                            name=name)
        parameter2 = watertxt.get_parameter(watertxt_data=watertxt_data2,
                                            name=name)

        assert parameter1 is not None, "Parameter name {} is not in watertxt_data".format(
            name)
        assert parameter2 is not None, "Parameter name {} is not in watertxt_data".format(
            name)

        # calculate the difference
        diff = parameter2["data"] - parameter1["data"]

        # plot parameters on axes1
        self.axes1.plot(dates,
                        parameter1["data"],
                        color="b",
                        label=filename1 + ": " + parameter1["name"],
                        linewidth=2)
        self.axes1.hold(True)
        self.axes1.plot(dates,
                        parameter2["data"],
                        color="r",
                        label=filename2 + ": " + parameter2["name"],
                        linewidth=2)

        # plot the difference on axes2
        self.axes2.plot(dates, diff, color="k", linewidth=2)

        # add title, labels, legend
        self.axes1.set_title(parameter1["name"])

        self.axes2.set_xlabel("Date")
        self.axes2.set_ylabel("Difference")

        handles1, labels1 = self.axes1.get_legend_handles_labels()
        legend1 = self.axes1.legend(handles1, labels1, fancybox=True)
        legend1.get_frame().set_alpha(0.5)
        legend1.draggable(state=True)

        # show text of mean, max, min values on graph; use matplotlib.patch.Patch properies and bbox
        text1 = "mean = {:.2f}\nmax = {:.2f}\nmin = {:.2f}".format(
            parameter1["mean"], parameter1["max"], parameter1["min"])
        text2 = "mean = {:.2f}\nmax = {:.2f}\nmin = {:.2f}".format(
            parameter2["mean"], parameter2["max"], parameter2["min"])

        text_diff = "mean = {:.2f}\nmax = {:.2f}\nmin = {:.2f}".format(
            nanmean(diff), np.max(diff), np.min(diff))

        patch_properties1 = {
            "boxstyle": "round",
            "facecolor": "b",
            "alpha": 0.5
        }
        patch_properties2 = {
            "boxstyle": "round",
            "facecolor": "r",
            "alpha": 0.5
        }
        patch_properties_diff = {
            "boxstyle": "round",
            "facecolor": "wheat",
            "alpha": 0.5
        }

        self.axes1.text(0.02,
                        0.95,
                        text1,
                        transform=self.axes1.transAxes,
                        fontsize=12,
                        verticalalignment="top",
                        horizontalalignment="left",
                        bbox=patch_properties1)
        self.axes1.text(0.02,
                        0.45,
                        text2,
                        transform=self.axes1.transAxes,
                        fontsize=12,
                        verticalalignment="top",
                        horizontalalignment="left",
                        bbox=patch_properties2)
        self.axes2.text(0.02,
                        0.95,
                        text_diff,
                        transform=self.axes2.transAxes,
                        fontsize=12,
                        verticalalignment="top",
                        horizontalalignment="left",
                        bbox=patch_properties_diff)

        # use a more precise date string for the x axis locations in the toolbar and rotate labels
        self.axes2.fmt_xdata = mdates.DateFormatter("%Y-%m-%d")

        # rotate and align the tick labels so they look better
        self.figure.autofmt_xdate()

        # draw the plot
        self.canvas.draw()

    def clear_watertxtcmp_plot(self):
        """ Clear the plot axes """

        self.figure.clear()
        self.canvas.draw()

    def reset_watertxtcmp_plot(self):
        """ Clear the plot axes """

        self.axes1.clear()
        self.axes2.clear()
        self.canvas.draw()
        self.axes1.grid(True)
        self.axes2.grid(True)

    #-------------------------------- Basemap Plot ------------------------------------

    def setup_basemap_plot(self):
        """ Setup the watertxt plot """

        self.clear_basemap_plot()

        # set up axes and its properties
        self.basemap_axes = self.figure.add_subplot(111)
        self.basemap_axes.grid(True)

    def get_map_extents(self, shapefiles, shp_name=None):
        """   
        Get max and min extent coordinates from a list of shapefiles to use as the 
        extents on the map. Use the map extents to calculate the map center and the 
        standard parallels.

        Parameters
        ----------
        shapefiles : list 
            List of shapefile_data dictionaries 
        shp_name : string
            String name of shapefile to use for getting map extents 

        Returns
        -------
        extent_coords : dictionary 
            Dictionary containing "lon_min", "lon_max", "lat_max", "lat_min" keys with respective calculated values
        center_coords : dictionary 
            Dictionary containing "lon", "lat" keys with respective calculated values
        standard_parallels : dictionary 
            Dictionary containing "first", "second" keys with respective calculated values (first = min(lat), second = max(lat))   
        """
        extent_coords = {}
        center_coords = {}
        standard_parallels = {}

        lons = []
        lats = []

        if shp_name:
            for shapefile_data in shapefiles:
                if shp_name in shapefile_data["name"].split("_")[0]:
                    lons.append(shapefile_data["extents"][0:2])
                    lats.append(shapefile_data["extents"][2:])

        else:
            for shapefile_data in shapefiles:
                lons.append(shapefile_data["extents"][0:2])
                lats.append(shapefile_data["extents"][2:])

        extent_coords["lon_min"] = np.min(lons)
        extent_coords["lon_max"] = np.max(lons)
        extent_coords["lat_min"] = np.min(lats)
        extent_coords["lat_max"] = np.max(lats)

        center_coords["lon"] = np.mean(
            [extent_coords["lon_min"], extent_coords["lon_max"]])
        center_coords["lat"] = np.mean(
            [extent_coords["lat_min"], extent_coords["lat_max"]])

        standard_parallels["first"] = extent_coords["lat_min"]
        standard_parallels["second"] = extent_coords["lat_max"]

        return extent_coords, center_coords, standard_parallels

    def plot_shapefiles_map(self,
                            shapefiles,
                            display_fields=[],
                            colors=[],
                            title=None,
                            shp_name=None,
                            buff=1.0):
        """   
        Generate a map showing all the shapefiles in the shapefile_list.  
        Shapefiles should be in a Geographic Coordinate System (longitude and 
        latitude coordinates) such as World WGS84; Matplotlib"s basemap library 
        does the proper transformation to a projected coordinate system.  The projected
        coordinate system used is Albers Equal Area.
        
        Parameters
        ----------
        shapefiles : list 
            List of dictionaries containing shapefile information
        title : string 
            String title for plot
        display_fields : list 
            List of strings that correspond to a shapefile field where the corresponding value(s) will be displayed.
        colors : list
            List of strings that correspond to colors to be displayed
        shp_name : string
            String name of shapefile to use for getting map extents 
        buff : float
            Float value in coordinate degrees to buffer the map with
        """

        self.setup_basemap_plot()

        extent_coords, center_coords, standard_parallels = self.get_map_extents(
            shapefiles, shp_name=shp_name)

        # create the basemap object with Albers Equal Area Conic Projection
        bmap = Basemap(projection="aea",
                       llcrnrlon=extent_coords["lon_min"] - buff,
                       llcrnrlat=extent_coords["lat_min"] - buff,
                       urcrnrlon=extent_coords["lon_max"] + buff,
                       urcrnrlat=extent_coords["lat_max"] + buff,
                       lat_1=standard_parallels["first"],
                       lat_2=standard_parallels["second"],
                       lon_0=center_coords["lon"],
                       lat_0=center_coords["lat"],
                       resolution="h",
                       area_thresh=10000,
                       ax=self.basemap_axes)

        # have basemap object plot background stuff
        bmap.drawcoastlines()
        bmap.drawcountries()
        bmap.drawrivers(linewidth=1, color="blue")
        bmap.drawstates()
        bmap.drawmapboundary(fill_color="aqua")
        bmap.fillcontinents(color="coral", lake_color="aqua")
        bmap.drawparallels(np.arange(-80., 81., 1.),
                           labels=[1, 0, 0, 0],
                           linewidth=0.5)
        bmap.drawmeridians(np.arange(-180., 181., 1.),
                           labels=[0, 0, 0, 1],
                           linewidth=0.5)

        # plot each shapefile on the basemap
        legend_handles = []
        legend_labels = []
        colors_index = 0
        colors_list = [
            "b", "g", "y", "r", "c", "y", "m", "orange", "aqua", "darksalmon",
            "gold", "k"
        ]
        for shapefile_data in shapefiles:

            # set up colors to use
            if colors:
                color = colors[colors_index]
            elif colors_index > len(colors_list) - 1:
                color = np.random.rand(3, )
            else:
                color = colors_list[colors_index]

            full_path = os.path.join(shapefile_data["path"],
                                     shapefile_data["name"].split(".")[0])

            shp_tuple = bmap.readshapefile(
                full_path, "shp", drawbounds=False
            )  # use basemap shapefile reader for ease of plotting
            for shape_dict, shape in zip(
                    bmap.shp_info, bmap.shp
            ):  # zip the shapefile information and its shape as defined by basemap

                if shapefile_data["type"] == "POLYGON":
                    p1 = Polygon(shape,
                                 facecolor=color,
                                 edgecolor="k",
                                 linewidth=1,
                                 alpha=0.7,
                                 label=shapefile_data["name"])
                    self.basemap_axes.add_patch(p1)
                    xx, yy = zip(*shape)
                    txt_x = str(np.mean(xx))
                    txt_y = str(np.mean(yy))

                elif shapefile_data["type"] == "POINT":
                    x, y = shape

                    if "usgsgages" in shapefile_data["name"].split("_")[0]:
                        p1 = bmap.plot(x,
                                       y,
                                       color=color,
                                       marker="^",
                                       markersize=10,
                                       label=shapefile_data["name"])
                    elif "wateruse" in shapefile_data["name"].split("_")[0]:
                        p1 = bmap.plot(x,
                                       y,
                                       color=color,
                                       marker="o",
                                       markersize=5,
                                       label=shapefile_data["name"])
                    else:
                        print("what!!")
                        p1 = bmap.plot(x,
                                       y,
                                       color=color,
                                       marker="o",
                                       markersize=10,
                                       label=shapefile_data["name"])

                    txt_x = str(x)
                    txt_y = str(y)

                else:
                    xx, yy = zip(*shape)
                    p1 = bmap.plot(xx,
                                   yy,
                                   linewidth=1,
                                   color=color,
                                   label=shapefile_data["name"])
                    txt_x = str(np.mean(xx))
                    txt_y = str(np.mean(yy))

                if isinstance(p1, list):
                    p1 = p1[0]

                # control text display of shapefile fields
                for display_field in display_fields:
                    if display_field in shape_dict.keys():
                        self.basemap_axes.text(txt_x,
                                               txt_y,
                                               shape_dict[display_field],
                                               color="k",
                                               fontsize=12,
                                               fontweight="bold")

            colors_index += 1
            legend_handles.append(p1)
            legend_labels.append(shapefile_data["name"].split("_")[0])

        handles, labels = self.basemap_axes.get_legend_handles_labels()

        # edit the contents of handles and labels to only show 1 legend per shape
        handles = legend_handles
        labels = legend_labels
        legend = self.basemap_axes.legend(handles,
                                          labels,
                                          fancybox=True,
                                          numpoints=1)
        legend.get_frame().set_alpha(0.5)
        legend.draggable(state=True)

        # draw the plot
        self.canvas.draw()

    def clear_basemap_plot(self):
        """ Clear the plot axes """

        self.figure.clear()
        self.canvas.draw()

    def reset_basemap_plot(self):
        """ Clear the plot axes """

        self.basemap_axes.clear()
        self.canvas.draw()
コード例 #9
0
ファイル: plotwindow.py プロジェクト: jjdmol/LOFAR
class PlotWindow(QFrame):

   # Init the class: create plot window and canvas layout (and corresponding buttons)
   #
   def __init__(self, parent):
      QDialog.__init__(self)

      self.rim=0.05                 # rim around plot

      # The plot class holds its data now, so that it can be exported after a different
      # PlotWindow has been created
      self.parent=parent            # parent object/class
      self.fig=None
      self.showCursor=False
      self.cursorId=None
      self.markerId=None
      self.marker1=None              # position marker in the plot
      self.marker2=None

      self.x = parent.x             # plotted x axis data
      self.x0 = self.parent.solverQuery.getTimeSlots()[0]['STARTTIME']
      self.y1 = parent.y1           # plotted y axis data
      self.y2 = parent.y2           # plotted y2 axis data
      self.xdata = None             # cursor click x coordinate in data value
      self.ydata = None             # cursor click y coordinate in data value
      self.messages = parent.messages   # solver messages

      # Create canvas for plotting
      self.fig = Figure((5, 4), dpi=100)
      self.canvas = FigureCanvas(self.fig)
      self.canvas.setParent(self)
      self.fig.subplots_adjust(left=self.rim+0.05, right=1.0-self.rim, top=1.0-self.rim, bottom=self.rim)  # set a small rim

      self.mpl_toolbar = NavigationToolbar(self.canvas, self)
      self.mpl_toolbar.show()   # first hide the toolbar

      self.setMinimumWidth(900)
      self.setMinimumHeight(600)

      self.setWindowTitle = self.parent.tableName  + ": " + str(self.parent.solverQuery.getRank()) + " Parameters"
      self.createWidgets()
      self.createConnections()
      self.createLayouts()

   def createWidgets(self):
      # Create Buttons for data export
      #
      self.exportButton=QPushButton("&Export Data")
      self.exportButton.setToolTip("Export the currently plotted data")
      self.exportButton.setMaximumWidth(100)

      self.exportComboBox=QComboBox()
      self.exportComboBox.addItem("ASCII")
      # export in Matlab format is only possible if scipy.io module has been imported
      if self.parent.haveModule('scipy') == True or self.parent.haveModule('scipy.io') == True:
         self.exportComboBox.addItem("Matlab")
      self.exportComboBox.setToolTip('File format for exporting data')
      self.exportComboBox.setMaximumWidth(100)
      self.exportComboBox.setMinimumHeight(25)

      self.showCursorCheckBox=QCheckBox("Show cursor")
      self.showCursorCheckBox.setToolTip("Show a marker line in plot")
      self.showCursorCheckBox.setCheckState(Qt.Unchecked)    # default off

      self.histogramButton=QPushButton("&Histogram")    # button to create a histogram
      self.histogramButton.setToolTip("Create a histogram of the current parameter")
      self.histogramButton.setMaximumWidth(150)
      self.histogramButton.setToolTip('Create a histogram of current data')

      self.onClickLabel=QLabel("On click display:")
      self.onClickComboBox=QComboBox()
      self.onClickComboBox.setMaximumWidth(150)
      self.onClickComboBox.setToolTip('What to display when data point in graph is clicked')
      self.onClickComboBox.addItem("CorrMatrix")      # first, default = correlation matrix
      self.onClickComboBox.addItem("Zoom")
      #self.onClickComboBox.addItem("Per iteration")
      #self.onClickComboBox.addItem("CorrMatrix and Iterations")

      self.solverMessageLabel=QLabel("Solver Message:")

      self.solverMessageText=QLineEdit()
      self.solverMessageText.setText('Undefined')
      self.solverMessageText.setToolTip('Message returned by LSQFit after iteration')
      self.solverMessageText.setReadOnly(True)
      self.solverMessageText.setMaximumWidth(125)

      self.closeButton=QPushButton()
      self.closeButton.setText('Close')
      self.closeButton.setToolTip('close this plot window')
      self.closeButton.setMaximumWidth(120)


   def createConnections(self):
      # Set connections
      self.connect(self.exportButton, SIGNAL('clicked()'), self.on_export)
      self.connect(self.histogramButton, SIGNAL('clicked()'), self.on_histogram)
      self.connect(self.closeButton, SIGNAL('clicked()'), SLOT('close()'))
      self.connect(self.showCursorCheckBox, SIGNAL('stateChanged(int)'), self.on_cursor)
      self.connect(self.onClickComboBox, SIGNAL('valueChanged(int)'), self.on_onClickComboBox)


   # Layouts for canvas and buttons
   #
   def createLayouts(self):
      buttonLayout = QVBoxLayout()
      buttonLayout.addWidget(self.exportButton)
      buttonLayout.addWidget(self.exportComboBox)
      buttonLayout.addWidget(self.showCursorCheckBox)
      buttonLayout.addWidget(self.histogramButton)
      buttonLayout.addWidget(self.onClickComboBox)
      buttonLayout.addWidget(self.solverMessageLabel)
      buttonLayout.addWidget(self.solverMessageText)
      buttonLayout.insertStretch(-1)
      buttonLayout.addWidget(self.closeButton)
      #buttonLayout.insertStretch(-1)
      #buttonLayout.setMaximumWidth(160)

      # Canvas layout
      canvasLayout = QVBoxLayout()
      canvasLayout.addWidget(self.canvas, 1)
      canvasLayout.addWidget(self.mpl_toolbar)

      mainLayout = QHBoxLayout()
      mainLayout.addLayout(buttonLayout)
      mainLayout.addLayout(canvasLayout)
      self.setLayout(mainLayout)

      self.show()           # show the plotWindow widget
      self.parent.setXLabel()
      self.parent.setYLabel()

      # Matplotlib event connections
      #if self.showMarker==True:
      #  cid = self.fig.canvas.mpl_connect('motion_notify_event', self.update_marker)
      #  cid = self.fig.canvas.mpl_connect('button_press_event', onclick)

      cid = self.fig.canvas.mpl_connect('motion_notify_event', self.on_solverMessage)  # TODO: this doesn work
      self.cursorId = self.fig.canvas.mpl_connect('button_press_event', self.on_click)
      self.plot()


   # React on showMarkerCheckBox signal
   #
   """
   def on_marker(self):
      #print "on_marker checkState = ", self.showMarkerCheckBox.checkState()  # DEBUG
      if self.showMarkerCheckBox.isChecked()==True:
        self.showMarker=True
        self.markerId = self.fig.canvas.mpl_connect('motion_notify_event', self.update_marker)
      else:
        print "on_marker() disconnecting marker event"
        self.showMarker=False
        self.fig.canvas.mpl_disconnect(self.markerId)

   # Plot a vertical line marker on the solutions plot showing the solution
   # of the currently plotted solver parameters
   # TODO: EXPERIMENTAL
   #
   def update_marker(self, event):
      #print "plotMarker() pos = ", event.xdata       # DEBUG
      
      #print 'button=%d, x=%d, y=%d, xdata=%f, ydata=%f'%(
      #   event.button, event.x, event.y, event.xdata, event.ydata)     # DEBUG      
      
      # Create markers (vertical lines) in both plots
      self.marker1=self.ax1.axvline(x=event.xdata, linewidth=1.5, color='r')
      self.marker2=self.ax2.axvline(x=event.xdata, linewidth=1.5, color='r')
 
      # We need to remove all unnecessary marker in plot 1 and plot 2
      # TODO: find better method, keeps double marker sometimes
      while len(self.ax1.lines)-1 > 1:
        self.ax1.lines[len(self.ax1.lines)-1].remove()
      while len(self.ax2.lines)-1 > 1:
        self.ax2.lines[len(self.ax1.lines)-1].remove()  
       
      self.marker1=self.ax1.axvline(x=event.xdata, linewidth=1.5, color='r')
      self.marker2=self.ax1.axvline(x=event.xdata, linewidth=1.5, color='r')
#      self.canvas.draw_idle()
      self.canvas.draw()
   """

   def plotcorrmatrix(self):
      print "plotcorrmatrix()"      # DEBUG

      #print "self.parent.xAxisType = ", self.parent.xAxisType   # DEBUG
      
      indx = np.searchsorted(self.x, [self.xdata])[0]
      if self.parent.xAxisType=="Time":
        start_time=self.parent.solverQuery.timeSlots[indx]['STARTTIME']
        end_time=self.parent.solverQuery.timeSlots[indx]['ENDTIME']      
        start_freq=self.parent.solverQuery.frequencies[self.parent.frequencyStartSlider.value()]['STARTFREQ']
        end_freq=self.parent.solverQuery.frequencies[self.parent.frequencyEndSlider.value()]['ENDFREQ']
      elif self.parent.xAxisType=="Freq":
        start_freq=self.parent.solverQuery.frequencySlots[indx]['STARTFREQ']
        end_freq=self.parent.solverQuery.frequencylots[indx]['ENDFREQ']      
        start_time=self.parent.solverQuery.frequencies[self.parent.timeStartSlider.value()]['STARTTIME']
        end_time=self.parent.solverQuery.frequencies[self.parent.timeEndSlider.value()]['ENDTIME']
      else:     # Iteration
        start_time=self.parent.solverQuery.timeSlots[self.parent.timeStartSlider.value()]['STARTTIME']
        end_time=self.parent.solverQuery.timeSlots[self.parent.timeEndSlider.value()]['ENDTIME']      
        start_freq=self.parent.solverQuery.frequencies[self.parent.frequencyStartSlider.value()]['STARTFREQ']
        end_freq=self.parent.solverQuery.frequencies[self.parent.frequencyEndSlider.value()]['ENDFREQ']


      #print "plotwindow::plotcorrmatri() start_time = ", start_time     # DEBUG
      #print "plotwindow::plotcorrmatri() end_time = ", end_time         # DEBUG
      #print "plotwindow::plotcorrmatri() start_freq = ", start_freq     # DEBUG
      #print "plotwindow::plotcorrmatri() end_freq = ", end_freq         # DEBUG

      corrMatrix=self.parent.solverQuery.getCorrMatrix(start_time, end_time, start_freq, end_freq)
      
      self.corrmatrixDialog=pc.plotCorrmatrix(self, corrMatrix)
      self.corrmatrixDialog.show()

   # Activate / Deactivate Matplotlib demo cursor 
   #
   def on_cursor(self):
      print "on_cursor()"   # DEBUG
      self.showCursor=self.showCursorCheckBox.isChecked()
   
      print "on_cursor() self.showCursor = ", self.showCursor
   
      if self.showCursor==True:
        self.cursor = Cursor(self.ax1, self)
        #self.cursor = SnaptoCursor(self.ax1, self.x, self.y1, self)
        self.fig.canvas.mpl_connect('motion_notify_event', self.cursor.mouse_move)
      else:
        self.cursor.lx.remove()
        self.cursor.ly.remove()
        self.fig.canvas.mpl_disconnect(self.cursorId)
        
        
   # Handle export button clicked()
   #
   def on_export(self):
      fileformat=self.exportComboBox.currentText()
      self.parent.on_export(fileformat)

   # TODO!
   def on_logarithmic(self):
      self.yscale('log')


   # Functio to execute on a click event (experimental)
   #
   def on_click(self, event):
      print 'button=%d, x=%d, y=%d, xdata=%f, ydata=%f'%(
         event.button, event.x, event.y, event.xdata, event.ydata)     # DEBUG      

      print "event.key = ", event.key   # DEBUG

      self.xdata=event.xdata
      self.ydata=event.ydata

      # Depending on the setting in the onClickComboBox launch appropriate dialog
      #
      if self.onClickComboBox.currentText()=="CorrMatrix":   # if CorrMatrix should be displayed
        # Pick per iteration details if possible
        if self.parent.tableType == "PERSOLUTION_CORRMATRIX" or self.parent.tableType == "PERITERATION_CORRMATRIX":
            self.plotcorrmatrix()
        else:
            print "on_clickMarker() table is not of correct type"
      elif self.onClickComboBox.currentText()=="Per iteration":
        print "plotwindow::on_click() trying to launch per iteration plotwindow"


   # Display a histogram of the converged solutions (i.e. LASTITER=TRUE)
   # for the currently selected parameter
   #
   def on_histogram(self):
      self.histoDialog=ph.plothistogram(self)
      self.histoDialog.show()


   def on_onClickComboBox(self):
      print "on_onClickComboBox()"    # DEBUG
      if self.onClickComboBox.currentText()=="Zoom":
        self.fig.canvas.mpl_disconnect(self.cursorId)
      elif self.onClickComboBox.currentText()=="CorrMatrix":
        self.cursorId = self.fig.canvas.mpl_connect('button_press_event', self.on_click)
      elif self.onClickComboBox.currentText()=="Per iteration":
        self.cursorId = self.fig.canvas.mpl_connect('button_press_event', self.on_click)
      

   def on_solverMessage(self, event):
      if self.messages!=None:                       # only if we indeed inherited messages from parent
        self.xdata = event.xdata
        self.ydata = event.ydata                    # get cursor position from figure
    
        index = np.searchsorted(self.x, [self.xdata])[0]     # get Message for the index of cursor position
        resultType=self.messages['result']

        #print "resultType = ", resultType
        #print "len(self.messages) = ", len(self.messages['last'])
        #print "self.xdata = ", self.xdata    
        #print "on_solverMessage() index = ", index
        #print "self.messages[index] = ", self.messages[resultType][index]

        #print "self.parent.messages = ", self.parent.messages
        #self.solverMessageText.setText(self.messages[resultType][index])
      
        self.solverMessageText.setReadOnly(False)     # make it writable
        
        #print "resultType =", resultType    # DEBUG
        if resultType=="last":
            #self.solverMessageText.setText(self.messages[resultType][index])    
            self.solverMessageText.setText(self.messages[index])    
        elif resultType=="all":
            #self.solverMessageText.setText(self.messages[resultType][index])
            self.solverMessageText.setText(self.messages[index])
        elif resultType==None:
            print "on_solverMessage() None messages"
            return
        self.solverMessageText.setReadOnly(True)      # make it readonly again that user can't mess with it
  
   # Plot data that has been read
   #
   def plot(self):
      print "PlotWindow::plot()"            # DEBUG

      parm=self.parent.parmsComboBox.currentText()   # Solution parameter, e.g. Gain:1:1:LBA001
      parameter=str(self.parent.parametersComboBox.currentText())    # Get solver parameter from drop down

      # Give for Time axis only time relative to start time
      # TODO this does not work
      if self.parent.xAxisType=="Time":
         self.x=self.parent.computeRelativeX()
      
      self.ax1=self.fig.add_subplot(211)   # create solutions subplot
      # Set title and labels
      self.ax1.set_xlabel(self.parent.xLabel)
      self.ax1.set_ylabel(parm + ":" + self.parent.parmValueComboBox.currentText())

      np.set_printoptions(precision=1)
#      self.ax1.get_xaxis().set_visible(False)  # TODO: How to get correct x-axis ticks?
      np.set_printoptions(precision=2)    # does this work?

      if self.parent.perIteration==True:
         x=range(1, len(self.y1)+1)       # we want the first iteration to be called "1"
         if self.parent.scatterCheckBox.isChecked()==True:
            self.ax1.scatter(x, self.y1)
         else:
            self.ax1.plot(x, self.y1)
      else:
         if self.parent.scatterCheckBox.isChecked()==True:
            self.ax1.scatter(self.x, self.y1)
         else:
            if len(self.y1)==1 or isinstance(self.y1, float):
               self.ax1.scatter(self.x, self.y1)
            else:
               self.ax1.plot(self.x, self.y1)

      # Solver log plot
      self.ax2=self.fig.add_subplot(212, sharex=self.ax1)     # sharex for common zoom
      # Set labels
      #self.ax2.set_xticklabels(self.ax1.get_xticklabels(), visible=True)
      self.ax2.set_ylabel(self.parent.parametersComboBox.currentText())
      if self.parent.perIteration==True:
         x=range(1, len(self.y2)+1)
         if self.parent.scatterCheckBox.isChecked()==True:
            self.ax2.scatter(x, self.y2)
         else:
            self.ax2.plot(x, self.y2)   # have to increase lower y limit (for unknown reason)
      else:
         if self.parent.scatterCheckBox.isChecked()==True:
            self.ax2.scatter(self.x, self.y2)
         else:
            if len(self.y1)==1 or isinstance(self.y2, float):
               self.ax2.scatter(self.x, self.y2)
            else:
               self.ax2.plot(self.x, self.y2)

      self.fig.canvas.draw()
コード例 #10
0
class plotCorrmatrix(QDialog):
    def __init__(self, parent, corrmatrix):
        QFrame.__init__(self)

        self.setWindowTitle("Correlation Matrix")

        self.corrmatrix = [[]]
        self.rank = None
        self.rim = 0.05

        self.parent = parent  # parent object/class
        self.fig = None

        # Create canvas for plotting
        self.fig = Figure((7, 7), dpi=100)
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setParent(self)
        self.fig.subplots_adjust(left=self.rim,
                                 right=1.0 - self.rim,
                                 top=1.0 - self.rim,
                                 bottom=self.rim)  # set a small rim
        self.ax = self.fig.add_subplot(111)

        self.mpl_toolbar = NavigationToolbar(self.canvas, self)
        self.mpl_toolbar.show()

        self.setMinimumWidth(700)
        self.setMinimumHeight(700)
        self.corrmatrix = corrmatrix

        self.xLabel = "Parameter index"
        self.yLabel = "Parameter index"

        self.createWidgets()
        self.createLayouts()
        self.connectSignals()
        self.plot(self.corrmatrix)

    def createWidgets(self):
        # Get time indices (and frequency range) from solverdialog class according to plotwindow index
        self.index = np.searchsorted(self.parent.x, [self.parent.xdata])[0]

        print("self.index = ", self.index)  # DEBUG

        self.start_time = self.parent.parent.solverQuery.timeSlots[
            self.index]['STARTTIME']
        self.end_time = self.parent.parent.solverQuery.timeSlots[
            self.index]['ENDTIME']
        self.start_freq = self.parent.parent.solverQuery.frequencies[
            self.parent.parent.frequencyStartSlider.value()]['STARTFREQ']
        self.end_freq = self.parent.parent.solverQuery.frequencies[
            self.parent.parent.frequencyEndSlider.value()]['ENDFREQ']

        self.timeLabel = QLabel("Time cell")
        self.startTimeLabel = QLabel(
            "S: " + str(self.parent.parent.convertDate(self.start_time)))
        self.endTimeLabel = QLabel(
            "E: " + str(self.parent.parent.convertDate(self.end_time)))
        self.startTimeLabel.show()
        self.endTimeLabel.show()
        self.freqLabel = QLabel("Freq cell")
        self.startFreqLabel = QLabel("S: " + str(self.start_freq) + " Hz")
        self.endFreqLabel = QLabel("E: " + str(self.end_freq) + " Hz")
        self.startFreqLabel.show()
        self.endFreqLabel.show()

        self.closeButton = QPushButton()
        self.closeButton = QPushButton()
        self.closeButton.setText('Close')
        self.closeButton.setToolTip('close this plotcorrmatrix window')
        self.closeButton.setMaximumWidth(120)
        self.closeButton.show()

        self.prevButton = QPushButton("Prev")
        self.nextButton = QPushButton("Next")

    def createLayouts(self):
        self.buttonLayout = QVBoxLayout()  # layout containing widgets
        self.matrixLayout = QVBoxLayout(
        )  # layout containing canvas and toolbar
        self.mainLayout = QHBoxLayout()
        self.buttonLayout.addWidget(self.timeLabel)
        self.buttonLayout.addWidget(self.startTimeLabel)
        self.buttonLayout.addWidget(self.endTimeLabel)
        self.buttonLayout.addWidget(self.freqLabel)
        self.buttonLayout.addWidget(self.startFreqLabel)
        self.buttonLayout.addWidget(self.endFreqLabel)

        self.prevNextLayout = QHBoxLayout()
        if self.parent.parent.xAxisType != "Iteration":  # we don't support previous and next in iteration mode
            self.prevNextLayout.addWidget(self.prevButton)
            self.prevNextLayout.addWidget(self.nextButton)
            self.buttonLayout.addLayout(self.prevNextLayout)
        self.buttonLayout.insertStretch(-1)
        self.buttonLayout.addWidget(self.closeButton)

        self.matrixLayout.addWidget(self.canvas)
        self.matrixLayout.addWidget(self.mpl_toolbar)
        self.mainLayout.addLayout(self.buttonLayout)
        self.mainLayout.addLayout(self.matrixLayout)

        self.setLayout(self.mainLayout)

    def connectSignals(self):
        self.connect(self.closeButton, SIGNAL('clicked()'), SLOT('close()'))
        self.connect(self.prevButton, SIGNAL('clicked()'), self.on_prevButton)
        self.connect(self.nextButton, SIGNAL('clicked()'), self.on_nextButton)
        self.connect(self.prevButton, SIGNAL('clicked()'),
                     self.retrieveCorrMatrix)
        self.connect(self.nextButton, SIGNAL('clicked()'),
                     self.retrieveCorrMatrix)

    #*********************************************
    #
    # Handler functions for events
    #
    #*********************************************

    def on_prevButton(self):
        self.index = self.index - 1
        if self.index == 0:
            self.prevButton.setDisabled(True)

    def on_nextButton(self):
        self.index = self.index + 1
        if self.index > 0 and self.index < len(self.parent.x) - 1:
            self.prevButton.setEnabled(True)
        if self.index == len(self.parent.x) - 1:
            self.nextButton.setDisabled(True)

    def retrieveCorrMatrix(self):
        if self.parent.parent.xAxisType == "Time":
            self.start_time = self.parent.parent.solverQuery.timeSlots[
                self.index]['STARTTIME']
            self.end_time = self.parent.parent.solverQuery.timeSlots[
                self.index]['ENDTIME']
            self.start_freq = self.parent.parent.solverQuery.frequencies[
                self.parent.parent.frequencyStartSlider.value()]['STARTFREQ']
            self.end_freq = self.parent.parent.solverQuery.frequencies[
                self.parent.parent.frequencyEndSlider.value()]['ENDFREQ']
        elif self.parent.parent.xAxisType == "Freq":
            self.start_freq = self.parent.parent.solverQuery.frequencySlots[
                self.index]['STARTFREQ']
            self.end_freq = self.parent.parent.solverQuery.frequencylots[
                self.index]['ENDFREQ']
            self.start_time = self.parent.parent.solverQuery.frequencies[
                self.parent.parent.timeStartSlider.value()]['STARTTIME']
            self.end_time = self.parent.solverQuery.frequencies[
                self.parent.parent.timeEndSlider.value()]['ENDTIME']
        else:  # Iteration
            # Do nothing? Because there is only one Corrmatrix per solution but not per iteration!?
            print(
                "plotcorrmatrix::retrieveCorrMatrix() can't step forward or backward in per iteration mode"
            )
            return
            self.start_time = self.parent.parent.solverQuery.timeSlots[
                self.parent.parent.timeStartSlider.value()]['STARTTIME']
            self.end_time = self.parent.parent.solverQuery.timeSlots[
                self.parent.parent.timeEndSlider.value()]['ENDTIME']
            self.start_freq = self.parent.parent.solverQuery.frequencies[
                self.parent.parent.frequencyStartSlider.value()]['STARTFREQ']
            self.end_freq = self.parent.parent.solverQuery.frequencies[
                self.parent.parent.frequencyEndSlider.value()]['ENDFREQ']

        print("plotcorrmatrix::retrieveCorrMatrix()")  # DEBUG
        print("plotwindow::plotcorrmatri() start_time = ",
              self.start_time)  # DEBUG
        print("plotwindow::plotcorrmatri() end_time = ",
              self.end_time)  # DEBUG
        print("plotwindow::plotcorrmatri() start_freq = ",
              self.start_freq)  # DEBUG
        print("plotwindow::plotcorrmatri() end_freq = ",
              self.end_freq)  # DEBUG

        self.corrmatrix = self.parent.parent.solverQuery.getCorrMatrix(
            self.start_time, self.end_time, self.start_freq, self.end_freq)
        self.updateLabels()
        self.plot(self.corrmatrix)

    def updateLabels(self):
        self.startTimeLabel.setText(
            "S: " + str(self.parent.parent.convertDate(self.start_time)))
        self.endTimeLabel.setText(
            "E: " + str(self.parent.parent.convertDate(self.end_time)))
        self.startFreqLabel.setText("S: " + str(self.start_freq) + " Hz")
        self.endFreqLabel.setText("E: " + str(self.end_freq) + " Hz")

    #*********************************************
    #
    # Plot a correlation matrix in a plotWindow
    #
    #*********************************************
    #
    # corrmatrix      - numpy.ndarray holding (linearized) correlation Matrix
    #
    def plot(self, corrmatrix):
        print("plotCorrmatrix::plotCorrMatrix()")  # DEBUG

        # We plot into the existing canvas object of the PlotWindow class
        rank = self.parent.parent.solverQuery.getRank()

        if rank != math.sqrt(len(corrmatrix)):
            raise ValueError

        shape = corrmatrix.shape  # get shape of array (might be 1-D)
        corrmatrix = np.reshape(corrmatrix, (rank, rank))
        if len(shape) == 1:  # if we got only one dimension...
            if shape[0] != rank * rank:  # if the length of the array is not rank^2
                raise ValueError
            else:
                corrmatrix = np.reshape(corrmatrix, (rank, rank))
        elif len(shape) == 2:  # we already have a two-dimensional array
            print("shape[0] = ", shape[0], "   shape[1] = ", shape[1])  # DEBUG
            if shape[0] != rank or shape[1] != rank:
                raise ValueError

        # Clear all axes, and clear figure (needed to remove colorbar)
        self.ax.cla()
        self.fig.clf()
        self.ax = self.fig.add_subplot(111)  # create axes again in figure
        # plot CorrMatrix as a figure image
        self.img = self.ax.imshow(corrmatrix,
                                  cmap=cm.jet,
                                  aspect='equal',
                                  interpolation=None)
        self.colorbar = self.fig.colorbar(self.img)
        self.canvas.draw()
コード例 #11
0
    def rebuild_widget(self, number_of_plots, plot_stretching):

        self.__number_of_plots = number_of_plots
        self.__plot_stretching = plot_stretching

        ids = []
        if self.__top_vbox.count() < self.__number_of_plots:
            ids = range(self.__top_vbox.count(), self.__number_of_plots)

        for i in ids:

            label = QLabel()
            label.setFont(self.__font)
            label.setAlignment(Qt.AlignCenter)

            # Create the mpl Figure and FigCanvas objects. 
            # 5x4 inches, 100 dots-per-inch
            #
            #dpi = 100
            #self.fig = Figure((5.0, 4.0), dpi=self.dpi)
            fig = pyplot.figure()
            canvas = FigureCanvas(fig)
            canvas.setParent(self)
    
            # Since we have only one plot, we can use add_axes 
            # instead of add_subplot, but then the subplot
            # configuration tool in the navigation toolbar wouldn't
            # work.
            #
            axes = fig.add_subplot(111)
    
            # Create the navigation toolbar, tied to the canvas
            #
            mpl_toolbar = NavigationToolbar(canvas, self, False)
    
            if self.__show_toolbar:
                mpl_toolbar.show()
            else:
                mpl_toolbar.hide()

            # Other GUI controls
            #
    
            tmp_vbox = QVBoxLayout()
            tmp_vbox.addWidget(label)
            tmp_vbox.addWidget(canvas, 1)
            tmp_vbox.addWidget(mpl_toolbar)

            widget = QWidget()
            widget.setLayout(tmp_vbox)

            self.__plots.append((label, canvas, fig, axes, mpl_toolbar, widget))

            self.__plot_infos.append((self.PLOT_TYPE_NONE, '', None, {}))

            self.__top_vbox.addWidget(widget)

        for i in xrange(self.__number_of_plots):

            stretch = 0
            if plot_stretching != None:
                stretch = plot_stretching[i]
                self.__top_vbox.setStretch(i, stretch)
            else:
                self.__top_vbox.setStretch(i, 1)

            plot = self.__plots[i]
            label, canvas, fig, axes, mpl_toolbar, widget = plot
            widget.show()

        for i in xrange(self.__number_of_plots, self.__top_vbox.count()):

            plot = self.__plots[i]
            label, canvas, fig, axes, mpl_toolbar, widget = plot
            widget.hide()

        if self.__show_menu:
            menubar = QMenuBar()
            save_menu = menubar.addMenu("&Save")
    
            menu_items = []
            for i,plot_info in enumerate(self.__plot_infos):
                plot_caption = plot_info[1]
                menu_name = "Save &plot '%s' [%d]" % (plot_caption, i+1)
                if len(plot_caption) == 0:
                    menu_name = "Save &plot #%d" % (i+1)
                save_plot_action = self.__make_action(menu_name,
                                                     shortcut="Ctrl+P",
                                                     slot=functools.partial(self.on_save_plot, i))
                menu_items.append(save_plot_action)
            menu_items.append(None)
            save_all_action = self.__make_action("Save &all plots",
                shortcut="Ctrl+A", slot=self.on_save_all_plots)
            menu_items.append(save_all_action)
    
            self.__add_actions(save_menu, menu_items)
    
            self.layout().setMenuBar(menubar)
コード例 #12
0
class PlotWindow(QFrame):

    # Init the class: create plot window and canvas layout (and corresponding buttons)
    #
    def __init__(self, parent):
        QDialog.__init__(self)

        self.rim = 0.05  # rim around plot

        # The plot class holds its data now, so that it can be exported after a different
        # PlotWindow has been created
        self.parent = parent  # parent object/class
        self.fig = None
        self.showCursor = False
        self.cursorId = None
        self.markerId = None
        self.marker1 = None  # position marker in the plot
        self.marker2 = None

        self.x = parent.x  # plotted x axis data
        self.x0 = self.parent.solverQuery.getTimeSlots()[0]['STARTTIME']
        self.y1 = parent.y1  # plotted y axis data
        self.y2 = parent.y2  # plotted y2 axis data
        self.xdata = None  # cursor click x coordinate in data value
        self.ydata = None  # cursor click y coordinate in data value
        self.messages = parent.messages  # solver messages

        # Create canvas for plotting
        self.fig = Figure((5, 4), dpi=100)
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setParent(self)
        self.fig.subplots_adjust(left=self.rim + 0.05,
                                 right=1.0 - self.rim,
                                 top=1.0 - self.rim,
                                 bottom=self.rim)  # set a small rim

        self.mpl_toolbar = NavigationToolbar(self.canvas, self)
        self.mpl_toolbar.show()  # first hide the toolbar

        self.setMinimumWidth(900)
        self.setMinimumHeight(600)

        self.setWindowTitle = self.parent.tableName + ": " + str(
            self.parent.solverQuery.getRank()) + " Parameters"
        self.createWidgets()
        self.createConnections()
        self.createLayouts()

    def createWidgets(self):
        # Create Buttons for data export
        #
        self.exportButton = QPushButton("&Export Data")
        self.exportButton.setToolTip("Export the currently plotted data")
        self.exportButton.setMaximumWidth(100)

        self.exportComboBox = QComboBox()
        self.exportComboBox.addItem("ASCII")
        # export in Matlab format is only possible if scipy.io module has been imported
        if self.parent.haveModule('scipy') == True or self.parent.haveModule(
                'scipy.io') == True:
            self.exportComboBox.addItem("Matlab")
        self.exportComboBox.setToolTip('File format for exporting data')
        self.exportComboBox.setMaximumWidth(100)
        self.exportComboBox.setMinimumHeight(25)

        self.showCursorCheckBox = QCheckBox("Show cursor")
        self.showCursorCheckBox.setToolTip("Show a marker line in plot")
        self.showCursorCheckBox.setCheckState(Qt.Unchecked)  # default off

        self.histogramButton = QPushButton(
            "&Histogram")  # button to create a histogram
        self.histogramButton.setToolTip(
            "Create a histogram of the current parameter")
        self.histogramButton.setMaximumWidth(150)
        self.histogramButton.setToolTip('Create a histogram of current data')

        self.onClickLabel = QLabel("On click display:")
        self.onClickComboBox = QComboBox()
        self.onClickComboBox.setMaximumWidth(150)
        self.onClickComboBox.setToolTip(
            'What to display when data point in graph is clicked')
        self.onClickComboBox.addItem(
            "CorrMatrix")  # first, default = correlation matrix
        self.onClickComboBox.addItem("Zoom")
        #self.onClickComboBox.addItem("Per iteration")
        #self.onClickComboBox.addItem("CorrMatrix and Iterations")

        self.solverMessageLabel = QLabel("Solver Message:")

        self.solverMessageText = QLineEdit()
        self.solverMessageText.setText('Undefined')
        self.solverMessageText.setToolTip(
            'Message returned by LSQFit after iteration')
        self.solverMessageText.setReadOnly(True)
        self.solverMessageText.setMaximumWidth(125)

        self.closeButton = QPushButton()
        self.closeButton.setText('Close')
        self.closeButton.setToolTip('close this plot window')
        self.closeButton.setMaximumWidth(120)

    def createConnections(self):
        # Set connections
        self.connect(self.exportButton, SIGNAL('clicked()'), self.on_export)
        self.connect(self.histogramButton, SIGNAL('clicked()'),
                     self.on_histogram)
        self.connect(self.closeButton, SIGNAL('clicked()'), SLOT('close()'))
        self.connect(self.showCursorCheckBox, SIGNAL('stateChanged(int)'),
                     self.on_cursor)
        self.connect(self.onClickComboBox, SIGNAL('valueChanged(int)'),
                     self.on_onClickComboBox)

    # Layouts for canvas and buttons
    #
    def createLayouts(self):
        buttonLayout = QVBoxLayout()
        buttonLayout.addWidget(self.exportButton)
        buttonLayout.addWidget(self.exportComboBox)
        buttonLayout.addWidget(self.showCursorCheckBox)
        buttonLayout.addWidget(self.histogramButton)
        buttonLayout.addWidget(self.onClickComboBox)
        buttonLayout.addWidget(self.solverMessageLabel)
        buttonLayout.addWidget(self.solverMessageText)
        buttonLayout.insertStretch(-1)
        buttonLayout.addWidget(self.closeButton)
        #buttonLayout.insertStretch(-1)
        #buttonLayout.setMaximumWidth(160)

        # Canvas layout
        canvasLayout = QVBoxLayout()
        canvasLayout.addWidget(self.canvas, 1)
        canvasLayout.addWidget(self.mpl_toolbar)

        mainLayout = QHBoxLayout()
        mainLayout.addLayout(buttonLayout)
        mainLayout.addLayout(canvasLayout)
        self.setLayout(mainLayout)

        self.show()  # show the plotWindow widget
        self.parent.setXLabel()
        self.parent.setYLabel()

        # Matplotlib event connections
        #if self.showMarker==True:
        #  cid = self.fig.canvas.mpl_connect('motion_notify_event', self.update_marker)
        #  cid = self.fig.canvas.mpl_connect('button_press_event', onclick)

        cid = self.fig.canvas.mpl_connect(
            'motion_notify_event',
            self.on_solverMessage)  # TODO: this doesn work
        self.cursorId = self.fig.canvas.mpl_connect('button_press_event',
                                                    self.on_click)
        self.plot()

    # React on showMarkerCheckBox signal
    #
    """
   def on_marker(self):
      #print "on_marker checkState = ", self.showMarkerCheckBox.checkState()  # DEBUG
      if self.showMarkerCheckBox.isChecked()==True:
        self.showMarker=True
        self.markerId = self.fig.canvas.mpl_connect('motion_notify_event', self.update_marker)
      else:
        print "on_marker() disconnecting marker event"
        self.showMarker=False
        self.fig.canvas.mpl_disconnect(self.markerId)

   # Plot a vertical line marker on the solutions plot showing the solution
   # of the currently plotted solver parameters
   # TODO: EXPERIMENTAL
   #
   def update_marker(self, event):
      #print "plotMarker() pos = ", event.xdata       # DEBUG
      
      #print 'button=%d, x=%d, y=%d, xdata=%f, ydata=%f'%(
      #   event.button, event.x, event.y, event.xdata, event.ydata)     # DEBUG      
      
      # Create markers (vertical lines) in both plots
      self.marker1=self.ax1.axvline(x=event.xdata, linewidth=1.5, color='r')
      self.marker2=self.ax2.axvline(x=event.xdata, linewidth=1.5, color='r')
 
      # We need to remove all unnecessary marker in plot 1 and plot 2
      # TODO: find better method, keeps double marker sometimes
      while len(self.ax1.lines)-1 > 1:
        self.ax1.lines[len(self.ax1.lines)-1].remove()
      while len(self.ax2.lines)-1 > 1:
        self.ax2.lines[len(self.ax1.lines)-1].remove()  
       
      self.marker1=self.ax1.axvline(x=event.xdata, linewidth=1.5, color='r')
      self.marker2=self.ax1.axvline(x=event.xdata, linewidth=1.5, color='r')
#      self.canvas.draw_idle()
      self.canvas.draw()
   """

    def plotcorrmatrix(self):
        print("plotcorrmatrix()")  # DEBUG

        #print "self.parent.xAxisType = ", self.parent.xAxisType   # DEBUG

        indx = np.searchsorted(self.x, [self.xdata])[0]
        if self.parent.xAxisType == "Time":
            start_time = self.parent.solverQuery.timeSlots[indx]['STARTTIME']
            end_time = self.parent.solverQuery.timeSlots[indx]['ENDTIME']
            start_freq = self.parent.solverQuery.frequencies[
                self.parent.frequencyStartSlider.value()]['STARTFREQ']
            end_freq = self.parent.solverQuery.frequencies[
                self.parent.frequencyEndSlider.value()]['ENDFREQ']
        elif self.parent.xAxisType == "Freq":
            start_freq = self.parent.solverQuery.frequencySlots[indx][
                'STARTFREQ']
            end_freq = self.parent.solverQuery.frequencylots[indx]['ENDFREQ']
            start_time = self.parent.solverQuery.frequencies[
                self.parent.timeStartSlider.value()]['STARTTIME']
            end_time = self.parent.solverQuery.frequencies[
                self.parent.timeEndSlider.value()]['ENDTIME']
        else:  # Iteration
            start_time = self.parent.solverQuery.timeSlots[
                self.parent.timeStartSlider.value()]['STARTTIME']
            end_time = self.parent.solverQuery.timeSlots[
                self.parent.timeEndSlider.value()]['ENDTIME']
            start_freq = self.parent.solverQuery.frequencies[
                self.parent.frequencyStartSlider.value()]['STARTFREQ']
            end_freq = self.parent.solverQuery.frequencies[
                self.parent.frequencyEndSlider.value()]['ENDFREQ']

        #print "plotwindow::plotcorrmatri() start_time = ", start_time     # DEBUG
        #print "plotwindow::plotcorrmatri() end_time = ", end_time         # DEBUG
        #print "plotwindow::plotcorrmatri() start_freq = ", start_freq     # DEBUG
        #print "plotwindow::plotcorrmatri() end_freq = ", end_freq         # DEBUG

        corrMatrix = self.parent.solverQuery.getCorrMatrix(
            start_time, end_time, start_freq, end_freq)

        self.corrmatrixDialog = pc.plotCorrmatrix(self, corrMatrix)
        self.corrmatrixDialog.show()

    # Activate / Deactivate Matplotlib demo cursor
    #
    def on_cursor(self):
        print("on_cursor()")  # DEBUG
        self.showCursor = self.showCursorCheckBox.isChecked()

        print("on_cursor() self.showCursor = ", self.showCursor)

        if self.showCursor == True:
            self.cursor = Cursor(self.ax1, self)
            #self.cursor = SnaptoCursor(self.ax1, self.x, self.y1, self)
            self.fig.canvas.mpl_connect('motion_notify_event',
                                        self.cursor.mouse_move)
        else:
            self.cursor.lx.remove()
            self.cursor.ly.remove()
            self.fig.canvas.mpl_disconnect(self.cursorId)

    # Handle export button clicked()
    #
    def on_export(self):
        fileformat = self.exportComboBox.currentText()
        self.parent.on_export(fileformat)

    # TODO!
    def on_logarithmic(self):
        self.yscale('log')

    # Functio to execute on a click event (experimental)
    #
    def on_click(self, event):
        print('button=%d, x=%d, y=%d, xdata=%f, ydata=%f' %
              (event.button, event.x, event.y, event.xdata,
               event.ydata))  # DEBUG

        print("event.key = ", event.key)  # DEBUG

        self.xdata = event.xdata
        self.ydata = event.ydata

        # Depending on the setting in the onClickComboBox launch appropriate dialog
        #
        if self.onClickComboBox.currentText(
        ) == "CorrMatrix":  # if CorrMatrix should be displayed
            # Pick per iteration details if possible
            if self.parent.tableType == "PERSOLUTION_CORRMATRIX" or self.parent.tableType == "PERITERATION_CORRMATRIX":
                self.plotcorrmatrix()
            else:
                print("on_clickMarker() table is not of correct type")
        elif self.onClickComboBox.currentText() == "Per iteration":
            print(
                "plotwindow::on_click() trying to launch per iteration plotwindow"
            )

    # Display a histogram of the converged solutions (i.e. LASTITER=TRUE)
    # for the currently selected parameter
    #
    def on_histogram(self):
        self.histoDialog = ph.plothistogram(self)
        self.histoDialog.show()

    def on_onClickComboBox(self):
        print("on_onClickComboBox()")  # DEBUG
        if self.onClickComboBox.currentText() == "Zoom":
            self.fig.canvas.mpl_disconnect(self.cursorId)
        elif self.onClickComboBox.currentText() == "CorrMatrix":
            self.cursorId = self.fig.canvas.mpl_connect(
                'button_press_event', self.on_click)
        elif self.onClickComboBox.currentText() == "Per iteration":
            self.cursorId = self.fig.canvas.mpl_connect(
                'button_press_event', self.on_click)

    def on_solverMessage(self, event):
        if self.messages != None:  # only if we indeed inherited messages from parent
            self.xdata = event.xdata
            self.ydata = event.ydata  # get cursor position from figure

            index = np.searchsorted(
                self.x, [self.xdata
                         ])[0]  # get Message for the index of cursor position
            resultType = self.messages['result']

            #print "resultType = ", resultType
            #print "len(self.messages) = ", len(self.messages['last'])
            #print "self.xdata = ", self.xdata
            #print "on_solverMessage() index = ", index
            #print "self.messages[index] = ", self.messages[resultType][index]

            #print "self.parent.messages = ", self.parent.messages
            #self.solverMessageText.setText(self.messages[resultType][index])

            self.solverMessageText.setReadOnly(False)  # make it writable

            #print "resultType =", resultType    # DEBUG
            if resultType == "last":
                #self.solverMessageText.setText(self.messages[resultType][index])
                self.solverMessageText.setText(self.messages[index])
            elif resultType == "all":
                #self.solverMessageText.setText(self.messages[resultType][index])
                self.solverMessageText.setText(self.messages[index])
            elif resultType == None:
                print("on_solverMessage() None messages")
                return
            self.solverMessageText.setReadOnly(
                True)  # make it readonly again that user can't mess with it

    # Plot data that has been read
    #
    def plot(self):
        print("PlotWindow::plot()")  # DEBUG

        parm = self.parent.parmsComboBox.currentText(
        )  # Solution parameter, e.g. Gain:1:1:LBA001
        parameter = str(self.parent.parametersComboBox.currentText()
                        )  # Get solver parameter from drop down

        # Give for Time axis only time relative to start time
        # TODO this does not work
        if self.parent.xAxisType == "Time":
            self.x = self.parent.computeRelativeX()

        self.ax1 = self.fig.add_subplot(211)  # create solutions subplot
        # Set title and labels
        self.ax1.set_xlabel(self.parent.xLabel)
        self.ax1.set_ylabel(parm + ":" +
                            self.parent.parmValueComboBox.currentText())

        np.set_printoptions(precision=1)
        #      self.ax1.get_xaxis().set_visible(False)  # TODO: How to get correct x-axis ticks?
        np.set_printoptions(precision=2)  # does this work?

        if self.parent.perIteration == True:
            x = list(range(1,
                           len(self.y1) +
                           1))  # we want the first iteration to be called "1"
            if self.parent.scatterCheckBox.isChecked() == True:
                self.ax1.scatter(x, self.y1)
            else:
                self.ax1.plot(x, self.y1)
        else:
            if self.parent.scatterCheckBox.isChecked() == True:
                self.ax1.scatter(self.x, self.y1)
            else:
                if len(self.y1) == 1 or isinstance(self.y1, float):
                    self.ax1.scatter(self.x, self.y1)
                else:
                    self.ax1.plot(self.x, self.y1)

        # Solver log plot
        self.ax2 = self.fig.add_subplot(
            212, sharex=self.ax1)  # sharex for common zoom
        # Set labels
        #self.ax2.set_xticklabels(self.ax1.get_xticklabels(), visible=True)
        self.ax2.set_ylabel(self.parent.parametersComboBox.currentText())
        if self.parent.perIteration == True:
            x = list(range(1, len(self.y2) + 1))
            if self.parent.scatterCheckBox.isChecked() == True:
                self.ax2.scatter(x, self.y2)
            else:
                self.ax2.plot(
                    x, self.y2
                )  # have to increase lower y limit (for unknown reason)
        else:
            if self.parent.scatterCheckBox.isChecked() == True:
                self.ax2.scatter(self.x, self.y2)
            else:
                if len(self.y1) == 1 or isinstance(self.y2, float):
                    self.ax2.scatter(self.x, self.y2)
                else:
                    self.ax2.plot(self.x, self.y2)

        self.fig.canvas.draw()
コード例 #13
0
ファイル: plotcorrmatrix.py プロジェクト: jjdmol/LOFAR
class plotCorrmatrix(QDialog):
   def __init__(self, parent, corrmatrix):
     QFrame.__init__(self)
    
     self.setWindowTitle("Correlation Matrix")
     
     self.corrmatrix=[[]]
     self.rank=None
     self.rim=0.05
  
     self.parent=parent            # parent object/class
     self.fig=None
  
     # Create canvas for plotting
     self.fig = Figure((7, 7), dpi=100)
     self.canvas = FigureCanvas(self.fig)
     self.canvas.setParent(self)
     self.fig.subplots_adjust(left=self.rim, right=1.0-self.rim, top=1.0-self.rim, bottom=self.rim)  # set a small rim
     self.ax=self.fig.add_subplot(111)

     self.mpl_toolbar = NavigationToolbar(self.canvas, self)
     self.mpl_toolbar.show()
  
     self.setMinimumWidth(700)
     self.setMinimumHeight(700)
     self.corrmatrix=corrmatrix

     self.xLabel="Parameter index"
     self.yLabel="Parameter index"

     self.createWidgets()
     self.createLayouts()
     self.connectSignals()
     self.plot(self.corrmatrix)


   def createWidgets(self):
     # Get time indices (and frequency range) from solverdialog class according to plotwindow index
     self.index = np.searchsorted(self.parent.x, [self.parent.xdata])[0]
     
     print "self.index = ", self.index    # DEBUG
     
     self.start_time=self.parent.parent.solverQuery.timeSlots[self.index]['STARTTIME']
     self.end_time=self.parent.parent.solverQuery.timeSlots[self.index]['ENDTIME']      
     self.start_freq=self.parent.parent.solverQuery.frequencies[self.parent.parent.frequencyStartSlider.value()]['STARTFREQ']
     self.end_freq=self.parent.parent.solverQuery.frequencies[self.parent.parent.frequencyEndSlider.value()]['ENDFREQ']

      
     self.timeLabel=QLabel("Time cell")
     self.startTimeLabel=QLabel("S: " + str(self.parent.parent.convertDate(self.start_time)))
     self.endTimeLabel=QLabel("E: " + str(self.parent.parent.convertDate(self.end_time)))
     self.startTimeLabel.show()
     self.endTimeLabel.show()
     self.freqLabel=QLabel("Freq cell")
     self.startFreqLabel=QLabel("S: " + str(self.start_freq) + " Hz")
     self.endFreqLabel=QLabel("E: " + str(self.end_freq) + " Hz")
     self.startFreqLabel.show()
     self.endFreqLabel.show()

     self.closeButton=QPushButton()
     self.closeButton=QPushButton()
     self.closeButton.setText('Close')
     self.closeButton.setToolTip('close this plotcorrmatrix window')
     self.closeButton.setMaximumWidth(120)
     self.closeButton.show()

     self.prevButton=QPushButton("Prev")
     self.nextButton=QPushButton("Next")
      

   def createLayouts(self):
     self.buttonLayout=QVBoxLayout()                   # layout containing widgets
     self.matrixLayout=QVBoxLayout()                   # layout containing canvas and toolbar
     self.mainLayout=QHBoxLayout()
     self.buttonLayout.addWidget(self.timeLabel)
     self.buttonLayout.addWidget(self.startTimeLabel)
     self.buttonLayout.addWidget(self.endTimeLabel)
     self.buttonLayout.addWidget(self.freqLabel)
     self.buttonLayout.addWidget(self.startFreqLabel)
     self.buttonLayout.addWidget(self.endFreqLabel)
     
     self.prevNextLayout=QHBoxLayout()
     if self.parent.parent.xAxisType!="Iteration":         # we don't support previous and next in iteration mode
       self.prevNextLayout.addWidget(self.prevButton)
       self.prevNextLayout.addWidget(self.nextButton)
       self.buttonLayout.addLayout(self.prevNextLayout)
     self.buttonLayout.insertStretch(-1)
     self.buttonLayout.addWidget(self.closeButton)

     
     self.matrixLayout.addWidget(self.canvas)
     self.matrixLayout.addWidget(self.mpl_toolbar)
     self.mainLayout.addLayout(self.buttonLayout)
     self.mainLayout.addLayout(self.matrixLayout)

     self.setLayout(self.mainLayout)


   def connectSignals(self):
      self.connect(self.closeButton, SIGNAL('clicked()'), SLOT('close()'))
      self.connect(self.prevButton, SIGNAL('clicked()'), self.on_prevButton)
      self.connect(self.nextButton, SIGNAL('clicked()'), self.on_nextButton)
      self.connect(self.prevButton, SIGNAL('clicked()'), self.retrieveCorrMatrix)
      self.connect(self.nextButton, SIGNAL('clicked()'), self.retrieveCorrMatrix)
      
  
   #*********************************************
   #
   # Handler functions for events
   #
   #*********************************************

   def on_prevButton(self):
     self.index = self.index - 1
     if self.index == 0:
       self.prevButton.setDisabled(True)
  
   def on_nextButton(self):
     self.index = self.index + 1
     if self.index > 0 and self.index < len(self.parent.x)-1:
       self.prevButton.setEnabled(True)
     if self.index == len(self.parent.x)-1:
       self.nextButton.setDisabled(True)
     
   def retrieveCorrMatrix(self):
     if self.parent.parent.xAxisType=="Time":
       self.start_time=self.parent.parent.solverQuery.timeSlots[self.index]['STARTTIME']
       self.end_time=self.parent.parent.solverQuery.timeSlots[self.index]['ENDTIME']      
       self.start_freq=self.parent.parent.solverQuery.frequencies[self.parent.parent.frequencyStartSlider.value()]['STARTFREQ']
       self.end_freq=self.parent.parent.solverQuery.frequencies[self.parent.parent.frequencyEndSlider.value()]['ENDFREQ']
     elif self.parent.parent.xAxisType=="Freq":
       self.start_freq=self.parent.parent.solverQuery.frequencySlots[self.index]['STARTFREQ']
       self.end_freq=self.parent.parent.solverQuery.frequencylots[self.index]['ENDFREQ']      
       self.start_time=self.parent.parent.solverQuery.frequencies[self.parent.parent.timeStartSlider.value()]['STARTTIME']
       self.end_time=self.parent.solverQuery.frequencies[self.parent.parent.timeEndSlider.value()]['ENDTIME']
     else:     # Iteration
       # Do nothing? Because there is only one Corrmatrix per solution but not per iteration!?
       print "plotcorrmatrix::retrieveCorrMatrix() can't step forward or backward in per iteration mode"
       return
       self.start_time=self.parent.parent.solverQuery.timeSlots[self.parent.parent.timeStartSlider.value()]['STARTTIME']
       self.end_time=self.parent.parent.solverQuery.timeSlots[self.parent.parent.timeEndSlider.value()]['ENDTIME']      
       self.start_freq=self.parent.parent.solverQuery.frequencies[self.parent.parent.frequencyStartSlider.value()]['STARTFREQ']
       self.end_freq=self.parent.parent.solverQuery.frequencies[self.parent.parent.frequencyEndSlider.value()]['ENDFREQ']

     print "plotcorrmatrix::retrieveCorrMatrix()"                           # DEBUG
     print "plotwindow::plotcorrmatri() start_time = ", self.start_time     # DEBUG
     print "plotwindow::plotcorrmatri() end_time = ", self.end_time         # DEBUG
     print "plotwindow::plotcorrmatri() start_freq = ", self.start_freq     # DEBUG
     print "plotwindow::plotcorrmatri() end_freq = ", self.end_freq         # DEBUG

     self.corrmatrix=self.parent.parent.solverQuery.getCorrMatrix(self.start_time, self.end_time, self.start_freq, self.end_freq)
     self.updateLabels()
     self.plot(self.corrmatrix)

   def updateLabels(self):
     self.startTimeLabel.setText("S: " + str(self.parent.parent.convertDate(self.start_time)))
     self.endTimeLabel.setText("E: " + str(self.parent.parent.convertDate(self.end_time)))
     self.startFreqLabel.setText("S: " + str(self.start_freq) + " Hz")
     self.endFreqLabel.setText("E: " + str(self.end_freq) + " Hz")
     

   #*********************************************
   #
   # Plot a correlation matrix in a plotWindow
   #
   #*********************************************     
   #
   # corrmatrix      - numpy.ndarray holding (linearized) correlation Matrix
   #
   def plot(self, corrmatrix):
     print "plotCorrmatrix::plotCorrMatrix()"   # DEBUG
  
     # We plot into the existing canvas object of the PlotWindow class
     rank=self.parent.parent.solverQuery.getRank()
     
     if rank != math.sqrt(len(corrmatrix)):
       raise ValueError
    
     shape=corrmatrix.shape      # get shape of array (might be 1-D)
     corrmatrix=np.reshape(corrmatrix, (rank, rank))
     if len(shape)==1:                  # if we got only one dimension...
       if shape[0] != rank*rank:        # if the length of the array is not rank^2
         raise ValueError
       else:
         corrmatrix=np.reshape(corrmatrix, (rank, rank))
     elif len(shape)==2:              # we already have a two-dimensional array
       print "shape[0] = ", shape[0], "   shape[1] = ", shape[1]       # DEBUG
       if shape[0] != rank or shape[1] != rank:
         raise ValueError

     # Clear all axes, and clear figure (needed to remove colorbar)
     self.ax.cla()
     self.fig.clf()
     self.ax=self.fig.add_subplot(111)      # create axes again in figure
     # plot CorrMatrix as a figure image
     self.img=self.ax.imshow(corrmatrix, cmap=cm.jet , aspect='equal', interpolation=None)
     self.colorbar = self.fig.colorbar(self.img)
     self.canvas.draw()
コード例 #14
0
class MatplotlibWidget(QtGui.QWidget):
    """ This subclass of QtWidget will manage the widget drawing; name matches the class in the *_ui.py file"""    
 
    # Global colors dictionary
    colors_dict = {
        "Discharge": "b",
        "Subsurface Flow": "g",
        "Impervious Flow": "SteelBlue",
        "Infiltration Excess": "SeaGreen",
        "Initial Abstracted Flow": "MediumBlue",
        "Overland Flow": "RoyalBlue",
        "PET": "orange",
        "AET": "DarkOrange",
        "Average Soil Root zone": "Gray",
        "Average Soil Unsaturated Zone": "DarkGray",
        "Snow Pack": "PowderBlue",
        "Precipitation": "SkyBlue",
        "Storage Deficit": "Brown",
        "Return Flow": "Aqua",
        "Water Use": "DarkCyan",
        "Discharge + Water Use": "DarkBlue"
    }

    def __init__(self, parent = None):
        super(MatplotlibWidget, self).__init__(parent)

        # create object scope variables for watertxt data plot; used by radio buttons and span selector
        self.watertxt_data = None
        self.parameter = None
        self.color_str = None
        self.axes_text = None
        self.axes_radio = None
        self.parent = parent

        # create figure
        self.figure = Figure()

        # create canvas and set some of its properties
        self.canvas = FigureCanvas(self.figure)
        self.canvas.setParent(parent) 
        self.canvas.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
        self.canvas.updateGeometry()
        self.canvas.setFocusPolicy(QtCore.Qt.StrongFocus)
        self.canvas.setFocus()

        # set up axes and its properties
        self.ax = self.figure.add_subplot(111) 
        self.ax.grid(True)

        # create toolbar  
        self.matplotlib_toolbar = NavigationToolbar(self.canvas, parent) # the matplotlib toolbar object

        # create the layout
        self.layout = QtGui.QVBoxLayout()

        # add the widgets to the layout
        self.layout.addWidget(self.matplotlib_toolbar)
        self.layout.addWidget(self.canvas)

        # set the layout
        self.setLayout(self.layout)

    #-------------------------------- WATER.txt Parameter Plot ------------------------------------ 

    def setup_watertxt_plot(self):
        """ Setup the watertxt plot """

        self.clear_watertxt_plot()

        # set up axes and its properties
        self.axes = self.figure.add_subplot(111) 
        self.axes.grid(True)

        # create radio buttons
        self.axes_radio = self.figure.add_axes([0.01, 0.02, 0.10, 0.15])        # [left, bottom, width, height] = fractions of figure width and height
        self.figure.subplots_adjust(bottom=0.2)
        self.radio_buttons = RadioButtons(ax = self.axes_radio, labels = ("Span On", "Span Off"), active = 1, activecolor= "r")
        self.radio_buttons.on_clicked(self.toggle_selector)

        # create SpanSelector; invisble at first unless activated with toggle selector        
        self.span_selector = SpanSelector(self.axes, self.on_select_axes, 'horizontal', useblit = True, rectprops = dict(alpha=0.5, facecolor='red'))
        self.span_selector.visible = False

    def plot_watertxt_parameter(self, watertxt_data, name): 
        """ Plot a parameter from a WATER.txt file """

        self.reset_watertxt_plot()

        self.dates = watertxt_data["dates"]
        self.watertxt_data = watertxt_data
        self.parameter = watertxt.get_parameter(watertxt_data, name = name)     

        assert self.parameter is not None, "Parameter name {} is not in watertxt_data".format(name)

        self.axes.set_title("Parameter: {}".format(self.parameter["name"]))
        self.axes.set_xlabel("Date")
        ylabel = "\n".join(wrap(self.parameter["name"], 60))
        self.axes.set_ylabel(ylabel)

        # get proper color that corresponds to parameter name
        self.color_str = self.colors_dict[name.split('(')[0].strip()]

        # plot parameter    
        self.axes.plot(self.dates, self.parameter["data"], color = self.color_str, label = self.parameter["name"], linewidth = 2)   

        # legend; make it transparent    
        handles, labels = self.axes.get_legend_handles_labels()
        legend = self.axes.legend(handles, labels, fancybox = True)
        legend.get_frame().set_alpha(0.5)
        legend.draggable(state=True)

        # show text of mean, max, min values on graph; use matplotlib.patch.Patch properies and bbox
        text = "mean = {:.2f}\nmax = {:.2f}\nmin = {:.2f}".format(self.parameter["mean"], self.parameter["max"], self.parameter["min"])

        patch_properties = {"boxstyle": "round", "facecolor": "wheat", "alpha": 0.5}
                       
        self.axes_text = self.axes.text(0.05, 0.95, text, transform = self.axes.transAxes, fontsize = 14, 
                                        verticalalignment = "top", horizontalalignment = "left", bbox = patch_properties)    

        # use a more precise date string for the x axis locations in the toolbar and rotate labels
        self.axes.fmt_xdata = mdates.DateFormatter("%Y-%m-%d")

        # rotate and align the tick labels so they look better; note that self.figure.autofmt_xdate() does not work because of the radio button axes 
        for label in self.axes.get_xticklabels():
            label.set_ha("right")
            label.set_rotation(30)

        # draw the plot
        self.canvas.draw()

    def on_select_helper(self, xmin, xmax):
        """ Helper for on_select methods """

        # convert matplotlib float dates to a datetime format
        date_min = mdates.num2date(xmin)
        date_max = mdates.num2date(xmax) 

        # put the xmin and xmax in datetime format to compare
        date_min = datetime.datetime(date_min.year, date_min.month, date_min.day, date_min.hour, date_min.minute)    
        date_max = datetime.datetime(date_max.year, date_max.month, date_max.day, date_max.hour, date_max.minute)

        # find the indices that were selected    
        indices = np.where((self.dates >= date_min) & (self.dates <= date_max))
        indices = indices[0]
        
        # get the selected dates and values
        selected_dates = self.dates[indices]
        selected_values = self.parameter["data"][indices]

        # compute simple stats on selected values 
        selected_values_mean = nanmean(selected_values)
        selected_value_max = np.nanmax(selected_values)
        selected_value_min = np.nanmin(selected_values)

        return selected_dates, selected_values, selected_values_mean, selected_value_max, selected_value_min

    def on_select_axes(self, xmin, xmax):
        """ A select handler for SpanSelector that updates axes with the new x and y limits selected by user """

        selected_dates, selected_values, selected_values_mean, selected_value_max, selected_value_min = self.on_select_helper(xmin, xmax)

        # plot the selected values and update plots limits and text
        self.axes.plot(selected_dates, selected_values, self.color_str)
        self.axes.set_xlim(selected_dates[0], selected_dates[-1])
        self.axes.set_ylim(selected_values.min(), selected_values.max())

        text = 'mean = %.2f\nmax = %.2f\nmin = %.2f' % (selected_values_mean, selected_value_max, selected_value_min)           
        self.axes_text.set_text(text)

        # draw the updated plot
        self.canvas.draw() 

    def toggle_selector(self, radio_button_label):
        """ 
        A toggle radio buttons for the matplotlib SpanSelector widget.
        """ 

        if radio_button_label == "Span On":
            self.span_selector.visible = True
            self.matplotlib_toolbar.hide()

        elif radio_button_label == "Span Off":
            self.span_selector.visible = False
            self.matplotlib_toolbar.show()         
            self.plot_watertxt_parameter(watertxt_data = self.watertxt_data, name = self.parameter["name"])

    def clear_watertxt_plot(self):
        """ Clear the plot axes """ 

        self.figure.clear()
        self.canvas.draw()

    def reset_watertxt_plot(self):
        """ Clear the plot axes """ 

        self.axes.clear()
        self.canvas.draw()
        self.axes.grid(True)

    #-------------------------------- WATER.txt Parameter Comparison Plot ------------------------------------        

    def setup_watertxtcmp_plot(self):
        """ Setup the watertxt plot """

        self.clear_watertxtcmp_plot()

        # set up axes and its properties
        self.axes1 = self.figure.add_subplot(211)
        self.axes2 = self.figure.add_subplot(212, sharex = self.axes1)

        self.axes1.grid(True)
        self.axes2.grid(True)

    def plot_watertxtcmp_parameter(self, watertxt_data1, watertxt_data2, filename1, filename2, name): 
        """ Plot a parameter from a WATER.txt file """

        self.reset_watertxtcmp_plot()

        dates = watertxt_data1["dates"]

        parameter1 = watertxt.get_parameter(watertxt_data = watertxt_data1, name = name)     
        parameter2 = watertxt.get_parameter(watertxt_data = watertxt_data2, name = name)  

        assert parameter1 is not None, "Parameter name {} is not in watertxt_data".format(name)
        assert parameter2 is not None, "Parameter name {} is not in watertxt_data".format(name)

        # calculate the difference
        diff = parameter2["data"] - parameter1["data"]

        # plot parameters on axes1  
        self.axes1.plot(dates, parameter1["data"], color = "b", label = filename1 + ": " + parameter1["name"], linewidth = 2)   
        self.axes1.hold(True)
        self.axes1.plot(dates, parameter2["data"], color = "r", label = filename2 + ": " + parameter2["name"], linewidth = 2)   

        # plot the difference on axes2
        self.axes2.plot(dates, diff, color = "k", linewidth = 2)

        # add title, labels, legend
        self.axes1.set_title(parameter1["name"])

        self.axes2.set_xlabel("Date")
        self.axes2.set_ylabel("Difference")
 
        handles1, labels1 = self.axes1.get_legend_handles_labels()
        legend1 = self.axes1.legend(handles1, labels1, fancybox = True)
        legend1.get_frame().set_alpha(0.5)
        legend1.draggable(state=True)

        # show text of mean, max, min values on graph; use matplotlib.patch.Patch properies and bbox
        text1 = "mean = {:.2f}\nmax = {:.2f}\nmin = {:.2f}".format(parameter1["mean"], parameter1["max"], parameter1["min"])
        text2 = "mean = {:.2f}\nmax = {:.2f}\nmin = {:.2f}".format(parameter2["mean"], parameter2["max"], parameter2["min"])

        text_diff = "mean = {:.2f}\nmax = {:.2f}\nmin = {:.2f}".format(nanmean(diff), np.max(diff), np.min(diff))

        patch_properties1 = {"boxstyle": "round", "facecolor": "b", "alpha": 0.5}
        patch_properties2 = {"boxstyle": "round", "facecolor": "r", "alpha": 0.5}
        patch_properties_diff = {"boxstyle": "round", "facecolor": "wheat", "alpha": 0.5}
                       
        self.axes1.text(0.02, 0.95, text1, transform = self.axes1.transAxes, fontsize = 12, verticalalignment = "top", horizontalalignment = "left", bbox = patch_properties1)
        self.axes1.text(0.02, 0.45, text2, transform = self.axes1.transAxes, fontsize = 12, verticalalignment = "top", horizontalalignment = "left", bbox = patch_properties2)
        self.axes2.text(0.02, 0.95, text_diff, transform = self.axes2.transAxes, fontsize = 12, verticalalignment = "top", horizontalalignment = "left", bbox = patch_properties_diff)

        # use a more precise date string for the x axis locations in the toolbar and rotate labels
        self.axes2.fmt_xdata = mdates.DateFormatter("%Y-%m-%d")

        # rotate and align the tick labels so they look better
        self.figure.autofmt_xdate()

        # draw the plot
        self.canvas.draw()

    def clear_watertxtcmp_plot(self):
        """ Clear the plot axes """ 

        self.figure.clear()
        self.canvas.draw()

    def reset_watertxtcmp_plot(self):
        """ Clear the plot axes """ 

        self.axes1.clear()
        self.axes2.clear()
        self.canvas.draw()
        self.axes1.grid(True)
        self.axes2.grid(True)


    #-------------------------------- Basemap Plot ------------------------------------

    def setup_basemap_plot(self):
        """ Setup the watertxt plot """

        self.clear_basemap_plot()

        # set up axes and its properties
        self.basemap_axes = self.figure.add_subplot(111) 
        self.basemap_axes.grid(True)

    def get_map_extents(self, shapefiles, shp_name = None):
        """   
        Get max and min extent coordinates from a list of shapefiles to use as the 
        extents on the map. Use the map extents to calculate the map center and the 
        standard parallels.

        Parameters
        ----------
        shapefiles : list 
            List of shapefile_data dictionaries 
        shp_name : string
            String name of shapefile to use for getting map extents 

        Returns
        -------
        extent_coords : dictionary 
            Dictionary containing "lon_min", "lon_max", "lat_max", "lat_min" keys with respective calculated values
        center_coords : dictionary 
            Dictionary containing "lon", "lat" keys with respective calculated values
        standard_parallels : dictionary 
            Dictionary containing "first", "second" keys with respective calculated values (first = min(lat), second = max(lat))   
        """
        extent_coords = {}    
        center_coords = {}
        standard_parallels = {}

        lons = []
        lats = []

        if shp_name:
            for shapefile_data in shapefiles:            
                if shp_name in shapefile_data["name"].split("_")[0]:
                    lons.append(shapefile_data["extents"][0:2])
                    lats.append(shapefile_data["extents"][2:])
            
        else:
            for shapefile_data in shapefiles:
                lons.append(shapefile_data["extents"][0:2])
                lats.append(shapefile_data["extents"][2:])

        extent_coords["lon_min"] = np.min(lons)
        extent_coords["lon_max"] = np.max(lons)
        extent_coords["lat_min"] = np.min(lats)
        extent_coords["lat_max"] = np.max(lats)

        center_coords["lon"] = np.mean([extent_coords["lon_min"], extent_coords["lon_max"]])
        center_coords["lat"] = np.mean([extent_coords["lat_min"], extent_coords["lat_max"]])

        standard_parallels["first"] = extent_coords["lat_min"]
        standard_parallels["second"] = extent_coords["lat_max"]
            
        return extent_coords, center_coords, standard_parallels


    def plot_shapefiles_map(self, shapefiles, display_fields = [], colors = [], title = None, shp_name = None, buff = 1.0):
        """   
        Generate a map showing all the shapefiles in the shapefile_list.  
        Shapefiles should be in a Geographic Coordinate System (longitude and 
        latitude coordinates) such as World WGS84; Matplotlib"s basemap library 
        does the proper transformation to a projected coordinate system.  The projected
        coordinate system used is Albers Equal Area.
        
        Parameters
        ----------
        shapefiles : list 
            List of dictionaries containing shapefile information
        title : string 
            String title for plot
        display_fields : list 
            List of strings that correspond to a shapefile field where the corresponding value(s) will be displayed.
        colors : list
            List of strings that correspond to colors to be displayed
        shp_name : string
            String name of shapefile to use for getting map extents 
        buff : float
            Float value in coordinate degrees to buffer the map with
        """  

        self.setup_basemap_plot()

        extent_coords, center_coords, standard_parallels = self.get_map_extents(shapefiles, shp_name = shp_name)     

        # create the basemap object with Albers Equal Area Conic Projection
        bmap = Basemap(projection = "aea", 
                       llcrnrlon = extent_coords["lon_min"] - buff, llcrnrlat = extent_coords["lat_min"] - buff, 
                       urcrnrlon = extent_coords["lon_max"] + buff, urcrnrlat = extent_coords["lat_max"] + buff, 
                       lat_1 = standard_parallels["first"], lat_2 = standard_parallels["second"],
                       lon_0 = center_coords["lon"], lat_0 = center_coords["lat"],
                       resolution = "h", area_thresh = 10000, ax = self.basemap_axes)    
        
        # have basemap object plot background stuff
        bmap.drawcoastlines()
        bmap.drawcountries()
        bmap.drawrivers(linewidth = 1, color = "blue")
        bmap.drawstates()
        bmap.drawmapboundary(fill_color = "aqua")
        bmap.fillcontinents(color = "coral", lake_color = "aqua")
        bmap.drawparallels(np.arange(-80., 81., 1.), labels = [1, 0, 0, 0], linewidth = 0.5)
        bmap.drawmeridians(np.arange(-180., 181., 1.), labels = [0, 0, 0, 1], linewidth = 0.5)
         
        # plot each shapefile on the basemap    
        legend_handles = []
        legend_labels = []
        colors_index = 0
        colors_list = ["b", "g", "y", "r", "c", "y", "m", "orange", "aqua", "darksalmon", "gold", "k"]
        for shapefile_data in shapefiles:
            
            # set up colors to use
            if colors:
                color = colors[colors_index]        
            elif colors_index > len(colors_list) - 1:
                color = np.random.rand(3,)
            else:
                color = colors_list[colors_index]         
            
            full_path = os.path.join(shapefile_data["path"], shapefile_data["name"].split(".")[0])
            
            shp_tuple = bmap.readshapefile(full_path, "shp", drawbounds = False)                            # use basemap shapefile reader for ease of plotting
            for shape_dict, shape in zip(bmap.shp_info, bmap.shp):                                          # zip the shapefile information and its shape as defined by basemap

                if shapefile_data["type"] == "POLYGON":
                    p1 = Polygon(shape, facecolor = color, edgecolor = "k",
                                             linewidth = 1, alpha = 0.7, label = shapefile_data["name"])            
                    self.basemap_axes.add_patch(p1)
                    xx, yy = zip(*shape)
                    txt_x = str(np.mean(xx))
                    txt_y = str(np.mean(yy))
                    
                elif shapefile_data["type"] == "POINT":
                    x, y = shape

                    if "usgsgages" in shapefile_data["name"].split("_")[0]:
                        p1 = bmap.plot(x, y, color = color, marker = "^", markersize = 10, label = shapefile_data["name"])
                    elif "wateruse" in shapefile_data["name"].split("_")[0]:
                        p1 = bmap.plot(x, y, color = color, marker = "o", markersize = 5, label = shapefile_data["name"])
                    else:
                        print("what!!")
                        p1 = bmap.plot(x, y, color = color, marker = "o", markersize = 10, label = shapefile_data["name"])

                    txt_x = str(x)
                    txt_y = str(y)
                    
                else:
                    xx, yy = zip(*shape)
                    p1 = bmap.plot(xx, yy, linewidth = 1, color = color, label = shapefile_data["name"])
                    txt_x = str(np.mean(xx))
                    txt_y = str(np.mean(yy))
                
                
                if isinstance(p1, list):
                    p1 = p1[0]

                # control text display of shapefile fields
                for display_field in display_fields:
                    if display_field in shape_dict.keys():
                        self.basemap_axes.text(txt_x, txt_y, shape_dict[display_field], color = "k", fontsize = 12, fontweight = "bold")

            colors_index += 1    
            legend_handles.append(p1)    
            legend_labels.append(shapefile_data["name"].split("_")[0])

        handles, labels = self.basemap_axes.get_legend_handles_labels()
        
        # edit the contents of handles and labels to only show 1 legend per shape
        handles = legend_handles
        labels = legend_labels
        legend = self.basemap_axes.legend(handles, labels, fancybox = True, numpoints = 1)
        legend.get_frame().set_alpha(0.5)
        legend.draggable(state = True)

        # draw the plot
        self.canvas.draw()


    def clear_basemap_plot(self):
        """ Clear the plot axes """ 

        self.figure.clear()
        self.canvas.draw()

    def reset_basemap_plot(self):
        """ Clear the plot axes """ 

        self.basemap_axes.clear()
        self.canvas.draw()
コード例 #15
0
ファイル: matplot.py プロジェクト: emayssat/python-eggs
class LMatplotlibWidget(LWidget):

    def __init__(self, parent=None):
        super(LMatplotlibWidget, self).__init__(parent)
        self.setName(WIDGET_NAME)
        self.buildUi()
        self.dataContainer = LMyDataContainer(self)
        self.actions = LMyActions(self.dataContainer,self)
        self.setDebugLevel(5)
        self.updateUi()

    @LInAndOut(DEBUG & WIDGETS)
    def buildUi(self):
        self.verticalLayout = QVBoxLayout(self)
        self.figure = Figure()
        self.canvas = Canvas(self.figure)	                # <-- figure required
        self.navigationToolbar = NavigationToolbar(self.canvas, self)
        self.verticalLayout.addWidget(self.canvas)
        self.verticalLayout.addWidget(self.navigationToolbar)

        #Canvas.setSizePolicy(self.canvas, QSizePolicy.Expanding, QSizePolicy.Expanding)
        #Canvas.updateGeometry(self.canvas)

    @LInAndOut(DEBUG & WIDGETS)
    def updateUi(self):
        left = self.dataContainer.leftMargin
        bottom = self.dataContainer.bottomMargin
        right = self.dataContainer.rightMargin
        top = self.dataContainer.topMargin
        wspace = self.dataContainer.verticalSeparation
        hspace = self.dataContainer.horizontalSeparation
        self.figure.subplots_adjust(left, bottom, right, top, wspace, hspace)

        if self.dataContainer.showNavigationToolbar:
            self.navigationToolbar.show()
        else:
            self.navigationToolbar.hide()

    #----------------------------------------------------------------------
    # Interface (set)

    @LInAndOut(DEBUG & WIDGETS)
    def setOptions(self, options):
        super(LMatplotlibWidget, self).setOptions(options)
        if options.verboseLevel is not None:
            self.setVerboseLevel(options.verboseLevel)
        if options.navigationToolbar is not None:
            self.showNavigationToolbar(options.navigationToolbar)
        self.updateUi()

    @LInAndOut(DEBUG & WIDGETS)
    def setVerboseLevel(self, level):
        self.dataContainer.verboseLevel = level

    #----------------------------------------------------------------------
    # Interface (get)

    def getFigure(self):
        return self.figure

    #----------------------------------------------------------------------
    # Interface (misc)

    @LInAndOut(DEBUG & WIDGETS)
    def showNavigationToolbar(self, flag=True):
        self.dataContainer.showNavigationToolbar = flag
        self.updateUi()

    @LInAndOut(DEBUG & WIDGETS)
    def snapshot(self, fileName = None):
        if fileName is None:
            caption = "%s - Save File" % self.name
            filter = "PNG Image (*.png);;All files (*.*)"
            fileName = QFileDialog.getSaveFileName(self.parent(), caption=caption,filter=filter )
            fileName = "%s" % fileName
        if len(fileName) > 0:
            self.figure.savefig(fileName, facecolor='w', edgecolor='w', orientation='portrait', papertype=None, format=None, transparent=False, bbox_inches=None, pad_inches=0.1)

    @LInAndOut(DEBUG & WIDGETS)
    def draw(self):
        self.canvas.draw()
コード例 #16
0
class PlotWindow(QFrame):

    # Init the class: create plot window and canvas layout (and corresponding buttons)
    # Steps contains a dictionary of dictionaries with the identified steps
    #
    def __init__(self, parent):
        #QFrame.__init__(self)
        QMainWindow.__init__(self, None)
        self.setWindowTitle('BBS timing statistics')

        self.parent = parent  # Parent: BBSTiming class
        self.currentPlotStyle = "bar"  # current style of plot: bar, colorbar, lines
        self.plotStyles = ["bar", "colorbar",
                           "line"]  # supported plot styles                 #
        self.summation = False  # show "individual" execution times or "summation"

        self.fig = None  # figure
        self.axes = None  # plot axes

        self.create_main_frame()
        self.createWidgets()
        self.createLayouts()
        self.createConnections()

        self.setMinimumWidth(700)
        self.setMinimumHeight(400)

    # Create a main frame
    #
    def create_main_frame(self):
        self.main_frame = QWidget()
        self.dpi = 75
        self.setMinimumWidth(300)
        self.setMinimumHeight(300)

        # We want matplotlib export functionality, so include toolbar
        # MPL Canvas and Toolbar
        # Create canvas for plotting
        self.fig = Figure((5, 4), dpi=75)
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setParent(self)
        self.fig.subplots_adjust(left=0.1, right=0.96, top=0.94,
                                 bottom=0.06)  # set a small rim

        self.mpl_toolbar = NavigationToolbar(self.canvas, self)
        self.mpl_toolbar.show()  # first hide the toolbar

    # Create the layouts for the widgets
    #
    def createLayouts(self):
        # Layouts
        self.buttonLayout = QVBoxLayout()
        self.canvasLayout = QVBoxLayout()
        self.mainLayout = QHBoxLayout()

        # Add Widgets to the layout
        self.buttonLayout.addWidget(self.loadButton)
        self.buttonLayout.addWidget(self.quitButton)
        self.buttonLayout.insertStretch(-1)

        self.subStepsLayout = QHBoxLayout()
        self.subStepsLayout.addWidget(self.showSubstepsCheckBox)
        self.subStepsLayout.addWidget(self.showSubstepsLabel)
        self.buttonLayout.addLayout(self.subStepsLayout)
        self.showIndividualStepsLayout = QHBoxLayout()
        self.showIndividualStepsLayout.addWidget(self.showIndividualCheckBox)
        self.showIndividualStepsLayout.addWidget(self.showIndividualLabel)
        self.buttonLayout.addLayout(self.showIndividualStepsLayout)

        self.buttonLayout.addWidget(self.stepComboBox)
        #self.buttonLayout.addWidget(self.stepListView)
        self.buttonLayout.addWidget(self.substepComboBox)
        self.buttonLayout.addWidget(self.keywordComboBox)
        self.buttonLayout.addWidget(self.plotStyleComboBox)
        self.buttonLayout.addWidget(self.stepComboBox)
        self.buttonLayout.addWidget(self.plotButton)
        self.buttonLayout.insertStretch(-1)

        self.canvasLayout.addWidget(self.canvas)
        self.canvasLayout.addWidget(self.mpl_toolbar)

        self.mainLayout.addLayout(self.buttonLayout)
        self.mainLayout.addLayout(self.canvasLayout)
        self.setLayout(self.mainLayout)

    # Create GUI widgets
    #
    def createWidgets(self):
        #print "createWidgets()"             # DEBUG

        self.loadButton = QPushButton("Load logfile")
        self.loadButton.setToolTip('load a BBS kernellog file')
        self.loadButton.setMaximumWidth(200)
        self.quitButton = QPushButton("Quit")
        self.quitButton.setMaximumWidth(200)
        self.quitButton.setToolTip('Quit the application')
        self.quitButton.setMaximumWidth(200)
        self.plotButton = QPushButton("Plot")
        self.plotButton.setToolTip('force a replot')

        self.showSubstepsCheckBox = QCheckBox()
        self.showSubstepsLabel = QLabel("Show substeps")
        self.showSubstepsCheckBox.setToolTip("Show also substeps in timing")
        self.showSubstepsCheckBox.setCheckState(Qt.Unchecked)  # Default: False
        self.showSubstepsCheckBox.show()
        self.showSubstepsLabel.show()

        self.showIndividualCheckBox = QCheckBox()
        self.showIndividualLabel = QLabel("Numbered steps")
        self.showIndividualCheckBox.setToolTip(
            "Show individually numbered steps")
        self.showIndividualCheckBox.setCheckState(
            Qt.Unchecked)  # Default: False
        self.showIndividualCheckBox.show()
        self.showIndividualLabel.show()

        # GUI Widgets depending on log file
        self.createStepComboBox()  # Selector for Step
        self.createKeywordComboBox()  # Selector for: total, count, avg

        # Selector for plot type: bar, line, multibar
        self.createPlotstyleComboBox()
        self.createStepComboBox()
        #self.createStepListView()
        # This is now done in a function, too
        #      self.substepComboBox=QComboBox()    # we create this here once
        #      self.substepComboBox.hide()
        #      self.substepComboBox.setToolTip('Substeps of step')
        #      self.substepComboBox.setMaximumWidth(200)

        self.createSubbandComboBox()

    # Create the step combobox containing the timed steps
    # This should be a multi-selection box to plot multiple
    # steps
    #
    def createStepComboBox(self):
        #print "createStepComboBox()"     # DEBUG

        self.stepComboBox = QComboBox()
        for step in self.parent.timedSteps:
            self.stepComboBox.addItem(step)

        self.stepComboBox.addItem("all")
        self.stepComboBox.show()
        self.stepComboBox.setMaximumWidth(200)

    def createSubstepComboBox(self):
        print("createSubstepComboBox()")  # DEBUG

        self.substepComboBox = QComboBox()  # we create this here once
        self.substepComboBox.hide()
        self.substepComboBox.setToolTip('Substeps of step')
        self.substepComboBox.setMaximumWidth(200)

    # Fill step Checkbox with step names, either these are
    # grouped by their common name, or shown as individually
    # numbered steps
    #
    def fillSteps(self):
        print("fillSteps()")  # DEBUG

        self.stepComboBox.clear()
        # Decide if we want the steps grouped or individually numbered
        if self.showIndividualCheckBox.isChecked() == True:
            steps = self.parent.timedStepsCount
        else:
            steps = self.parent.timedSteps

        #print "fillSteps() steps = ", steps
        for step in steps:
            # Check if that substep is already in there, avoid duplicates
            if self.stepComboBox.findData(step) == -1:
                self.stepComboBox.addItem(step)
        self.stepComboBox.addItem(
            "all")  # we again have to add our "all" option

    # Get the corresponding substeps for a step
    #
    def fillSubsteps(self):
        print("fillSubsteps()")  # DEBUG

        # Get substeps for currently selected step (or all if "all")
        step = str(self.stepComboBox.currentText())

        self.substepComboBox.clear()  # first clear substeps comboBox
        if step != "all" and step != "ALL":
            substeps = self.parent.getSubsteps(step)

            #print "fillSubsteps() substeps = ", substeps    # DEBUG
            for substep in substeps:
                # Check if that substep is already in there, avoid duplicates
                if self.substepComboBox.findData(substep) == -1:
                    self.substepComboBox.addItem(substep)
        else:
            self.substepComboBox.clear()  # First remove existing substeps

            index = 0
            while index < self.stepComboBox.count():  # loop over all steps
                # TODO: Might not be supported to show substeps for ALL steps...
                #substeps=str(self.stepComboBox.itemText(index))
                #print "fillSubsteps() substeps = ", substeps

                #print "fillSubsteps() index = ", index, "maxCount = ", self.stepComboBox.count()
                step = str(self.stepComboBox.itemText(index))
                print("fillSubsteps() step = ", step)
                if step != "all" and step != "ALL":
                    substeps = self.parent.getSubsteps(step)

                    keys = list(substeps.keys())
                    #print "keys = ", keys
                    for j in range(len(substeps) - 1):
                        #print "fillSubsteps() substeps = ", substeps
                        substep = keys[j]
                        if substep != "all" and substep != "ALL":
                            self.substepComboBox.addItem(substep)
                        j = j + 1

                index = index + 1

            self.substepComboBox.addItem("ALL")  # we need to add an "ALL"

    """
   # Alternative view, displaying all the steps
   # in a list view that then can be selected for
   # plotting
   #
   def createStepListView(self):
      print "createStepListBox()"      # DEBUG
      
      self.stepListView=QListView()
      for step in self.parent.timedSteps:
         self.stepListView.insertStringList(step)
      self.stepListView.show()
      step.stepListView.setMaximumWidth(200)
   """

    # On timing combobox event
    #
    def createKeywordComboBox(self):
        print("createTimingComboBox()")  # DEBUG

        self.keywordComboBox = QComboBox()
        for key in self.parent.keywords:
            self.keywordComboBox.addItem(key)

        self.keywordComboBox.show()
        self.keywordComboBox.setMaximumWidth(200)

    # Create a comboBox offering different Matplotlib styles
    #
    def createPlotstyleComboBox(self):
        print("createPlotstyleComboBox()")  # DEBUG

        self.plotStyleComboBox = QComboBox()
        for style in self.plotStyles:
            self.plotStyleComboBox.addItem(style)

        self.plotStyleComboBox.show()
        self.plotStyleComboBox.setMaximumWidth(200)

    # Create subbands comboBox which allows selection of an individual subband
    # from a pipeline.log
    def createSubbandComboBox(self):
        print("createSubbandComboBox()")  # DEBUG

        self.subbandComboBox = QComboBox()
        for sub in self.parent.subbands:
            self.subbandComboBox.addItem(sub)

        self.subbandComboBox.show()
        self.subbandComboBox.setMaximumWidth(200)

    #**************************************
    #
    # Create connections
    #
    #**************************************

    def createConnections(self):
        print("createConnections()")  # DEBUG

        self.connect(self.loadButton, SIGNAL('clicked()'), self.on_loadfile)
        self.connect(self.quitButton, SIGNAL('clicked()'), self,
                     SLOT('close()'))

        self.connect(self.stepComboBox, SIGNAL('currentIndexChanged(int)'),
                     self.on_step)
        self.connect(self.stepComboBox, SIGNAL('currentIndexChanged(int)'),
                     self.on_showSubsteps)
        #self.connect(self.substepComboBox, SIGNAL('currentIndexChanged(int)'), self.on_step)
        self.connect(self.substepComboBox, SIGNAL('currentIndexChanged(int)'),
                     self.on_plot)
        self.connect(self.keywordComboBox, SIGNAL('currentIndexChanged(int)'),
                     self.on_keyword)
        self.connect(self.plotStyleComboBox,
                     SIGNAL('currentIndexChanged(int)'), self.on_plotStyle)
        self.connect(self.showSubstepsCheckBox, SIGNAL('stateChanged(int)'),
                     self.on_showSubsteps)
        self.connect(self.showIndividualCheckBox, SIGNAL('stateChanged(int)'),
                     self.on_individualSteps)
        self.connect(self.subbandComboBox, SIGNAL('currentIndexChanged(int)'),
                     self.on_subband)

        self.connect(self.plotButton, SIGNAL('clicked()'), self.on_plot)

    #**************************************
    #
    # Event handlers
    #
    #**************************************

    # Load Kernellog file dialog
    #
    def on_loadfile(self):
        #print "on_loadfile()"    # DEBUG

        # Customization: check if ~/Cluster/SolutionTests exists
        if os.path.exists('/Users/duscha/Desktop/'):
            setDir = QString('/Users/duscha/Desktop/')
        else:
            setDir = QString('')

        path = str(QFileDialog.getOpenFileName(self, 'Load Kernellog', setDir))
        path = str(
            path)  # Convert to string so that it can be used by load table

        if path:
            self.parent.readLogfile(path)
        else:
            print("load_table: invalid path")

    # On step combobox event
    #
    def on_step(self):
        print("on_step()")  # DEBUG
        #step=str(self.stepComboBox.currentText())
        self.on_plot()

    # On substep combobox event
    #
    def on_substep(self):
        print("on_substep()")  # DEBUG
        #step=str(self.stepComboBox.currentText())
        self.on_plot()

    # On toggle individual treatment of counted steps
    #
    def on_individualSteps(self):
        print("on_individualSteps()")  # DEBUG
        self.fillSteps()  # update steps combobox
        self.on_showSubsteps()  # also update substeps combobox
        #step=str(self.stepComboBox.currentText())
        self.on_plot()

    # On selection of different subbands
    #
    def on_subband(self):
        print("on_subband()")  # DEBUG
        self.fillSteps()  # update steps combobox
        self.on_showSubsteps()  # also update substeps combobox
        self.on_plot()

    # On toggling of show substeps
    #
    def on_showSubsteps(self):
        print("on_substeps()")  # DEBUG

        if self.showSubstepsCheckBox.isChecked() == True:
            self.showSubSteps = True
            self.substepComboBox.show()
            self.fillSubsteps()
        else:
            self.showSubSteps = False
            self.substepComboBox.hide()
            self.substepComboBox.clear()

    # On keyword combobox event
    #
    def on_keyword(self):
        print("on_keyword()")  # DEBUG
        self.on_plot()

    # On change of plot style
    #
    def on_plotStyle(self):
        print("on_plotStyle()")  # DEBUG

        self.plotStyle = self.plotStyleComboBox.currentText(
        )  # change class attribute

    # On plot button action
    #
    def on_plot(self):
        self.fig.clf()  # clear the figure

        print("on_plot()")

        step = str(self.stepComboBox.currentText())
        self.plot(step)
        """
      step=str(self.stepComboBox.currentText())
      # If we have all steps selected:
      if step=="ALL" or step=="all":
         for i in range(0, self.stepComboBox.count()):         # loop over all steps
            currentStep=self.stepComboBox.itemText(i)          # get the step name from QComboBox
            
            print "on_plot() currentStep = ", currentStep
            
            self.plot(currentStep)                             # plot it
      else:
         #print "foo"
         self.plot(step)                                       # replot with new plotstyle
      """

    # Replot diagram
    #
    def plot(self, step):
        print("plot()")  # DEBUG

        width = 0.25  # width of bar plots

        # Get the data according to GUI settings
        step = str(step)
        substep = str(self.substepComboBox.currentText())
        keyword = str(self.keywordComboBox.currentText())
        style = str(self.plotStyleComboBox.currentText())

        print("plot() step = ", step, "substep = ", substep, "keyword = ",
              keyword, "style = ", style)  # DEBUG

        self.axes = self.fig.add_subplot(111)  # add 1 subplot to the canvas
        result = []

        # TODO: plot all substeps if we get multiple in results
        if step == "all" or step == "ALL":
            if self.showIndividualCheckBox.isChecked():
                steps = self.parent.timedStepsCount
            else:
                steps = self.parent.timedSteps

            print("plot() steps = ", steps)  # DEBUG
            for i in range(0, len(steps)):
                #print "plot()", self.parent.getSubStepValue(str(steps[i]), substep, keyword)
                result.append(self.parent.getStepFinal(str(steps[i]), keyword))

                #print "len(result) = ", len(result)
                print("plot() result[" + str(i) + "] = " + str(result[i]))
                #self.axes.bar(i, result[i], width)

        # If we want to see all steps, but not for individual substeps
        elif step == "all" or step == "ALL" and (substep == None
                                                 or substep == ""):
            if self.showIndividualCheckBox.isChecked():
                steps = self.parent.getSubsteps(step, keyword)
            else:
                steps = self.parent.timedSteps
                print("steps = ", steps)
                #steps.append(self.parent.timedSteps)
                newsteps = []
                if isinstance(steps, list):
                    for i in range(0, len(steps)):  # overplot them in one plot
                        newsteps.append(steps[i])

                result = newsteps
        elif substep == "all" or substep == "ALL":
            print("plot(): substep=all")
            result = (self.parent.getSubStepValue(step, keyword))
        elif substep == None or substep == "":
            result = (self.parent.getStepFinal(step, keyword))
        else:
            result = (self.parent.getSubStepValue(step, substep, keyword))

        #if isinstance(result[0], list):
        #   result=self.linearizeList(result)

        if isinstance(result, list):
            print("plot() len(result) = ", len(result))  # DEBUG
            print("plot() result = ", result)  # DEBUG
            #print "plot() result[1] = ", result[1]           # DEBUG

        #
        # Plot on canvas
        #
        ind = []
        if isinstance(result, float) or isinstance(result, int):
            ind = 0
        elif isinstance(result, bool):
            print("plot() invalid result returned")
        else:
            maxInd = len(result)
            for i in range(0, maxInd):
                ind.append(width * 1.1 * i)

        # Decide on plotstyle which plotting to do
        if self.currentPlotStyle == "bar":
            print("ind = ", ind)  # DEBUG
            print("result = ", result)  # DEBUG
            rects1 = self.axes.bar(ind, result, width, color='r')

        elif self.currentPlotStyle == "colorbar":
            print("plot() colorbar")
        else:
            print("plot() lines")
            self.axes.scatter(0, result)

        #
        # Set axes labels according to selected keyword on y-axis and
        # for each plotted step/substep identifier on the x-axis
        #
        ylabel = str(self.keywordComboBox.currentText())
        if self.keywordComboBox.currentText(
        ) == "total" or self.keywordComboBox.currentText() == "avg":
            ylabel = ylabel + " s"
        self.axes.set_ylabel(ylabel)

        self.canvas.draw()

    #******************************************************
    #
    # Helper functions
    #
    #*******************************************************

    def linearizeList(self, reorderlist):
        print("linearizeList()")  # DEBUG

        newlist = []

        if isinstance(reorderlist, list):
            Nlists = len(reorderlist)
            for i in range(Nlists):
                if isinstance(reorderlist[i], list):
                    for j in len(reorderlist[i]):
                        newlist.append(reorderlist[i][j])
                else:
                    newlist.append(reorderlist[i])
        return newlist

    #******************************************************
    #
    # Update GUI Widgets on loading a new Kernellog file
    #
    #*******************************************************

    # Update the Kernel log dependent widgets, i.e. deleting
    # and recreating them
    #
    def updateWidgets(self):
        print("updateWidgets()")  # DEBUG

        self.deleteWidgets()
        self.createWidgets()

    # Delete GUI Widgets that are created dynamically from the log
    #
    def deleteWidgets(self):  # DEBUG
        print("deleteWidgets()")

        self.stepComboBox.deleteLater()
        self.keywordComboBox.deleteLater()
        self.plotstyleComboBox.deleteLater()
        self.stepComboBox.deleteLater()
コード例 #17
0
ファイル: BBStiming.py プロジェクト: kernsuite-debian/lofar
class PlotWindow(QFrame):

   # Init the class: create plot window and canvas layout (and corresponding buttons)
   # Steps contains a dictionary of dictionaries with the identified steps
   #
   def __init__(self, parent):
      #QFrame.__init__(self)
      QMainWindow.__init__(self, None)
      self.setWindowTitle('BBS timing statistics')
      
      self.parent=parent                 # Parent: BBSTiming class
      self.currentPlotStyle="bar"        # current style of plot: bar, colorbar, lines 
      self.plotStyles=["bar", "colorbar", "line"]     # supported plot styles                 #
      self.summation=False               # show "individual" execution times or "summation"
      
      self.fig=None                      # figure
      self.axes=None                     # plot axes
      
      self.create_main_frame()
      self.createWidgets()
      self.createLayouts()
      self.createConnections()

      self.setMinimumWidth(700)
      self.setMinimumHeight(400)
      

   # Create a main frame
   #
   def create_main_frame(self):
      self.main_frame = QWidget()
      self.dpi = 75
      self.setMinimumWidth(300)
      self.setMinimumHeight(300)

      # We want matplotlib export functionality, so include toolbar
      # MPL Canvas and Toolbar
      # Create canvas for plotting
      self.fig = Figure((5, 4), dpi=75)
      self.canvas = FigureCanvas(self.fig)
      self.canvas.setParent(self)
      self.fig.subplots_adjust(left=0.1, right=0.96, top=0.94, bottom=0.06)  # set a small rim

      self.mpl_toolbar = NavigationToolbar(self.canvas, self)
      self.mpl_toolbar.show()   # first hide the toolbar
   
   
   # Create the layouts for the widgets
   #
   def createLayouts(self):
      # Layouts
      self.buttonLayout=QVBoxLayout()
      self.canvasLayout=QVBoxLayout()
      self.mainLayout=QHBoxLayout()
      
      # Add Widgets to the layout
      self.buttonLayout.addWidget(self.loadButton)
      self.buttonLayout.addWidget(self.quitButton)
      self.buttonLayout.insertStretch(-1)


      self.subStepsLayout=QHBoxLayout()
      self.subStepsLayout.addWidget(self.showSubstepsCheckBox)
      self.subStepsLayout.addWidget(self.showSubstepsLabel)
      self.buttonLayout.addLayout(self.subStepsLayout)
      self.showIndividualStepsLayout=QHBoxLayout()
      self.showIndividualStepsLayout.addWidget(self.showIndividualCheckBox)
      self.showIndividualStepsLayout.addWidget(self.showIndividualLabel)
      self.buttonLayout.addLayout(self.showIndividualStepsLayout)

      self.buttonLayout.addWidget(self.stepComboBox)
      #self.buttonLayout.addWidget(self.stepListView)      
      self.buttonLayout.addWidget(self.substepComboBox)
      self.buttonLayout.addWidget(self.keywordComboBox)
      self.buttonLayout.addWidget(self.plotStyleComboBox)
      self.buttonLayout.addWidget(self.stepComboBox)
      self.buttonLayout.addWidget(self.plotButton)
      self.buttonLayout.insertStretch(-1)

      
      self.canvasLayout.addWidget(self.canvas)
      self.canvasLayout.addWidget(self.mpl_toolbar)

      self.mainLayout.addLayout(self.buttonLayout)
      self.mainLayout.addLayout(self.canvasLayout)
      self.setLayout(self.mainLayout)


   # Create GUI widgets
   #
   def createWidgets(self):
      #print "createWidgets()"             # DEBUG

      self.loadButton=QPushButton("Load logfile")
      self.loadButton.setToolTip('load a BBS kernellog file')
      self.loadButton.setMaximumWidth(200)
      self.quitButton=QPushButton("Quit")
      self.quitButton.setMaximumWidth(200)
      self.quitButton.setToolTip('Quit the application')
      self.quitButton.setMaximumWidth(200)
      self.plotButton=QPushButton("Plot")
      self.plotButton.setToolTip('force a replot')
      
      self.showSubstepsCheckBox=QCheckBox()
      self.showSubstepsLabel=QLabel("Show substeps")
      self.showSubstepsCheckBox.setToolTip("Show also substeps in timing")
      self.showSubstepsCheckBox.setCheckState(Qt.Unchecked)       # Default: False
      self.showSubstepsCheckBox.show()
      self.showSubstepsLabel.show()

      self.showIndividualCheckBox=QCheckBox()
      self.showIndividualLabel=QLabel("Numbered steps")
      self.showIndividualCheckBox.setToolTip("Show individually numbered steps")
      self.showIndividualCheckBox.setCheckState(Qt.Unchecked)       # Default: False
      self.showIndividualCheckBox.show()
      self.showIndividualLabel.show()

      # GUI Widgets depending on log file
      self.createStepComboBox()           # Selector for Step    
      self.createKeywordComboBox()        # Selector for: total, count, avg

      # Selector for plot type: bar, line, multibar
      self.createPlotstyleComboBox()
      self.createStepComboBox()
      #self.createStepListView()
# This is now done in a function, too
#      self.substepComboBox=QComboBox()    # we create this here once
#      self.substepComboBox.hide()
#      self.substepComboBox.setToolTip('Substeps of step')
#      self.substepComboBox.setMaximumWidth(200)

      self.createSubbandComboBox()
    
    
   # Create the step combobox containing the timed steps
   # This should be a multi-selection box to plot multiple
   # steps
   #
   def createStepComboBox(self):
      #print "createStepComboBox()"     # DEBUG
      
      self.stepComboBox=QComboBox()      
      for step in self.parent.timedSteps:
         self.stepComboBox.addItem(step)  
   
      self.stepComboBox.addItem("all")
      self.stepComboBox.show()
      self.stepComboBox.setMaximumWidth(200)


   def createSubstepComboBox(self):
      print "createSubstepComboBox()"     # DEBUG

      self.substepComboBox=QComboBox()    # we create this here once
      self.substepComboBox.hide()
      self.substepComboBox.setToolTip('Substeps of step')
      self.substepComboBox.setMaximumWidth(200)


   # Fill step Checkbox with step names, either these are
   # grouped by their common name, or shown as individually
   # numbered steps
   #
   def fillSteps(self):
      print "fillSteps()"           # DEBUG
   
      self.stepComboBox.clear()
      # Decide if we want the steps grouped or individually numbered
      if self.showIndividualCheckBox.isChecked()==True:      
         steps=self.parent.timedStepsCount
      else:
         steps=self.parent.timedSteps
         
      #print "fillSteps() steps = ", steps
      for step in steps:
         # Check if that substep is already in there, avoid duplicates
         if self.stepComboBox.findData(step) == -1:
            self.stepComboBox.addItem(step)         
      self.stepComboBox.addItem("all")          # we again have to add our "all" option
      

   # Get the corresponding substeps for a step
   #
   def fillSubsteps(self):
      print "fillSubsteps()"         # DEBUG

      # Get substeps for currently selected step (or all if "all")
      step=str(self.stepComboBox.currentText())
      
      self.substepComboBox.clear()           # first clear substeps comboBox
      if step != "all" and step!="ALL":
         substeps=self.parent.getSubsteps(step)
         
         #print "fillSubsteps() substeps = ", substeps    # DEBUG
         for substep in substeps:
            # Check if that substep is already in there, avoid duplicates
            if self.substepComboBox.findData(substep) == -1:
               self.substepComboBox.addItem(substep)
      else:
         self.substepComboBox.clear()                 # First remove existing substeps
         
         index=0
         while index < self.stepComboBox.count():  # loop over all steps        
            # TODO: Might not be supported to show substeps for ALL steps...
            #substeps=str(self.stepComboBox.itemText(index))
            #print "fillSubsteps() substeps = ", substeps
            
            #print "fillSubsteps() index = ", index, "maxCount = ", self.stepComboBox.count()
            step=str(self.stepComboBox.itemText(index))
            print "fillSubsteps() step = ", step
            if step != "all" and step != "ALL":
               substeps=self.parent.getSubsteps(step)
            
               keys=substeps.keys()
               #print "keys = ", keys
               for j in range(len(substeps)-1):
                  #print "fillSubsteps() substeps = ", substeps
                  substep=keys[j]
                  if substep != "all" and substep != "ALL":
                     self.substepComboBox.addItem(substep)
                  j=j+1
            
            index=index+1
   
         self.substepComboBox.addItem("ALL")       # we need to add an "ALL"
      
      
   """
   # Alternative view, displaying all the steps
   # in a list view that then can be selected for
   # plotting
   #
   def createStepListView(self):
      print "createStepListBox()"      # DEBUG
      
      self.stepListView=QListView()
      for step in self.parent.timedSteps:
         self.stepListView.insertStringList(step)
      self.stepListView.show()
      step.stepListView.setMaximumWidth(200)
   """

      
   # On timing combobox event
   #
   def createKeywordComboBox(self):   
      print "createTimingComboBox()"   # DEBUG
      
      self.keywordComboBox=QComboBox()
      for key in self.parent.keywords:
         self.keywordComboBox.addItem(key)
      
      self.keywordComboBox.show()
      self.keywordComboBox.setMaximumWidth(200)
      

   # Create a comboBox offering different Matplotlib styles
   #
   def createPlotstyleComboBox(self):
      print "createPlotstyleComboBox()"     # DEBUG
      
      self.plotStyleComboBox=QComboBox()
      for style in self.plotStyles:
         self.plotStyleComboBox.addItem(style)
      
      self.plotStyleComboBox.show()
      self.plotStyleComboBox.setMaximumWidth(200)

   
   # Create subbands comboBox which allows selection of an individual subband
   # from a pipeline.log
   def createSubbandComboBox(self):
      print "createSubbandComboBox()"   # DEBUG

      self.subbandComboBox=QComboBox()
      for sub in self.parent.subbands:
         self.subbandComboBox.addItem(sub)

      self.subbandComboBox.show()
      self.subbandComboBox.setMaximumWidth(200)


   #**************************************
   #
   # Create connections
   #
   #**************************************

   def createConnections(self):
      print "createConnections()"      # DEBUG

      self.connect(self.loadButton, SIGNAL('clicked()'), self.on_loadfile)   
      self.connect(self.quitButton, SIGNAL('clicked()'), self, SLOT('close()')) 

      self.connect(self.stepComboBox, SIGNAL('currentIndexChanged(int)'), self.on_step)
      self.connect(self.stepComboBox, SIGNAL('currentIndexChanged(int)'), self.on_showSubsteps)
      #self.connect(self.substepComboBox, SIGNAL('currentIndexChanged(int)'), self.on_step)
      self.connect(self.substepComboBox, SIGNAL('currentIndexChanged(int)'), self.on_plot)      
      self.connect(self.keywordComboBox, SIGNAL('currentIndexChanged(int)'), self.on_keyword)
      self.connect(self.plotStyleComboBox, SIGNAL('currentIndexChanged(int)'), self.on_plotStyle)
      self.connect(self.showSubstepsCheckBox, SIGNAL('stateChanged(int)'), self.on_showSubsteps)
      self.connect(self.showIndividualCheckBox, SIGNAL('stateChanged(int)'), self.on_individualSteps)
      self.connect(self.subbandComboBox, SIGNAL('currentIndexChanged(int)'), self.on_subband)

      self.connect(self.plotButton, SIGNAL('clicked()'), self.on_plot)


   #**************************************
   #
   # Event handlers
   #
   #**************************************

   # Load Kernellog file dialog
   #
   def on_loadfile(self):
      #print "on_loadfile()"    # DEBUG
      
      # Customization: check if ~/Cluster/SolutionTests exists
      if os.path.exists('/Users/duscha/Desktop/'):
         setDir=QString('/Users/duscha/Desktop/')
      else:
         setDir=QString('')

      path = unicode(QFileDialog.getOpenFileName(self, 'Load Kernellog', setDir))
      path=str(path)  # Convert to string so that it can be used by load table

      if path:
         self.parent.readLogfile(path)
      else:
         print "load_table: invalid path"


   # On step combobox event
   #      
   def on_step(self):
      print "on_step()"                # DEBUG
      #step=str(self.stepComboBox.currentText())
      self.on_plot()


   # On substep combobox event
   #
   def on_substep(self):
      print "on_substep()"             # DEBUG    
      #step=str(self.stepComboBox.currentText())
      self.on_plot()


   # On toggle individual treatment of counted steps
   #
   def on_individualSteps(self):
      print "on_individualSteps()"     # DEBUG
      self.fillSteps()                 # update steps combobox
      self.on_showSubsteps()           # also update substeps combobox
      #step=str(self.stepComboBox.currentText())
      self.on_plot()

   # On selection of different subbands
   #
   def on_subband(self):
      print "on_subband()"             # DEBUG
      self.fillSteps()                 # update steps combobox
      self.on_showSubsteps()           # also update substeps combobox
      self.on_plot()

   # On toggling of show substeps
   #
   def on_showSubsteps(self):
      print "on_substeps()"            # DEBUG
      
      if self.showSubstepsCheckBox.isChecked()==True:
         self.showSubSteps=True
         self.substepComboBox.show()
         self.fillSubsteps()
      else:
         self.showSubSteps=False
         self.substepComboBox.hide()
         self.substepComboBox.clear()      
   
   # On keyword combobox event
   #
   def on_keyword(self):
      print "on_keyword()"             # DEBUG
      self.on_plot()
      

   # On change of plot style
   #
   def on_plotStyle(self):
      print "on_plotStyle()"           # DEBUG
      
      self.plotStyle=self.plotStyleComboBox.currentText()      # change class attribute
 
 
   # On plot button action
   #
   def on_plot(self):
      self.fig.clf()       # clear the figure
      
      print "on_plot()"
      
      step=str(self.stepComboBox.currentText())
      self.plot(step)
      """
      step=str(self.stepComboBox.currentText())
      # If we have all steps selected:
      if step=="ALL" or step=="all":
         for i in range(0, self.stepComboBox.count()):         # loop over all steps
            currentStep=self.stepComboBox.itemText(i)          # get the step name from QComboBox
            
            print "on_plot() currentStep = ", currentStep
            
            self.plot(currentStep)                             # plot it
      else:
         #print "foo"
         self.plot(step)                                       # replot with new plotstyle
      """

   # Replot diagram 
   #
   def plot(self, step):
      print "plot()"                    # DEBUG

      width=0.25            # width of bar plots
      
      # Get the data according to GUI settings     
      step=str(step)
      substep=str(self.substepComboBox.currentText())
      keyword=str(self.keywordComboBox.currentText())
      style=str(self.plotStyleComboBox.currentText())
      
      print "plot() step = ", step, "substep = ", substep, "keyword = ", keyword, "style = ", style      # DEBUG

      self.axes=self.fig.add_subplot(111)          # add 1 subplot to the canvas
      result=[]
      
      # TODO: plot all substeps if we get multiple in results
      if step=="all" or step=="ALL":
         if self.showIndividualCheckBox.isChecked():
            steps=self.parent.timedStepsCount
         else:
            steps=self.parent.timedSteps
         
         print "plot() steps = ", steps      # DEBUG        
         for i in range(0, len(steps)):
            #print "plot()", self.parent.getSubStepValue(str(steps[i]), substep, keyword)
            result.append(self.parent.getStepFinal(str(steps[i]), keyword))
            
            #print "len(result) = ", len(result)
            print "plot() result[" + str(i) + "] = " + str(result[i])
            #self.axes.bar(i, result[i], width)

      
      # If we want to see all steps, but not for individual substeps
      elif step=="all" or step=="ALL" and (substep==None or substep==""):      
         if self.showIndividualCheckBox.isChecked():
            steps=self.parent.getSubsteps(step, keyword)
         else:
            steps=self.parent.timedSteps
            print "steps = ", steps
            #steps.append(self.parent.timedSteps)
            newsteps=[]
            if isinstance(steps, list):
               for i in range(0, len(steps)):   # overplot them in one plot
                  newsteps.append(steps[i])
            
            result=newsteps
      elif substep=="all" or substep=="ALL":
          print "plot(): substep=all"
          result=(self.parent.getSubStepValue(step, keyword))
      elif substep==None or substep=="":
         result=(self.parent.getStepFinal(step, keyword))
      else:
         result=(self.parent.getSubStepValue(step, substep, keyword))
      
      
      #if isinstance(result[0], list):
      #   result=self.linearizeList(result)
      
      if isinstance(result, list):
         print "plot() len(result) = ", len(result)        # DEBUG
         print "plot() result = ", result                  # DEBUG
         #print "plot() result[1] = ", result[1]           # DEBUG

      #
      # Plot on canvas
      #
      ind=[]
      if isinstance(result, float) or isinstance(result, int):
         ind=0
      elif isinstance(result, bool):
         print "plot() invalid result returned"
      else:
         maxInd=len(result)
         for i in range(0, maxInd):
            ind.append(width*1.1*i)      
      
      # Decide on plotstyle which plotting to do
      if self.currentPlotStyle=="bar":
         print "ind = ", ind           # DEBUG
         print "result = ", result     # DEBUG
         rects1 = self.axes.bar(ind, result, width, color='r')
      
      elif self.currentPlotStyle=="colorbar":
         print "plot() colorbar"
      else:
         print "plot() lines"
         self.axes.scatter(0, result)

      #
      # Set axes labels according to selected keyword on y-axis and
      # for each plotted step/substep identifier on the x-axis
      #
      ylabel=str(self.keywordComboBox.currentText())
      if self.keywordComboBox.currentText() == "total" or self.keywordComboBox.currentText() == "avg":
         ylabel=ylabel + " s"
      self.axes.set_ylabel(ylabel)
      
      self.canvas.draw()


   #******************************************************
   #
   # Helper functions
   #
   #*******************************************************   

   def linearizeList(self, reorderlist):
      print "linearizeList()"          # DEBUG
   
      newlist=[]
      
      if isinstance(reorderlist, list):
         Nlists=len(reorderlist)
         for i in range(Nlists):
            if isinstance(reorderlist[i], list):
               for j in len(reorderlist[i]):
                  newlist.append(reorderlist[i][j])
            else:
                  newlist.append(reorderlist[i])
      return newlist
      

   #******************************************************
   #
   # Update GUI Widgets on loading a new Kernellog file
   #
   #*******************************************************

   # Update the Kernel log dependent widgets, i.e. deleting
   # and recreating them
   #   
   def updateWidgets(self):
      print "updateWidgets()"       # DEBUG

      self.deleteWidgets()
      self.createWidgets()   

       
   # Delete GUI Widgets that are created dynamically from the log
   #
   def deleteWidgets(self):         # DEBUG
      print "deleteWidgets()"
      
      self.stepComboBox.deleteLater()
      self.keywordComboBox.deleteLater()
      self.plotstyleComboBox.deleteLater()
      self.stepComboBox.deleteLater()