Ejemplo n.º 1
0
class AmountGraph(wx.Panel):
    def __init__(self, parent, all_data):
        wx.Panel.__init__(self, parent=parent)
        plt.style.use('bmh')

        # matplotlib figure
        self.figure = Figure()
        self.ax = self.figure.subplots()
        money_list = [money[2] for money in all_data]
        if money_list == []:
            max_money = 1000
        else:
            max_money = max(money_list)
        hist_bins = round(max_money / 1000)
        self.ax.hist(money_list,
                     histtype='barstacked',
                     bins=hist_bins,
                     range=(0, hist_bins * 1000),
                     rwidth=1)

        # canvas
        self.canvas = FigureCanvasWxAgg(self, wx.ID_ANY, self.figure)
        self.canvas.SetBackgroundColour(wx.Colour(100, 255, 255))

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.canvas, 1, flag=wx.EXPAND)
        self.SetSizer(sizer)
        self.Fit()
Ejemplo n.º 2
0
class PlotPanel(wx.Panel):
    """
    The PlotPanel has a Figure and a Canvas. OnSize events simply set a 
    flag, and the actual resizing of the figure is triggered by an Idle event.
    """
    def __init__(self, parent, obj_id):
        # initialize Panel
        wx.Panel.__init__(self, parent, obj_id)

        # initialize matplotlib stuff
        self.figure = Figure(None, None)
        self.canvas = FigureCanvasWxAgg(self, wx.ID_ANY, self.figure)
        rgbtuple = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get()
        clr = [c / 255. for c in rgbtuple]
        self.figure.set_facecolor(clr)
        self.figure.set_edgecolor(clr)
        self.canvas.SetBackgroundColour(wx.Colour(*rgbtuple))

        self.Bind(wx.EVT_SIZE, self._on_size)

    def _on_size(self, event):
        self._set_size()

    def _set_size(self):
        pixels = tuple(self.GetClientSize())
        self.SetSize(pixels)
        self.canvas.SetSize(pixels)
        self.figure.set_size_inches(
            float(pixels[0]) / self.figure.get_dpi(),
            float(pixels[1]) / self.figure.get_dpi())

    def draw(self):
        pass  # abstract, to be overridden by child classes
Ejemplo n.º 3
0
class Plot(wx.Panel):
    def __init__(self, parent, id=-1, dpi=None):
        ps = parent.GetSize()
        wx.Panel.__init__(self, parent, id=id, size=ps)
        self.SetBackgroundColour('WHITE')
        self.figure = mpl.figure.Figure(dpi=dpi,
                                        facecolor='w',
                                        figsize=(ps[0] * .09, ps[1] * .09))
        #self.figure.SetBackgroundColour('WHITE')
        self.canvas = Canvas(self, -1, self.figure)
        self.canvas.SetBackgroundColour('WHITE')
        self.canvas.Bind(wx.EVT_RIGHT_DOWN, self.doSave)

    def doSave(self, event):
        dlg = wx.FileDialog(self,
                            message="Save file as ...",
                            defaultDir=os.curdir,
                            defaultFile="",
                            wildcard="*.png",
                            style=wx.FD_SAVE)
        if dlg.ShowModal() == wx.ID_OK:
            path = dlg.GetPath()
        dlg.Destroy()
        self.figure.savefig(path,
                            dpi=None,
                            facecolor='w',
                            edgecolor='w',
                            orientation='portrait',
                            papertype=None,
                            format='png',
                            transparent=False,
                            bbox_inches=None,
                            pad_inches=0.1,
                            frameon=None)
Ejemplo n.º 4
0
class PeriodGraph(wx.Panel):
    def __init__(self, parent, test):
        wx.Panel.__init__(self, parent=parent)
        plt.style.use('bmh')

        # matplotlib figure
        year_list = [item[2] for item in test]
        year_list = list(set(year_list))
        year_list.sort()
        month_list = [num for num in range(1, 13)]
        use_list = [item[0] for item in test]
        use_list = list(set(use_list))
        use_list.sort()

        data_list = {
            use: [[0 for month in month_list] for year in year_list]
            for use in use_list
        }

        for item in test:
            for y_index, year in enumerate(year_list):
                if item[2] == year:
                    for month in month_list:
                        if item[3] == month:
                            for use in use_list:
                                if item[0] == use:
                                    data_list[use][y_index][month -
                                                            1] = item[1]

        data_print_list = [
            f"{year}/{month}" for year in year_list for month in month_list
        ]

        plt.style.use('bmh')
        self.figure = Figure()
        self.ax1 = self.figure.subplots()
        all_list = np.array([0 for month in month_list for year in year_list])
        for use in use_list:
            use_data = []
            for data in data_list[use]:
                use_data.extend(data)
            use_data = np.array(use_data)
            all_list += use_data
            self.ax1.plot(data_print_list, use_data, marker='o')
            self.ax1.set_xticklabels(data_print_list,
                                     rotation=270,
                                     fontsize='small')
        self.ax2 = self.ax1.twinx()
        res = np.cumsum(all_list)
        self.ax2.plot(data_print_list, res, color="red")

        # canvas
        self.canvas = FigureCanvasWxAgg(self, wx.ID_ANY, self.figure)
        self.canvas.SetBackgroundColour(wx.Colour(100, 255, 255))

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.canvas, 1, flag=wx.EXPAND)
        self.SetSizer(sizer)
        self.Fit()
Ejemplo n.º 5
0
class PlotPanel(wx.Panel):
    """The PlotPanel has a Figure and a Canvas. OnSize events simply set a 
flag, and the actual resizing of the figure is triggered by an Idle event."""
    def __init__(self, parent, color=None, dpi=None, **kwargs):
        from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
        from matplotlib.figure import Figure

        # initialize Panel
        if 'id' not in kwargs.keys():
            kwargs['id'] = wx.ID_ANY
        if 'style' not in kwargs.keys():
            kwargs['style'] = wx.NO_FULL_REPAINT_ON_RESIZE
        wx.Panel.__init__(self, parent, **kwargs)

        # initialize matplotlib stuff
        self.figure = Figure(None, dpi)
        self.axes = self.figure.gca()
        self.canvas = FigureCanvasWxAgg(self, -1, self.figure)
        self.SetColor(color)

        self._SetSize()
        self.draw()
        self.axes.set_xlabel('T (s)')
        self.axes.set_ylabel('Alfa_max (g)')
        self.axes.set_title("wave curve")
        self.axes.grid(True)
        self._resizeflag = False

        self.Bind(wx.EVT_IDLE, self._onIdle)
        self.Bind(wx.EVT_SIZE, self._onSize)

    def SetColor(self, rgbtuple=None):
        """Set figure and canvas colours to be the same."""
        if rgbtuple is None:
            rgbtuple = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get()
        clr = [c / 255. for c in rgbtuple]
        self.figure.set_facecolor(clr)
        self.figure.set_edgecolor(clr)
        self.canvas.SetBackgroundColour(wx.Colour(*rgbtuple))

    def _onSize(self, event):
        self._resizeflag = True

    def _onIdle(self, evt):
        if self._resizeflag:
            self._resizeflag = False
            self._SetSize()

    def _SetSize(self):
        pixels = tuple(self.parent.GetClientSize())
        self.SetSize(pixels)
        self.canvas.SetSize(pixels)
        self.figure.set_size_inches(
            float(pixels[0]) / self.figure.get_dpi(),
            float(pixels[1]) / self.figure.get_dpi())

    def draw(self):
        pass  # abstract, to be overridden by child classes
Ejemplo n.º 6
0
class myWxPlot(wx.Panel):
    def __init__(self, parent):
        from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
        from matplotlib.figure import Figure

        self.parent = parent
        wx.Panel.__init__(self, parent)

        #matplotlib figure
        self.figure = Figure(None)
        self.figure.set_facecolor((0.7, 0.7, 1.))
        self.subplot = self.figure.add_subplot(111)
        #canvas
        self.canvas = FigureCanvasWxAgg(self, -1, self.figure)
        self.canvas.SetBackgroundColour(wx.Colour(100, 255, 255))

        self._SetSize()
        self.draw2()

    def _SetSize(self):
        size = tuple(self.parent.GetClientSize())
        self.SetSize(size)
        self.canvas.SetSize(size)
        self.figure.set_size_inches(
            float(size[0]) / self.figure.get_dpi(),
            float(size[1]) / self.figure.get_dpi())

    def draw(self):
        from mpl_toolkits.mplot3d import Axes3D
        import numpy as np

        x = np.arange(-3, 3, 0.25)
        y = np.arange(-3, 3, 0.25)
        X, Y = np.meshgrid(x, y)
        Z = np.sin(X) + np.cos(Y)

        ax = Axes3D(self.figure)
        ax.plot_wireframe(X, Y, Z)

    def draw2(self):
        import numpy as np

        theta = np.arange(0, 200, 0.1)
        x = 2 * np.cos(theta / 7)
        y = 3 * np.sin(theta / 3)

        self.subplot.plot(x, y, '-r')

        self.subplot.set_title("Sample", fontsize=12)
        self.subplot.set_xlabel("x")
        self.subplot.set_ylabel("y")
        self.subplot.set_xlim([-4, 4])
        self.subplot.set_ylim([-4, 4])
Ejemplo n.º 7
0
class WXMatPlotLibPanel(wx.Panel):
    def __init__(self, parent, color=None, dpi=None, **kwargs):
        from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
        from matplotlib.figure import Figure

        # initialize Panel
        if 'id' not in kwargs.keys():
            kwargs['id'] = wx.ID_ANY
        if 'style' not in kwargs.keys():
            kwargs['style'] = wx.NO_FULL_REPAINT_ON_RESIZE
        wx.Panel.__init__(self, parent, **kwargs)

        # initialize matplotlib stuff
        self.figure = Figure(None, dpi)
        self.canvas = FigureCanvasWxAgg(self, -1, self.figure)
        #self.SetColor( color )

        self._SetSize()
        self.draw()

        self._resizeflag = False

        self.Bind(wx.EVT_IDLE, self._onIdle)
        self.Bind(wx.EVT_SIZE, self._onSize)

    def SetColor(self, rgbtuple=None):
        """Set figure and canvas colours to be the same."""
        if rgbtuple is None:
            rgbtuple = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get()
        clr = [c / 255. for c in rgbtuple]
        self.figure.set_facecolor(clr)
        self.figure.set_edgecolor(clr)
        self.canvas.SetBackgroundColour(wx.Colour(*rgbtuple))

    def _onSize(self, event):
        self._resizeflag = True

    def _onIdle(self, evt):
        if self._resizeflag:
            self._resizeflag = False
            self._SetSize()

    def _SetSize(self):
        pixels = tuple(self.parent.GetClientSize())
        self.SetSize(pixels)
        self.canvas.SetSize(pixels)
        self.figure.set_size_inches(
            float(pixels[0]) / self.figure.get_dpi(),
            float(pixels[1]) / self.figure.get_dpi())

    def draw(self):
        pass  # abstract, to be overridden by child classes
Ejemplo n.º 8
0
class plottingWindow(wx.Window):
    def __init__(self, *args, **kwargs):

        if "figsize" in kwargs:
            self.figure = Figure(figsize=kwargs["figsize"])
            self._axes = [0.1, 0.1, 0.8, 0.8]
            del kwargs["figsize"]
        else:
            self.figure = Figure(figsize=[8, 2.5])

        self.figure.set_facecolor('white')

        wx.Window.__init__(self, *args, **kwargs)
        self.canvas = FigureCanvasWxAgg(self, -1, self.figure)
        self.figure.set_facecolor('white')
        self.figure.set_edgecolor('white')
        self.canvas.SetBackgroundColour('white')

        # Create a resizer
        self.Bind(wx.EVT_SIZE, self.sizeHandler)
        self.resize = 1

        #         self.canvas.mpl_connect('motion_notify_event', self.onMotion)

        # Prepare for zoom
        self.zoom = None
        self.zoomtype = "box"

    def setupGetXAxies(self, plots):
        self.getxaxis = GetXValues(plots)

    def repaint(self):
        """
        Redraw and refresh the plot.
        :return: None
        """
        self.canvas.draw()

    def clearPlot(self, *args):
        """
        Clear the plot and rest some of the parameters.
        :param args: Arguments
        :return:
        """
        self.figure.clear()
        self.repaint()

    def sizeHandler(self, *args, **kwargs):
        if self.resize == 1:
            self.canvas.SetSize(self.GetSize())
Ejemplo n.º 9
0
class PiePanel (wx.Panel):
    def __init__( self, parent, color=None, dpi=None, explode=(0, 0.05, 0, 0), fracs=[15,30,45, 10], **kwargs ):
        from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
        from matplotlib.figure import Figure
        if 'id' not in kwargs.keys():
            kwargs['id'] = wx.ID_ANY
        if 'style' not in kwargs.keys():
            kwargs['style'] = wx.NO_FULL_REPAINT_ON_RESIZE
        wx.Panel.__init__( self, parent, **kwargs )
        self.parent=parent
        self.figure = Figure( None, dpi )
        self.canvas = FigureCanvasWxAgg( self, -1, self.figure )
        labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
        self.SetColor( color )
        self._SetSize()
        ax = self.figure.add_axes([0.1, 0.1, 0.8, 0.8])
        pies=ax.pie(fracs, explode=explode, labels=labels, autopct='%1.1f%%', shadow=True)
        self.draw()
        self._resizeflag = False
        self.Bind(wx.EVT_IDLE, self._onIdle)
        self.Bind(wx.EVT_SIZE, self._onSize)

    def SetColor( self, rgbtuple=None ):
        """Set figure and canvas colours to be the same."""
        if rgbtuple is None:
            rgbtuple = wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ).Get()
        clr = [c/255. for c in rgbtuple]
        self.figure.set_facecolor( clr )
        self.figure.set_edgecolor( clr )
        self.canvas.SetBackgroundColour( wx.Colour( *rgbtuple ) )

    def _onSize( self, event ):
        self._resizeflag = True

    def _onIdle( self, evt ):
        if self._resizeflag:
            self._resizeflag = False
            self._SetSize()

    def _SetSize( self ):
        pixels = tuple( self.parent.GetClientSize() )
        self.SetSize( pixels )
        self.canvas.SetSize( pixels )
        self.figure.set_size_inches( float( pixels[0] )/self.figure.get_dpi(),
                                     float( pixels[1] )/self.figure.get_dpi() )
        def draw( self ):
            print "Drawing"
            self.canvas.draw()
Ejemplo n.º 10
0
class UseGraph(wx.Panel):
    def __init__(self, parent, use_accounting_list):
        wx.Panel.__init__(self, parent=parent)
        plt.style.use('bmh')
        use = [use_accounting[0] for use_accounting in use_accounting_list]
        money = [use_accounting[1] for use_accounting in use_accounting_list]
        use_money_df = pd.DataFrame({
            "use": use,
            "money": money
        },
                                    columns=["use", "money"])
        use_money_df["accum"] = np.cumsum(use_money_df["money"])
        use_money_df["accum_pa"] = use_money_df["accum"] / sum(money) * 100

        # matplotlib figure
        self.figure = Figure()
        self.ax1 = self.figure.subplots()
        self.ax1.bar(use, money, label=u'累計', width=-1, edgecolor='k')
        self.ax1.tick_params(axis="x", which="major", direction="in")
        self.ax1.set_xticklabels(use, rotation=270, fontsize='small')
        self.ax2 = self.ax1.twinx()
        self.ax2.plot(use,
                      use_money_df["accum_pa"],
                      c='k',
                      marker='o',
                      label=u'累積和')
        self.ax2.set_ylim([0, 100])
        self.ax2.set_yticks(np.arange(0, 101, 10))
        percent_labels = [f"{i}%" for i in np.arange(0, 101, 10)]
        self.ax2.set_yticklabels(percent_labels)
        try:
            self.figure.legend(bbox_to_anchor=(1, 0.05),
                               loc='upper right',
                               ncol=2)
        except:
            pass

        # canvas
        self.canvas = FigureCanvasWxAgg(self, wx.ID_ANY, self.figure)
        self.canvas.SetBackgroundColour(wx.Colour(100, 255, 255))

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.canvas, 1, flag=wx.EXPAND)
        self.SetSizer(sizer)
        self.Fit()
Ejemplo n.º 11
0
class WxMatplotlibPanel(wx.Panel):
    def __init__(self, parent):

        from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
        from matplotlib.figure import Figure

        self.parent = parent
        wx.Panel.__init__(self, parent)

        self.figure = Figure(None)
        self.figure.set_facecolor((0.7, 0.7, 1.))
        self.subplot = self.figure.add_subplot(111)

        self.canvas = FigureCanvasWxAgg(self, -1, self.figure)
        self.canvas.SetBackgroundColour(wx.Colour(100, 255, 255))

        self._SetSize()
        self.draw()

    def _SetSize(self):

        size = tuple(self.parent.GetClientSize())
        self.SetSize(size)
        self.canvas.SetSize(size)
        self.figure.set_size_inches(
            float(size[0]) / self.figure.get_dpi(),
            float(size[1]) / self.figure.get_dpi())

    def draw(self):
        from mpl_toolkits.mplot3d import Axes3D
        import numpy as np

        x = np.arange(-3, 3, 0.25)
        y = np.arange(-3, 3, 0.25)
        X, Y = np.meshgrid(x, y)
        Z = np.sin(X) + np.cos(Y)

        ax = Axes3D(self.figure)
        #ax.plot_wireframe(X, Y, Z)
        ax.plot_surface(X, Y, Z, rstride=1, cstride=1)
Ejemplo n.º 12
0
class plotTimeSeries(wx.Panel):


  def _init_coll_boxSizer1_Items(self, parent):
      # generated method, don't edit

      parent.AddWindow(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
      parent.AddWindow(self.toolbar, 0,  wx.EXPAND)


  def _init_sizers(self):
      # generated method, don't edit
      self.boxSizer1 = wx.BoxSizer(orient=wx.VERTICAL)
      self._init_coll_boxSizer1_Items(self.boxSizer1)
      self.SetSizer(self.boxSizer1)



  def _init_ctrls(self, parent):
      #matplotlib.figure.Figure.__init__(self)
      wx.Panel.__init__(self, parent, -1)
      self.parent = parent

      # self.figure = Figure()#matplotlib.figure.Figure()

      #init Plot
      # self.timeSeries=self.figure.add_subplot(111)
      self.timeSeries = host_subplot(111, axes_class=AA.Axes)

      # self.timeSeries.axis([0, 1, 0, 1])#
      self.timeSeries.plot([],[])
      self.timeSeries.set_title("No Data To Plot")

      self.canvas = FigCanvas(self, -1, plt.gcf())
      # self.canvas = FigCanvas(self, -1, self.figure)

      self.canvas.SetFont(wx.Font(20, wx.SWISS, wx.NORMAL, wx.NORMAL,
            False, u'Tahoma'))
      # self.canvas.mpl_connect('pick_event', self.on_pick)


      # Create the navigation toolbar, tied to the canvas
      self.toolbar = NavigationToolbar(self.canvas, allowselect=True)
      self.toolbar.Realize()
      self.seriesPlotInfo= None


      self.fontP = FontProperties()
      self.fontP.set_size('small')

      self.format = '-o'
      self.SetColor("WHITE")
      #self.canvas.gca().xaxis.set_major_locator()

      #init lists

      self.lines=[]
      self.axislist={}
      self.curveindex = -1
      self.editseriesID = -1
      self.editCurve =None
      self.cid=None

      self.canvas.draw()
      self._init_sizers()



  # def changeSelectionDT(self, sellist):
  #     #list of DateTimes

  #     print sellist
  #     self.parent.record_service.select_points(datetime_list= sellist)
  #     sellist = self.selFormat(sellist)
  #     self.changeSelection(sellist)
  #     print sellist


  # def selFormat(self, pairs):
  #   #convert selectionlist from datetimes to true false
  #     print len(pairs)
  #     if len(pairs) ==0:
  #       return [False] * len(self.editData.DataValues)
  #     verts =[ (matplotlib.dates.date2num(x), y) for x,y  in pairs]
  #     p = path.Path(verts)

  #     ind = p.contains_points(self.xys)
  #     return ind


  def changeSelection(self, sellist ):
    #list of True False
      self.editPoint.set_color(['k' if x==0 else 'r' for x in sellist])
      self.parent.record_service.select_points_tf(sellist)
      Publisher.sendMessage(("changeTableSelection"), sellist=sellist)

      self.canvas.draw()

  def onDateChanged(self, date, time):
      # print date
      # self.timeSeries.clear()
      date = datetime.datetime(date.Year, date.Month+1, date.Day, 0, 0, 0)
##      print date
      if time == "start":
        self.startDate = date
      else:
        self.endDate = date

      self.timeSeries.axis.axes.set_xbound(self.startDate, self.endDate)
      self.canvas.draw()

  def set_date_bound(self, start, end):
        if start < self.overallStart:
            self.overallStart = start

        if end > self.currEnd:
            self.currEnd = end

  def OnShowLegend(self, isVisible):
    # print self.timeSeries.show_legend
    if isVisible:
      plt.subplots_adjust(bottom=.1+.1)
      self.timeSeries.legend(loc='upper center', bbox_to_anchor=(0.5, -0.05),
               ncol=2, prop = self.fontP)

    else:
      plt.subplots_adjust(bottom=.1)
      self.timeSeries.legend_=None
    # self.timeSeries.plot(legend= not isVisible)
    self.canvas.draw()



  def OnPlotType(self, ptype):
    # self.timeSeries.clear()
    if ptype == "line":
      ls = '-'
      m='None'
    elif ptype == "point":
      ls='None'
      m='o'
    else:
      ls = '-'
      m='o'
    # print plt.setp(self.lines)
    # print(len(self.lines))
    format = ls+m
    for line, i in zip(self.lines, range(len(self.lines))):
      if not (i == self.curveindex):
        plt.setp(line, linestyle = ls, marker =  m)

    self.canvas.draw()


  def Clear(self):
    lines = []
    for key, ax in self.axislist.items():
      ax.clear()
    # self.stopEdit()

  def stopEdit(self):
      self.Clear()
      self.selectedlist = None
      self.editPoint =None
      self.lman= None
      self.canvas.mpl_disconnect(self.cid)
      self.cid=None
      self.xys = None

      self.curveindex = -1
      self.editCurve =None
      # self.RefreshPlot()
      if self.seriesPlotInfo and self.seriesPlotInfo.IsPlotted(self.editseriesID):
        self.updatePlot()
      self.editseriesID = -1


  def updateValues(self):
    # self.addEdit(self.editCursor, self.editSeries, self.editDataFilter)

    #clear current edit points and curve
    curraxis= self.axislist[self.editCurve.axisTitle]
    for l in curraxis.lines:
      if l.get_label() == self.editCurve.plotTitle:
        curraxis.lines.remove(l)
    self.editPoint.remove()


    #redraw editpoints and curve
    self.seriesPlotInfo.UpdateEditSeries()
    self.editCurve= self.seriesPlotInfo.GetEditSeriesInfo()
    self.drawEditPlot(self.editCurve)
    Publisher.sendMessage(("refreshTable"), e=None)
    # self.parent.parent.dataTable.Refresh()
    self.canvas.draw()


  def drawEditPlot(self, oneSeries):
      curraxis= self.axislist[oneSeries.axisTitle]
      self.lines[self.curveindex]=curraxis.plot_date([x[1] for x in oneSeries.dataTable], [x[0] for x in oneSeries.dataTable], "-", color=oneSeries.color, xdate = True, tz = None, label = oneSeries.plotTitle )

      self.selectedlist = self.parent.record_service.get_filter_list()
      self.editPoint = curraxis.scatter([x[1] for x in oneSeries.dataTable], [x[0] for x in oneSeries.dataTable], s= 20, c=['k' if x==0 else 'r' for x in self.selectedlist])
      self.xys = [(matplotlib.dates.date2num(x[1]), x[0]) for x in oneSeries.dataTable ]
      self.cid = self.canvas.mpl_connect('button_press_event', self.onpress)

  def SetColor( self, color):
      """Set figure and canvas colours to be the same."""
      plt.gcf().set_facecolor( color )
      plt.gcf().set_edgecolor( color )
      self.canvas.SetBackgroundColour( color )

  def Close(self):
    plt.close()


  def Plot(self, seriesPlotInfo):
    self.seriesPlotInfo= seriesPlotInfo
    self.updatePlot()

  def updatePlot(self):
      self.Clear()
      count = self.seriesPlotInfo.count()
      self.lines=[]

      # self.timeSeries=self.canvas.add_subplot(111)
      self.setUpYAxis()


      for oneSeries in self.seriesPlotInfo.GetSeriesInfo():

        if oneSeries.seriesID == self.seriesPlotInfo.GetEditSeriesID():

          self.curveindex = len(self.lines)
          self.lines.append("")
          self.editCurve= oneSeries
          self.drawEditPlot(oneSeries)

        else:
          curraxis= self.axislist[oneSeries.axisTitle]
          self.lines.append(curraxis.plot_date([x[1] for x in oneSeries.dataTable], [x[0] for x in oneSeries.dataTable], self.format, color=oneSeries.color, xdate = True, tz = None, label = oneSeries.plotTitle ))


      if count >1:
        # self.timeSeries.set_title("Multiple Series plotted")
        self.timeSeries.set_title("")
        plt.subplots_adjust(bottom=.1+.1)
        # self.timeSeries.legend(loc='upper center', bbox_to_anchor=(0.5, -0.05),
        #      ncol=2, prop = self.fontP)
        self.timeSeries.legend(loc='upper center', bbox_to_anchor=(0.5, -0.15),
             ncol=2, prop = self.fontP)
      elif count == 0:
        self.timeSeries.set_title("")
        self.timeSeries.legend_=None
      else:
        self.timeSeries.set_title(oneSeries.plotTitle)
        plt.subplots_adjust(bottom=.1)
        self.timeSeries.legend_=None


      # self.timeSeries.set_xlim([0,1000])
      self.timeSeries.set_xlabel("Date Time")
      self.canvas.draw()



  def setEdit(self, id):
      self.editseriesID = id
      if self.seriesPlotInfo and self.seriesPlotInfo.IsPlotted(self.editseriesID):
        self.editCurve = self.seriesPlotInfo.GetSeries(self.editseriesID)
        self.updatePlot()
        # print self.editCurve



  def setUpYAxis(self):
    self.axislist={}
    left = 0
    right = 0
    adj = .05
    #loop through the list of curves and add an axis for each
    for oneSeries in self.seriesPlotInfo.GetSeriesInfo():
      #test to see if the axis already exists
      if not oneSeries.axisTitle in self.axislist:
        self.axislist[oneSeries.axisTitle]=None


    for i, axis in zip(range(len(self.axislist)), self.axislist):
      if i %2==0:
        left = left+1
        #add to the left(yaxis)
        if i==0:
          #if first plot use the orig axis
          newAxis =self.timeSeries
        else:
          newAxis= self.timeSeries.twinx()
          new_fixed_axis = newAxis.get_grid_helper().new_fixed_axis
          newAxis.axis['left']= new_fixed_axis(loc = 'left', axes= newAxis, offset= (-30*left ,0))
          newAxis.axis["left"].toggle(all = True)
          newAxis.axis["right"].toggle(all = False)
          plt.subplots_adjust(left=.10+(adj*(left-1)))

      else:
        right= right+1
        #add to the right(y2axis)
        newAxis= self.timeSeries.twinx()
        new_fixed_axis = newAxis.get_grid_helper().new_fixed_axis
        newAxis.axis['right']= new_fixed_axis(loc = 'right', axes= newAxis, offset= (60*(right-1) ,0))
        newAxis.axis['right'].toggle(all=True)
        plt.subplots_adjust(right=.9-(adj*right))

      newAxis.set_ylabel(axis)
      self.axislist[axis]=newAxis




  def callback(self, verts):
      seldatetimes= [matplotlib.dates.num2date(x[0]) for x in verts]
      #print seldatetimes

      # self.parent.record_service.select_points(datetime_list=seldatetimes)

      p = path.Path(verts)
      ind = p.contains_points(self.xys)
      self.changeSelection(ind)

      self.canvas.draw_idle()
      self.canvas.widgetlock.release(self.lasso)
      del self.lasso



  def onpress(self, event):
      if self.canvas.widgetlock.locked(): return
      if event.inaxes is None: return
      self.lasso = Lasso(event.inaxes, (event.xdata, event.ydata), self.callback)
      # acquire a lock on the widget drawing
      self.canvas.widgetlock(self.lasso)


  def __init__(self, parent, id, pos, size, style, name):
      self._init_ctrls(parent)
Ejemplo n.º 13
0
class CTRL_Graphique(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self,
                          parent,
                          -1,
                          style=wx.TAB_TRAVERSAL | wx.SUNKEN_BORDER)
        self.dictParametres = None
        self.afficher_valeurs = False

        # Init canvas
        self.figure = matplotlib.pyplot.figure()
        self.canvas = Canvas(self, -1, self.figure)
        self.canvas.SetMinSize((20, 20))
        self.SetColor((255, 255, 255))

        # Layout
        sizer_canvas = wx.BoxSizer(wx.VERTICAL)
        sizer_canvas.Add(self.canvas, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_canvas)
        self.Layout()

    def OnBoutonZoom(self, event):
        import DLG_Zoom_graphe
        dlg = DLG_Zoom_graphe.Dialog(self, figure=self.figure)
        dlg.ShowModal()
        dlg.Destroy()

    def OnBoutonOptions(self, event):
        # Création du menu contextuel
        menuPop = UTILS_Adaptations.Menu()

        item = wx.MenuItem(menuPop, 10, _(u"Afficher les valeurs"),
                           _(u"Afficher les valeurs"), wx.ITEM_CHECK)
        menuPop.AppendItem(item)
        self.Bind(wx.EVT_MENU, self.On_afficher_valeurs, id=10)
        if self.afficher_valeurs == True: item.Check(True)

        self.PopupMenu(menuPop)
        menuPop.Destroy()

    def On_afficher_valeurs(self, event):
        self.afficher_valeurs = not self.afficher_valeurs
        self.MAJ()

    def SetColor(self, rgbtuple=None):
        """Set figure and canvas colours to be the same."""
        if rgbtuple is None:
            rgbtuple = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get()
        clr = [c / 255. for c in rgbtuple]
        self.figure.set_facecolor(clr)
        self.figure.set_edgecolor(clr)
        self.canvas.SetBackgroundColour(wx.Colour(*rgbtuple))

    def ConvertCouleur(self, couleur=None):
        return [c / 255. for c in couleur]

    def SetParametres(self, dictParametres=None):
        self.dictParametres = dictParametres

    def MAJ(self):
        self.figure.clear()
        if self.dictParametres == None:
            wx.CallAfter(self.SendSizeEvent)
            return

        if self.dictParametres[
                "IDmodele"] == "repartition_categories_debit_tresorerie":
            self.Graphe_repartition_categories(typeCategorie="debit",
                                               typeDonnees="tresorerie")
        if self.dictParametres[
                "IDmodele"] == "repartition_categories_credit_tresorerie":
            self.Graphe_repartition_categories(typeCategorie="credit",
                                               typeDonnees="tresorerie")
        if self.dictParametres[
                "IDmodele"] == "repartition_categories_debit_budgetaires":
            self.Graphe_repartition_categories(typeCategorie="debit",
                                               typeDonnees="budgetaires")
        if self.dictParametres[
                "IDmodele"] == "repartition_categories_credit_budgetaires":
            self.Graphe_repartition_categories(typeCategorie="credit",
                                               typeDonnees="budgetaires")
        if self.dictParametres[
                "IDmodele"] == "repartition_categories_debit_tresorerie_budgetaires":
            self.Graphe_repartition_categories(
                typeCategorie="debit", typeDonnees="tresorerie+budgetaires")
        if self.dictParametres[
                "IDmodele"] == "repartition_categories_credit_tresorerie_budgetaires":
            self.Graphe_repartition_categories(
                typeCategorie="credit", typeDonnees="tresorerie+budgetaires")
        if self.dictParametres["IDmodele"] == "tiers_debit":
            self.Graphe_tiers(typeCategorie="debit")
        if self.dictParametres["IDmodele"] == "tiers_credit":
            self.Graphe_tiers(typeCategorie="credit")
        self.Layout()

    def Graphe_repartition_categories(self,
                                      typeCategorie="",
                                      typeDonnees="tresorerie+budgetaires"):
        # Récupération des données
        conditions = []
        if self.dictParametres["date_debut"] != None:
            conditions.append("date_budget>='%s'" %
                              self.dictParametres["date_debut"])
            conditions.append("date_budget<='%s'" %
                              self.dictParametres["date_fin"])
        if self.dictParametres["IDanalytique"] != None:
            conditions.append("IDanalytique=%d" %
                              self.dictParametres["IDanalytique"])
        if len(conditions) > 0:
            ConditionsStr = "AND " + " AND ".join(conditions)
        else:
            ConditionsStr = ""

        DB = GestionDB.DB()
        dictDonnees = {}

        if "budgetaires" in typeDonnees:
            req = """SELECT compta_operations_budgetaires.IDcategorie, compta_categories.nom, SUM(compta_operations_budgetaires.montant)
            FROM compta_operations_budgetaires
            LEFT JOIN compta_categories ON compta_categories.IDcategorie = compta_operations_budgetaires.IDcategorie
            WHERE compta_operations_budgetaires.type='%s' %s
            GROUP BY compta_operations_budgetaires.IDcategorie
            ;""" % (typeCategorie, ConditionsStr)
            DB.ExecuterReq(req)
            listeDonnees = DB.ResultatReq()
            for IDcategorie, nom, montant in listeDonnees:
                if dictDonnees.has_key(IDcategorie) == False:
                    dictDonnees[IDcategorie] = {"nom": nom, "montant": 0.0}
                dictDonnees[IDcategorie]["montant"] += montant

        if "tresorerie" in typeDonnees:
            req = """SELECT compta_ventilation.IDcategorie, compta_categories.nom, SUM(compta_ventilation.montant)
            FROM compta_ventilation
            LEFT JOIN compta_categories ON compta_categories.IDcategorie = compta_ventilation.IDcategorie
            WHERE type='%s' %s
            GROUP BY compta_ventilation.IDcategorie
            ;""" % (typeCategorie, ConditionsStr)
            DB.ExecuterReq(req)
            listeDonnees = DB.ResultatReq()
            for IDcategorie, nom, montant in listeDonnees:
                if dictDonnees.has_key(IDcategorie) == False:
                    dictDonnees[IDcategorie] = {"nom": nom, "montant": 0.0}
                dictDonnees[IDcategorie]["montant"] += montant

        DB.Close()
        if len(dictDonnees) == 0:
            return

        listeValeurs = []
        listeLabels = []
        listeCouleurs = []

        montantTotal = 0.0
        for IDcategorie, dictTemp in dictDonnees.iteritems():
            montantTotal += dictTemp["montant"]

        index = 1
        for IDcategorie, dictTemp in dictDonnees.iteritems():
            listeValeurs.append(dictTemp["montant"])
            label = dictTemp["nom"]
            if self.afficher_valeurs == True:
                label += u"\n%.2f %s" % (float(montant), SYMBOLE)
            listeLabels.append(label)

            couleur = 1.0 * montant / montantTotal
            couleur = matplotlib.cm.hsv(index * 0.1)
            listeCouleurs.append(couleur)

            index += 1

        # Création du graphique
        ax = self.figure.add_subplot(111)
        cam = ax.pie(listeValeurs,
                     labels=listeLabels,
                     colors=listeCouleurs,
                     autopct='%1.1f%%',
                     shadow=False)
        title = ax.set_title(
            self.dictParametres["nom"],
            weight="bold",
            horizontalalignment='center')  #, position=(0.5, 0.97))
        matplotlib.pyplot.setp(title, rotation=0, fontsize=11)
        ax.set_aspect(1)
        labels, labelsPourcent = cam[1], cam[2]
        matplotlib.pyplot.setp(labels, rotation=0, fontsize=11)
        matplotlib.pyplot.setp(labelsPourcent, rotation=0, fontsize=9)

        # Finalisation
        ax.autoscale_view('tight')
        ax.figure.canvas.draw()
        wx.CallAfter(self.SendSizeEvent)

    def Graphe_tiers(self, typeCategorie=""):
        # Récupération des données
        conditions = []
        if self.dictParametres["date_debut"] != None:
            conditions.append("date_budget>='%s'" %
                              self.dictParametres["date_debut"])
            conditions.append("date_budget<='%s'" %
                              self.dictParametres["date_fin"])
        if self.dictParametres["IDanalytique"] != None:
            conditions.append("IDanalytique=%d" %
                              self.dictParametres["IDanalytique"])
        if len(conditions) > 0:
            ConditionsStr = "AND " + " AND ".join(conditions)
        else:
            ConditionsStr = ""

        DB = GestionDB.DB()
        req = """SELECT compta_tiers.IDtiers, compta_tiers.nom, SUM(compta_ventilation.montant)
        FROM compta_tiers
        LEFT JOIN compta_operations ON compta_operations.IDtiers = compta_tiers.IDtiers
        LEFT JOIN compta_ventilation ON compta_ventilation.IDoperation = compta_operations.IDoperation
        WHERE type='%s' %s
        GROUP BY compta_tiers.IDtiers
        ;""" % (typeCategorie, ConditionsStr)
        DB.ExecuterReq(req)
        listeDonnees = DB.ResultatReq()
        DB.Close()
        if len(listeDonnees) == 0:
            return

        listeValeurs = []
        listeLabels = []
        listeCouleurs = []

        for IDtiers, nom, montant in listeDonnees:
            listeValeurs.append(montant)
            listeLabels.append(nom)

        listeIndex = np.arange(len(listeLabels))
        bar_height = 0.2
        opacity = 0.4

        ax = self.figure.add_subplot(111)
        barres = ax.barh(listeIndex,
                         listeValeurs,
                         height=bar_height,
                         align='center',
                         alpha=opacity)

        # Formatage des montants sur x
        majorFormatter = FormatStrFormatter(u"%d " + SYMBOLE)
        ax.xaxis.set_major_formatter(majorFormatter)

        # Affichage des labels x
        ax.set_yticks(listeIndex)
        ax.set_yticklabels(listeLabels)

        def autolabel(rects):
            # attach some text labels
            for rect in rects:
                width = rect.get_width()
                ax.text(width + 10,
                        rect.get_y() + rect.get_height() / 2.,
                        u"%.2f %s" % (int(width), SYMBOLE),
                        ha='left',
                        va='center',
                        fontsize=8,
                        color="grey")

        if self.afficher_valeurs == True:
            autolabel(barres)

        # Recherche la largeur de texte max
        largeurMax = 0
        for label in listeLabels:
            if len(label) > largeurMax:
                largeurMax = len(label)

        # Espaces autour du graph
        margeGauche = 0.1 + largeurMax * 0.008
        self.figure.subplots_adjust(left=margeGauche,
                                    right=None,
                                    wspace=None,
                                    hspace=None)

        # Finalisation
        ax.autoscale_view('tight')
        ##        ax.grid(True)
        ax.figure.canvas.draw()
        wx.CallAfter(self.SendSizeEvent)
        return

        # Récupération des données
        from Ol import OL_Suivi_budget
        analyse = OL_Suivi_budget.Analyse(self.dictBudget)
        listeCategories = analyse.GetValeurs()

        listeRealise = []
        listeBudgete = []
        listeLabels = []

        for dictCategorie in listeCategories:
            listeRealise.append(dictCategorie["realise"])
            listeBudgete.append(dictCategorie["plafond"])
            listeLabels.append(dictCategorie["nomCategorie"])

##            if dictCategorie["typeCategorie"] == "debit" :
##                solde = plafond - realise
##            else :
##                solde = realise - plafond

##        # TEST
##        listeIndex = np.arange(len(listeLabels))
##        bar_width = 0.2
##        opacity = 0.4
##
##        ax = self.figure.add_subplot(111)
##        barres = ax.bar(listeIndex, listeRealise, width=bar_width, alpha=opacity, color="g", label=_(u"Réel"))
##        barres = ax.bar(listeIndex + bar_width, listeBudgete, width=bar_width, alpha=opacity, color="b", label=_(u"Budgété"))
##
##        # Formatage des montants sur y
##        majorFormatter = FormatStrFormatter(SYMBOLE + u" %d")
##        ax.yaxis.set_major_formatter(majorFormatter)
##
##        # Affichage des labels x
##        ax.set_xticks(listeIndex + bar_width)
##        ax.set_xticklabels(listeLabels)
##
##        labels = ax.get_xticklabels()
##        setp(labels, rotation=45)
##
##        # Légende
##        props = matplotlib.font_manager.FontProperties(size=10)
##        leg = ax.legend(loc='best', shadow=False, fancybox=True, prop=props)
##        leg.get_frame().set_alpha(0.5)
##
##        # Espaces autour du graph
##        self.figure.subplots_adjust(left=0.12, bottom=0.40, right=None, wspace=None, hspace=None)

# TEST
        listeIndex = np.arange(len(listeLabels))
        bar_height = 0.2
        opacity = 0.4

        ax = self.figure.add_subplot(111)
        barresRealise = ax.barh(listeIndex,
                                listeRealise,
                                height=bar_height,
                                alpha=opacity,
                                color="g",
                                label=_(u"Réel"))
        barresBudgete = ax.barh(listeIndex + bar_height,
                                listeBudgete,
                                height=bar_height,
                                alpha=opacity,
                                color="b",
                                label=_(u"Budgété"))

        # Formatage des montants sur x
        majorFormatter = FormatStrFormatter(u"%d " + SYMBOLE)
        ax.xaxis.set_major_formatter(majorFormatter)

        # Affichage des labels x
        ax.set_yticks(listeIndex + bar_height)
        ax.set_yticklabels(listeLabels)

        def autolabel(rects):
            # attach some text labels
            for rect in rects:
                width = rect.get_width()
                ax.text(width + 20,
                        rect.get_y() + rect.get_height() / 2.,
                        u"%.2f %s" % (int(width), SYMBOLE),
                        ha='left',
                        va='center',
                        fontsize=8,
                        color="grey")

        if self.afficher_valeurs == True:
            autolabel(barresRealise)
            autolabel(barresBudgete)

        # Recherche la largeur de texte max
        largeurMax = 0
        for label in listeLabels:
            if len(label) > largeurMax:
                largeurMax = len(label)

        # Espaces autour du graph
        margeGauche = 0.1 + largeurMax * 0.008
        self.figure.subplots_adjust(left=margeGauche,
                                    right=None,
                                    wspace=None,
                                    hspace=None)

        # Légende
        props = matplotlib.font_manager.FontProperties(size=10)
        leg = ax.legend(loc='best', shadow=False, fancybox=True, prop=props)
        leg.get_frame().set_alpha(0.5)

        # Finalisation
        ax.autoscale_view('tight')
        ax.grid(True)
        ax.figure.canvas.draw()
        wx.CallAfter(self.SendSizeEvent)
        return
Ejemplo n.º 14
0
class plotProb(wx.Panel):
    def _init_coll_boxSizer1_Items(self, parent):
        # generated method, don't edit

        parent.AddWindow(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        parent.AddWindow(self.toolbar, 0, wx.EXPAND)

    def _init_sizers(self):
        # generated method, don't edit
        self.boxSizer1 = wx.BoxSizer(orient=wx.VERTICAL)
        self._init_coll_boxSizer1_Items(self.boxSizer1)
        self.SetSizer(self.boxSizer1)

    def Clear(self):
        self.plot.clear()

    def _init_ctrls(self, prnt):
        #matplotlib.figure.Figure.__init__(self)
        wx.Panel.__init__(self, prnt, -1)

        self.figure = matplotlib.figure.Figure()
        self.plot = self.figure.add_subplot(111)
        self.plot.axis([0, 1, 0, 1])  #
        self.plot.plot([], [])
        self.plot.set_title("No Data To Plot")

        self.canvas = FigCanvas(self, -1, self.figure)
        # Create the navigation toolbar, tied to the canvas
        self.toolbar = NavigationToolbar(self.canvas)
        self.toolbar.Realize()

        #self.canvas.SetCursor(wx.StockCursor(wx.CURSOR_CROSS))
        #self.canvas.SetScrollbar(wx.HORIZONTAL, 0,5, 1000)
        self.SetColor("WHITE")
        self.canvas.SetFont(
            wx.Font(20, wx.SWISS, wx.NORMAL, wx.NORMAL, False, u'Tahoma'))

        self.fontP = FontProperties()
        self.fontP.set_size('small')

        self.canvas.draw()

        self._init_sizers()

    def OnPlotType(self, ptype):
        # self.timeSeries.clear()
        if ptype == "line":
            ls = '-'
            m = 'None'
        elif ptype == "point":
            ls = 'None'
            m = 's'
        else:
            ls = '-'
            m = 's'
        # print plt.setp(self.lines)
        # print(len(self.lines))
        format = ls + m
        for line in self.lines:
            plt.setp(line, linestyle=ls, marker=m)

        self.canvas.draw()

    def OnShowLegend(self, isVisible):
        # print self.timeSeries.show_legend
        if isVisible:
            plt.subplots_adjust(bottom=.1 + .1)
            self.plot.legend(loc='upper center',
                             bbox_to_anchor=(0.5, -0.05),
                             ncol=2,
                             prop=self.fontP)

        else:
            plt.subplots_adjust(bottom=.1)
            self.plot.legend_ = None
        # self.timeSeries.plot(legend= not isVisible)
        self.canvas.draw()

    def Plot(self, seriesPlotInfo):
        self.seriesPlotInfo = seriesPlotInfo
        self.updatePlot()

    def updatePlot(self):
        self.Clear()
        count = self.seriesPlotInfo.count()
        self.lines = []
        self.plot = self.figure.add_subplot(111)
        for oneSeries in self.seriesPlotInfo.GetSeriesInfo():

            self.plot.set_xlabel("Cumulative Frequency < Stated Value %")
            if count > 1:
                self.plot.set_ylabel("\n".join(
                    textwrap.wrap(oneSeries.axisTitle, 50)))
                self.plot.set_title("")

            else:
                self.plot.set_ylabel("\n".join(
                    textwrap.wrap(oneSeries.axisTitle, 50)))
                self.plot.set_title("\n".join(
                    textwrap.wrap(oneSeries.plotTitle, 55)))

            self.lines.append(
                self.plot.plot(oneSeries.Probability.Xaxis,
                               oneSeries.Probability.Yaxis,
                               'bs',
                               color=oneSeries.color,
                               label=oneSeries.plotTitle))

        self.setXaxis()

        if count > 1:
            plt.subplots_adjust(bottom=.1 + .1)
            self.plot.legend(loc='upper center',
                             bbox_to_anchor=(0.5, -0.05),
                             ncol=2,
                             prop=self.fontP)

        else:
            plt.subplots_adjust(bottom=.1)
            self.plot.legend_ = None
        self.canvas.draw()

    def addPlot(self, cursor, series, Filter):

        # self.cursor = Values[0]
        self.cursor = cursor

        self.cursor.execute("SELECT DataValue FROM DataValues" + Filter)
        self.dataValues = [x[0] for x in self.cursor.fetchall()]

        # self.Series= Values[1]
        self.Series = series

        self.plot.clear()

        length = len(self.dataValues)

        self.Yaxis = sorted(self.dataValues)
        self.Xaxis = []
        for it in range(0, length):
            #curValue = datavalues[it]
            curFreq = self.CalcualteProbabilityFreq(it + 1, length)
            curX = self.CalculateProbabilityXPosition(curFreq)
            #self.Yaxis.append(curValue)
            self.Xaxis.append(curX)

        #print self.Xaxis

    # print self.Yaxis

        self.plot.clear()
        x = range(len(self.Xaxis))
        self.plot.set_xlabel("Cumulative Frequency < Stated Value %")
        self.plot.set_ylabel("\n".join(
            textwrap.wrap(
                self.Series.variable_name + "(" +
                self.Series.variable_units_name + ")", 50)))
        self.plot.set_title("\n".join(
            textwrap.wrap(
                self.Series.site_name + " " + self.Series.variable_name, 55)))

        self.plot = self.figure.add_subplot(111)
        self.lines = self.plot.plot(self.Xaxis, self.Yaxis, 'bs')

        self.setXaxis()
        self.canvas.draw()

    def setXaxis(self):

        self.plot.set_xticklabels([
            "0.01", "0.02", "0.02", "1", "2", "5", "10", "20", "30", "40",
            "50", "60", "70", "80", "90", "95", "98", "99", "99.9", "99.98",
            "99.99"
        ])
        self.plot.set_xticks([
            -3.892, -3.5, -3.095, -2.323, -2.055, -1.645, -1.282, -0.842,
            -0.542, -0.254, 0, 0.254, 0.542, 0.842, 1.282, 1.645, 2.055, 2.323,
            3.095, 3.5, 3.892
        ])
        self.plot.set_xbound(-4, 4)

    def SetColor(self, color):
        """Set figure and canvas colours to be the same."""
        self.figure.set_facecolor(color)
        self.figure.set_edgecolor(color)
        self.canvas.SetBackgroundColour(color)

    def CalculateProbabilityXPosition(self, freq):
        try:
            return round(4.91 * ((freq**.14) - (1.00 - freq)**.14), 3)
        except:
            print "An error occurred while calculating the X-Position for a point in the prob plot"
            pass

    def CalcualteProbabilityFreq(self, rank, numRows):
        try:
            return round((rank - .0375) / (numRows + 1 - (2 * 0.375)), 3)
        except:
            print "An error occured while calculating the frequency for a point in the prob plot"
            pass

    def __init__(self, parent, id, pos, size, style, name):
        self._init_ctrls(parent)
Ejemplo n.º 15
0
class PlotBox(wx.Panel):
    def _init_coll_boxSizer1_Items(self, parent):
        # generated method, don't edit

        parent.AddWindow(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        parent.AddWindow(self.toolbar, 0, wx.EXPAND)

    def _init_sizers(self):
        # generated method, don't edit
        self.boxSizer1 = wx.BoxSizer(orient=wx.VERTICAL)
        self._init_coll_boxSizer1_Items(self.boxSizer1)
        self.SetSizer(self.boxSizer1)

    def _init_ctrls(self, prnt):
        # matplotlib.figure.Figure.__init__(self)
        wx.Panel.__init__(self, prnt, -1)

        Publisher.subscribe(self.monthly, ("box.Monthly"))
        Publisher.subscribe(self.yearly, ("box.Yearly"))
        Publisher.subscribe(self.seasonaly, ("box.Seasonal"))
        Publisher.subscribe(self.overall, ("box.Overall"))

        self.figure = Figure()
        # self.figure = plt.figure()

        plot = self.figure.add_subplot(111)
        #self.plot.axis([0, 1, 0, 1])  #
        plot.set_title("No Data To Plot")

        self.canvas = FigCanvas(self, -1, self.figure)
        # Create the navigation toolbar, tied to the canvas
        self.toolbar = NavigationToolbar(self.canvas, True)
        self.toolbar.Realize()
        self.figure.tight_layout()

        self.setColor("WHITE")
        self.canvas.SetFont(
            wx.Font(15, wx.SWISS, wx.NORMAL, wx.NORMAL, False, u'Tahoma'))

        self.canvas.draw()
        self._init_sizers()

    def clear(self):
        self.figure.clear()

    def close(self):
        self.figure.clf()
        # plt.close('all')

    def gridSize(self, cells):
        rows = 1
        cols = 1
        while rows * cols < cells:
            if rows == cols:
                cols = cols + 1
            else:
                rows = rows + 1
        return rows, cols

    def textSize(self, cells):
        wrap = 40
        wrap = wrap - (cells * 3)
        text = 20 - cells
        return wrap, text

    def Plot(self, seriesPlotInfo):
        self.seriesPlotInfo = seriesPlotInfo
        self.updatePlot()

    def updatePlot(self):
        self.clear()

        rows, cols = self.gridSize(self.seriesPlotInfo.count())
        # self.figure, self.axes = plt.subplots(nrows=rows, ncols=cols)

        i = 1
        for oneSeries in self.seriesPlotInfo.getAllSeries():
            if len(oneSeries.dataTable) > 0:
                self._createPlot(oneSeries, rows, cols, i)
                i += 1

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

    def _createPlot(self, oneSeries, rows, cols, index):

        ax = self.figure.add_subplot(repr(rows) + repr(cols) + repr(index))

        med = oneSeries.BoxWhisker.currinterval.medians
        ci = oneSeries.BoxWhisker.currinterval.confint
        mean = oneSeries.BoxWhisker.currinterval.means
        cl = oneSeries.BoxWhisker.currinterval.conflimit

        # Plot Means confidence level
        for x in range(len(mean)):
            ax.vlines(x + 1, cl[x][0], cl[x][1], color='r', linestyle="solid")
        # Plot Mean
        ax.scatter([range(1, len(mean) + 1)], mean, marker='o', c='r', s=10)

        # Plot Median
        ax.scatter([range(1, len(med) + 1)], med, marker='s', c="k", s=10)

        # bp = onSeries.dataTable.boxplot(
        bp = oneSeries.dataTable[
            oneSeries.dataTable["DataValue"] != oneSeries.noDataValue].boxplot(
                column="DataValue",
                ax=ax,
                by=oneSeries.BoxWhisker.currinterval.groupby,
                rot=35,
                notch=True,
                sym="-s",
                conf_intervals=ci,
                return_type='dict',
                grid=False)

        # Set Colors of the Box Whisker plot
        try:
            plt.setp(bp['DataValue']['whiskers'], color='k', linestyle='-')
            plt.setp(bp['DataValue']['medians'], color='k', linestyle='-')
            plt.setp(bp['DataValue']['boxes'], color='GREY', linestyle='-')
            plt.setp(bp['DataValue']['caps'], color='k')
            plt.setp(bp['DataValue']['fliers'],
                     markersize=3.5,
                     color=oneSeries.color)
        except:
            plt.setp(bp['whiskers'], color='k', linestyle='-')
            plt.setp(bp['medians'], color='k', linestyle='-')
            plt.setp(bp['boxes'], color='GREY', linestyle='-')
            plt.setp(bp['caps'], color='k')
            plt.setp(bp['fliers'], markersize=3.5, color=oneSeries.color)

        #Labels

        ax.set_xticklabels(
            [x for x in oneSeries.BoxWhisker.currinterval.xlabels])
        # set the text of the first few minor ticks created by pandas.plot

        # remove the minor xtick labels set by pandas.plot
        ax.set_xticklabels([], minor=True)
        # turn the minor ticks created by pandas.plot off
        # plt.minorticks_off()

        wrap, text = self.textSize(self.seriesPlotInfo.count())
        self.canvas.SetFont(
            wx.Font(text, wx.SWISS, wx.NORMAL, wx.NORMAL, False, u'Tahoma'))
        ax.set_xlabel("\n".join(
            textwrap.wrap(oneSeries.BoxWhisker.currinterval.title, wrap)))

        ax.set_ylabel("\n".join(
            textwrap.wrap(
                oneSeries.variableName + "\n (" + oneSeries.variableUnits +
                ")", wrap)))

        self.figure.suptitle("")
        ax.set_title("\n".join(textwrap.wrap(oneSeries.siteName, wrap)))

    def setColor(self, color):
        # """Set figure and canvas colours to be the same."""
        self.figure.set_facecolor(color)
        self.figure.set_edgecolor(color)
        self.canvas.SetBackgroundColour(color)

    def monthly(self, str):
        # print "monthly"
        self.seriesPlotInfo.setBoxInterval("Month")
        self.updatePlot()

    def seasonaly(self, str):
        # print"seasonal"
        self.seriesPlotInfo.setBoxInterval("Season")
        self.updatePlot()

    def yearly(self, str):
        # print "yearly"
        self.seriesPlotInfo.setBoxInterval("Year")
        self.updatePlot()

    def overall(self, str):
        # print "overall"
        self.seriesPlotInfo.setBoxInterval("Overall")
        self.updatePlot()

    def __init__(self, parent, id, pos, size, style, name):
        self._init_ctrls(parent)
Ejemplo n.º 16
0
class plotHist(wx.Panel):
    def _init_coll_boxSizer1_Items(self, parent):
        # generated method, don't edit

        parent.AddWindow(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        parent.AddWindow(self.toolbar, 0, wx.EXPAND)


    def _init_sizers(self):
        # generated method, don't edit
        self.boxSizer1 = wx.BoxSizer(orient=wx.VERTICAL)
        self._init_coll_boxSizer1_Items(self.boxSizer1)
        self.SetSizer(self.boxSizer1)


    def _init_ctrls(self, prnt):
        # matplotlib.figure.Figure.__init__(self)
        wx.Panel.__init__(self, prnt, -1)

        self.figure = Figure()

        plot = self.figure.add_subplot(111)
        plot.set_title("No Data To Plot")

        self.canvas = FigCanvas(self, -1, self.figure)
        # Create the navigation toolbar, tied to the canvas
        self.toolbar = NavigationToolbar(self.canvas, True)
        self.toolbar.Realize()
        self.figure.tight_layout()

        self.setColor("WHITE")
        self.canvas.SetFont(wx.Font(20, wx.SWISS, wx.NORMAL, wx.NORMAL,
                                    False, u'Tahoma'))
        self.canvas.draw()
        self._init_sizers()

        self.bins = 50


    def changeNumOfBins(self, bins):
        self.bins = bins
        self.updatePlot()


    def clear(self):
        self.figure.clear()
        # plt.clear()


    def gridSize(self, cells):
        rows = 1
        cols = 1
        while rows * cols < cells:
            if rows == cols:
                cols = cols + 1
            else:
                rows = rows + 1
        return rows, cols

    def textSize(self, cells):
        wrap = 50
        wrap = wrap - (cells * 3)
        text = 20 - cells
        return wrap, text

    def Plot(self, seriesPlotInfo):
        self.seriesPlotInfo = seriesPlotInfo
        self.updatePlot()

    def updatePlot(self):
        self.clear()
        rows, cols = self.gridSize(self.seriesPlotInfo.count())
        logger.debug("Rows: %s, cols: %s" % (rows,cols))

        i = 1
        for oneSeries in self.seriesPlotInfo.getAllSeries():
            if len(oneSeries.dataTable) > 0:
                self._createPlot(oneSeries, rows, cols, i)
                i += 1

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


    def _createPlot(self, oneSeries, rows, cols, index):
        ax = self.figure.add_subplot(repr(rows) + repr(cols) + repr(index))

        logger.debug("HISTOGRAM: %s"% ax)

        # oneSeries.filteredData.hist(ax= ax, color='k', alpha=0.5, bins=50)

        his = oneSeries.dataTable.hist(column="DataValue", ax=ax, bins=self.bins,
                                          facecolor=oneSeries.color,
                                          label=oneSeries.siteName + " " + oneSeries.variableName,
                                          grid=False)

        wrap, text = self.textSize(self.seriesPlotInfo.count())
        ax.set_xlabel("\n".join(textwrap.wrap(oneSeries.variableName, wrap)))
        ax.set_ylabel("Number of Observations")

        self.canvas.SetFont(wx.Font(text, wx.SWISS, wx.NORMAL, wx.NORMAL,
                                    False, u'Tahoma'))
        ax.set_title("\n".join(textwrap.wrap(oneSeries.siteName, wrap)))


    def setColor(self, color):
        """Set figure and canvas colours to be the same."""
        self.figure.set_facecolor(color)
        self.figure.set_edgecolor(color)
        self.canvas.SetBackgroundColour(color)


    def __init__(self, parent, id, pos, size, style, name):
        self._init_ctrls(parent)
Ejemplo n.º 17
0
class PlotPanel(wx.Panel):
    '''
    Principal Component Analysis (PCA) plot (PCA1 against PCA2) GUI
    '''
    def __init__(self, parent, id=-1, dpi=None, **kwargs):
        wx.Panel.__init__(self, parent, id=id, **kwargs)
        self.figure = Figure(dpi=dpi, figsize=(2, 2))
        self.canvas = Canvas(self, -1, self.figure)
        self.figure.set_facecolor((1, 1, 1))
        self.figure.set_edgecolor((1, 1, 1))
        self.canvas.SetBackgroundColour('white')
        self.subplot = self.figure.add_subplot(111)
        self.plot_scores = None
        self.class_masks = None
        self.class_names = None
        self.Loadings = None
        self.object_opacity = None
        self.object_accuracies = None
        self.leg = None
        self.maskedPCA1 = None
        self.maskedPCA2 = None
        self.axes = None

        # If the script is loaded from ClassifierGUI, load the classification weaklearners
        try:
            self.classifier = classifier
            self.classifier_rules = classifier.algorithm.weak_learners
        except:
            self.classifier_rules = [('None', 0, np.array([0, 0]))]

        self.chMap = p.image_channel_colors
        self.toolbar = NavigationToolbar2Wx(self.canvas)
        self.toolbar.Realize()
        POSITION_OF_CONFIGURE_SUBPLOTS_BTN = 6
        self.toolbar.DeleteToolByPos(POSITION_OF_CONFIGURE_SUBPLOTS_BTN)

        self.statusBar = wx.StatusBar(self, -1)
        self.statusBar.SetFieldsCount(1)
        self.motion_event_active = False
        self.canvas.mpl_connect('motion_notify_event', self.update_status_bar)
        self.canvas.mpl_connect('button_press_event', self.on_open_image)

        self.hide_legend_btn = wx.Button(self, -1, " Hide legend ")
        wx.EVT_BUTTON(self.hide_legend_btn, -1, self.hide_show_legend)
        self.hide_legend = True

        tools_sizer = wx.BoxSizer(wx.HORIZONTAL)
        tools_sizer.Add(self.toolbar, 0, wx.RIGHT | wx.EXPAND)
        tools_sizer.AddSpacer(5)
        tools_sizer.Add(self.hide_legend_btn, 0, wx.LEFT | wx.EXPAND)
        tools_sizer.AddSpacer(5)
        tools_sizer.Add(self.statusBar, 0, wx.LEFT | wx.EXPAND)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.canvas, 1, wx.EXPAND)
        sizer.Add(tools_sizer, 0, wx.EXPAND)
        self.SetSizer(sizer)

    def set_plot_type(self, plot_scores):
        '''
        Set the plot type (Scores. Loadings) for each notebook page
        '''
        self.plot_scores = plot_scores

    def set_colormap(self, class_array):
        '''
        Set the colormap based on the number of different classes to plot
        '''
        self.colormap = cm.get_cmap('hsv')
        num_colors = len(class_array)
        class_value = np.array(list(range(1, (num_colors + 2))),
                               dtype='float') / num_colors
        color_set = np.array(self.colormap(class_value))
        return color_set

    def on_open_image(self, event):
        if event.button == 2 and self.plot_scores == "Scores" and event.inaxes:
            self.open_image()

    def open_image(self):
        '''
        Open the image of the selected cell in the Scores plot
        '''
        imViewer = ShowImage(self.actual_key[:-1],
                             self.chMap[:],
                             parent=self.classifier,
                             brightness=1.0,
                             contrast=None)
        imViewer.imagePanel.SelectPoint(db.GetObjectCoords(self.actual_key))

    def hide_show_legend(self, event):
        '''
        Hide or show the legend on the canvas by pressing the button
        '''
        if self.leg is not None:
            if self.hide_legend:
                self.leg.set_visible(False)
                self.figure.canvas.draw()
                self.hide_legend = False
                self.hide_legend_btn.SetLabel(label='Show legend')
            else:
                self.leg.set_visible(True)
                self.figure.canvas.draw()
                self.hide_legend = True
                self.hide_legend_btn.SetLabel(label=' Hide legend ')

    def update_status_bar(self, event):
        '''
        Show the key for the nearest object (measured as the Euclidean distance) to the mouse pointer in the 
        plot (scores pdimensredux.PlotPanel.__init__dimensredux.PlotPanel.__init__lot) or the nearest feature 
        (loadings plot)
        '''
        if event.inaxes and self.motion_event_active:
            x, y = event.xdata, event.ydata
            if self.plot_scores == "Scores":
                dist = np.hypot((x - self.Scores[:, 0]),
                                (y - self.Scores[:, 1]))
                object_dict_key = np.where(dist == np.amin(dist))
                xy_key = int(object_dict_key[0][0])
                if self.object_accuracies:
                    errorData = ', CA = %0.1f%%' % (
                        (1 - self.object_opacity[xy_key]) * 100.0)
                else:
                    errorData = ''
                self.statusBar.SetStatusText(
                    ("Object key = " + str(self.data_dic[xy_key]) + errorData),
                    0)
                self.actual_key = self.data_dic[xy_key]
            elif self.plot_scores == "Loadings":
                dist = np.hypot((x - self.Loadings[0]), (y - self.Loadings[1]))
                feature_dict_key = np.where(dist == np.amin(dist))
                xy_key = int(feature_dict_key[0])
                feat_text = self.features_dic[xy_key].split('_')
                self.statusBar.SetStatusText(('_'.join(feat_text[1:])), 0)

    def plot_pca(self):
        '''
        Plot the Principal Component Analysis scores (cells) and loadings (features)
        along with the percentage of data variance the scores represent
        '''
        self.subplot.clear()
        # Only obtain class data from the database if no data is available yet
        if self.class_masks is None or self.class_names is None:
            self.class_masks, self.class_names = self.create_class_masks()
        self.data = np.nan_to_num(self.data)  # Eliminate NaNs

        # Calculate PCA-SVD and mask data with class information
        centered = self.mean_center(self.data)
        U, S, self.Loadings, explained_variance = self.pca_svd(
            centered, 100, True)
        self.Scores = np.array(U[:, 0:2])
        self.maskedPCA1, self.maskedPCA2 = self.mask_data(
            len(self.class_names), self.class_masks, self.Scores)
        self.axes = explained_variance[0:2]
        self.color_set = self.set_colormap(self.class_names)

        # Plot the first two PCAs' Scores in the Scores canvas
        if self.plot_scores == "Scores":
            handles = []
            labels = []

            # Determine the different opacities for the objects. This is set to 1 if no opacities have been specified.
            if self.object_opacity is None:
                self.object_opacity = np.ones([self.maskedPCA1.shape[0], 1])
                self.object_accuracies = False
            elif self.object_accuracies is None:
                self.object_accuracies = True
            opacities = np.unique(self.object_opacity)
            nOpacity = len(opacities)

            # For each class and opacity combination plot the corresponding objects
            for i in range(len(self.class_names)):
                cell_count = np.shape(np.nonzero(self.maskedPCA1[:, i]))
                for j in range(nOpacity):
                    showObjects = np.where(self.object_opacity == opacities[j])
                    subHandle = self.subplot.scatter(
                        self.maskedPCA1[showObjects[0], i],
                        self.maskedPCA2[showObjects[0], i],
                        8,
                        c=self.color_set[i, :],
                        linewidth="0.25",
                        alpha=0.25 + 0.75 * opacities[j])

                    # The highest opacity objects are added to the legend
                    if opacities[j] == np.max(opacities):
                        handles.append(subHandle)
                        labels.append(self.class_names[i] + ': ' +
                                      str(cell_count[1]))

            # Construct the legend and make up the rest of the plot
            self.leg = self.subplot.legend(handles,
                                           labels,
                                           loc=4,
                                           fancybox=True,
                                           handlelength=1)
            self.leg.get_frame().set_alpha(0.25)
            x_var = round(((1 - self.axes[0]) * 100), 2)
            y_var = round(((self.axes[0] - self.axes[1]) * 100), 2)
            x_axe_var = 'Explained variance: ' + str(x_var) + '%'
            y_axe_var = 'Explained variance: ' + str(y_var) + '%'
            self.subplot.set_xlabel(x_axe_var, fontsize=12)
            self.subplot.set_ylabel(y_axe_var, fontsize=12)
            self.subplot.axhline(0, -100000, 100000, c='k', lw=0.1)
            self.subplot.axvline(0, -100000, 100000, c='k', lw=0.1)
            self.figure.canvas.draw()
        elif self.plot_scores == "Loadings":
            # Plot the first two PCAs' Loadings in the Loading canvas
            weaklearners_mask = np.zeros((np.shape(self.Loadings[0])))
            for key in list(self.features_dic.keys()):
                for value in self.classifier_rules:
                    if value[0] == self.features_dic[key]:
                        weaklearners_mask[key] += 1
            scatter_mask = weaklearners_mask + 1
            colors_mask = []
            size_mask = []
            for i in range(len(scatter_mask)):
                colors_mask.append(COLORS[int(scatter_mask[i])])
                size_mask.append((int(scatter_mask[i])**2) * 5)

            self.subplot.scatter(self.Loadings[0],
                                 self.Loadings[1],
                                 c=colors_mask,
                                 s=size_mask,
                                 linewidth="0.5",
                                 marker='o')
            self.subplot.axhline(0, -100000, 100000, c='k', lw=0.1)
            self.subplot.axvline(0, -100000, 100000, c='k', lw=0.1)
            self.figure.canvas.draw()

        self.motion_event_active = True

    def plot_tsne(self):
        ''' 
        Plot the t-Distributed Stochastic Neighbor Embedding (t-SNE) distribution of the data
        '''
        self.subplot.clear()
        self.data = np.nan_to_num(self.data)  # Eliminate NaNs
        centered = self.mean_center(self.data)
        standardized = self.standardization(centered)

        # Calculate t-SNE of the data and mask it (python t-SNE version if Intel IPP is not installed)
        try:
            from calc_tsne import calc_tsne
            U = calc_tsne(standardized, 2, 50, 20.0)
        except:
            logging.warning(
                '''Could not use fast t-SNE. You may need to install the Intel Integrated Performance Libraries. Will use normal t-SNE instead.'''
            )
            try:
                from .tsne import tsne
                U = tsne(standardized, 2, 50, 20.0)
            except:
                logging.error(
                    '''Both t-SNE versions failed. Your dataset may be too large for t-SNE to handle. Will not plot t-SNE results.'''
                )
                return

        self.Scores = U[:, 0:2]
        if self.class_masks is None or self.class_names is None:
            self.class_masks, self.class_names = self.create_class_masks()
        self.masked_X, self.masked_Y = self.mask_data(len(self.class_names),
                                                      self.class_masks,
                                                      self.Scores)

        # Plot the masked t-SNE results in the Scores canvas
        self.color_set = self.set_colormap(self.class_names)
        handles = []
        labels = []

        # Determine the different opacities for the objects. This is set to 1 if no opacities have been specified.
        if self.object_opacity is None:
            self.object_opacity = np.ones([self.masked_X.shape[0], 1])
            self.object_accuracies = False
        elif self.object_accuracies is None:
            self.object_accuracies = True
        opacities = np.unique(self.object_opacity)
        nOpacity = len(opacities)

        # For each class and opacity combination plot the corresponding objects
        for i in range(len(self.class_names)):
            cell_count = np.shape(np.nonzero(self.masked_X[:, i]))
            for j in range(nOpacity):
                showObjects = np.where(self.object_opacity == opacities[j])
                subHandle = self.subplot.scatter(self.masked_X[showObjects, i],
                                                 self.masked_Y[showObjects, i],
                                                 8,
                                                 c=self.color_set[i, :],
                                                 linewidth="0.25",
                                                 alpha=0.25 +
                                                 0.75 * opacities[j])
                # The highest opacity objects are added to the legend
                if opacities[j] == np.max(opacities):
                    handles.append(subHandle)
                    labels.append(self.class_names[i] + ': ' +
                                  str(cell_count[1]))
        self.leg = self.subplot.legend(handles,
                                       labels,
                                       loc=4,
                                       fancybox=True,
                                       handlelength=1)
        self.leg.get_frame().set_alpha(0.25)
        self.subplot.axhline(0, -100000, 100000, c='k', lw=0.1)
        self.subplot.axvline(0, -100000, 100000, c='k', lw=0.1)
        self.figure.canvas.draw()
        self.motion_event_active = True

    def clean_canvas(self):
        self.subplot.clear()

    def standardization(self, centered_data):
        '''
        Standardize data prior to calculation in order to improve 
        the performance over measurements with large differences
        in their value ranges
        '''
        standards = np.std(centered_data, 0)

        for value in standards:
            if value == 0:
                logging.error(
                    'Division by zero, cannot proceed (an object measurements in your dataset has 0 standard deviation, please check your database)'
                )
            standardized_data = centered_data / standards

        return standardized_data

    def mean_center(self, raw_data):
        '''
        Centering the measurements data around the mean is necessary prior to 
        calculation
        '''
        row, col = np.shape(raw_data)
        centered_data = raw_data
        mean_data = raw_data.mean(axis=0)
        for i in range(row):
            centered_data[i] -= mean_data
        centered_data = centered_data[:, np.var(centered_data, axis=0) != 0]

        return centered_data

    def pca_svd(self, data, PCs=100, standardize=True):
        '''
        Calculate the eigenvectors of the data array using SVD 
        (Singular Value Decomposition) method
        '''
        row, col = np.shape(data)
        if PCs > col:
            PCs = col

        if standardize:
            data = self.standardization(data)
        import time
        U, S, V = np.linalg.svd(data, full_matrices=False)

        # Calculate the percentage of data measurements variance each PCA explains
        E = data.copy()
        row, col = np.shape(E)
        explained_variance = np.zeros((PCs))
        total_explained_variance = 0
        init_total_error = np.sum(np.square(E))
        for k in range(PCs):
            T = (U[:, k].reshape(row, 1)) * S[k]
            V_t = np.transpose(V)
            P = V_t[:, k].reshape(col, 1)
            E = E - T * (np.transpose(P))
            total_error = np.sum(np.square(E))
            total_object_residual_variance = (total_error / init_total_error)
            explained_variance[
                k] = 1 - total_object_residual_variance - total_explained_variance
            total_explained_variance += explained_variance[k]

        return U, S, V, explained_variance

    def create_class_masks(self):
        '''
        Create class masks for the data based on the classification data from CPAnalyst.
        This is done in order to print Scoring plots with points in different colors
        for each class
        '''
        class_data = db.execute('SELECT class, class_number FROM %s ' \
                                'ORDER BY %s ASC, %s ASC' % (p.class_table, \
                                                             p.image_id, p.object_id))

        class_name_number = set([result for result in class_data])
        class_name_number = sorted(class_name_number, key=itemgetter(1))
        class_names = [item[0] for item in class_name_number]
        class_number = np.array([result[1] for result in class_data])
        num_classes = len(class_names)

        # In case class numbers are missing in the range (for instance some classes
        # that were available to train objects in have no objects classified in them)
        # the class numbers should be remapped
        class_ids = [item[1] for item in class_name_number]
        max_id = np.max(class_ids)
        if len(class_ids) != max_id:
            logging.info(
                'Found non-consecutive class IDs. Remapping class IDs.')
            missing_ids = np.flipud(
                np.setdiff1d(np.arange(max_id) + 1, class_ids))
            while missing_ids.shape != (0, ):
                indices = class_number >= missing_ids[0]
                class_number[indices] -= 1
                missing_ids = np.delete(missing_ids, 0)

        class_masks = np.zeros((len(class_number), num_classes))
        for i in range(len(class_number)):
            class_col = class_number[i] - 1
            class_masks[i, class_col] = 1

        return class_masks, class_names

    def mask_data(self, num_classes, class_masks, Scores):
        '''
        Mask the Score matrixes using the masks from create_class_mask
        '''
        row = np.size(Scores[:, 0])
        col = num_classes
        masked_data_X = np.zeros((row, col))
        masked_data_Y = np.zeros((row, col))
        for i in range(num_classes):
            masked_data_X[:, i] = Scores[:, 0] * class_masks[:, i]
            masked_data_Y[:, i] = Scores[:, 1] * class_masks[:, i]

        return masked_data_X, masked_data_Y
Ejemplo n.º 18
0
class PlotPanel(wx.Panel):
    """
    The PlotPanel
    """
    def __init__(self, parent, color=None, dpi=None, **kwargs):
        # initialize Panel
        if 'id' not in kwargs.keys():
            kwargs['id'] = wx.ID_ANY
        if 'style' not in kwargs.keys():
            kwargs['style'] = wx.NO_FULL_REPAINT_ON_RESIZE
        wx.Panel.__init__(self, parent, **kwargs)
        self.SetMinSize((100, 40))

        # initialize matplotlib stuff
        self.figure = Figure(None, dpi=dpi, facecolor='white')
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.canvas.SetMinSize((30, 10))
        self.SetBackgroundColour('white')

        # Add the canvas to the sizer.
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.EXPAND)
        self.SetSizer(self.sizer)

        #self.canvas.mpl_connect('button_press_event', self.onClick)
        self.canvas.Bind(wx.EVT_SET_FOCUS, self.onSetFocus)
        self.Bind(wx.EVT_SET_FOCUS, self.onSetFocus2)
        self.canvas.Bind(wx.EVT_KEY_DOWN, self.onKeyDown)
        self.Bind(wx.EVT_KEY_DOWN, self.onKeyDown)
        self.canvas.Bind(wx.EVT_KEY_UP, self.onKeyUp)
        self.Bind(wx.EVT_KEY_UP, self.onKeyUp)
        self.Bind(wx.EVT_LEFT_DOWN, self.onLeftDown)
        self.canvas.Bind(wx.EVT_LEFT_DOWN, self.onLeftDown)

    def onClick(self, event):
        print "Clicked in View. event: %s" % event.guiEvent
        event.guiEvent.ResumePropagation(1)
        event.guiEvent.Skip()

    def onWxClick(self, event):
        print "Got the WX event."

    def onSetFocus(self, event):
        print "Canvas got Focus"
        event.Skip()

    def onSetFocus2(self, event):
        print "PlotPanel got Focus"

    def onKeyDown(self, event):
        print "Propagating keyDown in plotPanel"
        event.ResumePropagation(1)
        event.Skip()

    def onKeyUp(self, event):
        print "Propagating keyUp in plotPanel"
        event.ResumePropagation(1)
        event.Skip()

    def onLeftDown(self, event):
        print "PlotPanel LEFT DOWN"
        event.ResumePropagation(30)
        event.Skip()

    def SetColor(self, rgbtuple=None):
        """Set figure and canvas colours to be the same."""
        if rgbtuple is None:
            rgbtuple = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get()
        clr = [c / 255. for c in rgbtuple]
        self.figure.set_facecolor(clr)
        self.figure.set_edgecolor(clr)
        self.canvas.SetBackgroundColour(wx.Colour(*rgbtuple))
        self.canvas.Refresh()
Ejemplo n.º 19
0
class MyPlotPanel(wx.Panel):
    def __init__(self,
                 parent,
                 figsize=None,
                 dpi=None,
                 bgcolor=None,
                 type=None,
                 toolbar=None,
                 aspect='auto',
                 **kwargs):
        """ construction method of MyPlotPanel class
        :param parent: parent object
        :param figsize: plot figure size, (w, h)
        :param dpi: figure dpi,
        :parma bgcolor: background color of figure and canvas
        :param type: type of initial figure, 'image' or 'line'
        :param toolbar: show toolbar if not set None
        :param aspect: axes aspect, float number or 'auto' by default
        """
        wx.Panel.__init__(self, parent, **kwargs)
        self.parent = parent
        self.figsize = figsize
        self.dpi = dpi
        self.bgcolor = bgcolor
        self.type = type
        self.toolbar = toolbar
        self.aspect = aspect
        self.figure = Figure(self.figsize, self.dpi)
        self.canvas = FigureCanvas(self, -1, self.figure)

        # figure background color
        self.set_color(self.bgcolor)

        # initialize plot
        self._init_plot()

        # set layout
        self.set_layout()

        # post-initialization
        self._post_init()

        # binding events
        self.canvas.mpl_connect('button_press_event', self.on_press)
        self.canvas.mpl_connect('button_release_event', self.on_release)
        self.canvas.mpl_connect('motion_notify_event', self.on_motion)
        self.canvas.mpl_connect('pick_event', self.on_pick)
        self.Bind(wx.EVT_SIZE, self.on_size)

        self.xylim_choice.Bind(wx.EVT_CHOICE, self.xylim_choiceOnChoice)
        self.minlim_tc.Bind(wx.EVT_TEXT_ENTER, self.minlim_tcOnTextEnter)
        self.maxlim_tc.Bind(wx.EVT_TEXT_ENTER, self.maxlim_tcOnTextEnter)

    def set_layout(self):
        """ set panel layout
        """
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.canvas, 1, wx.EXPAND)
        hbox = wx.BoxSizer(wx.HORIZONTAL)

        # set toolbar if defined
        if self.toolbar is not None:
            self.toobar = MyToolbar(self.canvas)
            self.toobar.Realize()
            hbox.Add(self.toobar, 0, wx.EXPAND | wx.RIGHT, 5)

        # add x[y]lim control
        xylim_hbox = wx.BoxSizer(wx.HORIZONTAL)

        xy_vbox = wx.BoxSizer(wx.VERTICAL)

        xylim_choiceChoices = [u"X-Limit", u"Y-Limit", u"Auto"]
        self.xylim_choice = wx.Choice(self, wx.ID_ANY, wx.DefaultPosition,
                                      wx.DefaultSize, xylim_choiceChoices, 0)
        self.xylim_choice.SetSelection(0)
        xy_vbox.Add(self.xylim_choice, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 3)

        xylim_hbox.Add(xy_vbox, 0, wx.ALIGN_CENTER_VERTICAL, 1)

        lim_vbox = wx.BoxSizer(wx.VERTICAL)

        min_hbox = wx.BoxSizer(wx.HORIZONTAL)

        self.minlim_st = wx.StaticText(self, wx.ID_ANY, u"Min",
                                       wx.DefaultPosition, wx.DefaultSize, 0)
        self.minlim_st.Wrap(-1)
        self.minlim_st.SetFont(wx.Font(6, 70, 90, 90, False, "Monospace"))

        min_hbox.Add(self.minlim_st, 0,
                     wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.TOP, 1)

        self.minlim_tc = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString,
                                     wx.DefaultPosition, wx.DefaultSize,
                                     wx.TE_PROCESS_ENTER)
        self.minlim_tc.SetFont(wx.Font(6, 70, 90, 90, False, "Monospace"))
        self.minlim_tc.SetToolTip(u"Min of Limit")

        min_hbox.Add(self.minlim_tc, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1)

        lim_vbox.Add(min_hbox, 1, wx.EXPAND, 1)

        max_hbox = wx.BoxSizer(wx.HORIZONTAL)

        self.maxlim_st = wx.StaticText(self, wx.ID_ANY, u"Max",
                                       wx.DefaultPosition, wx.DefaultSize, 0)
        self.maxlim_st.Wrap(-1)
        self.maxlim_st.SetFont(wx.Font(6, 70, 90, 90, False, "Monospace"))

        max_hbox.Add(self.maxlim_st, 0,
                     wx.ALIGN_CENTER_VERTICAL | wx.BOTTOM | wx.RIGHT | wx.TOP,
                     1)

        self.maxlim_tc = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString,
                                     wx.DefaultPosition, wx.DefaultSize,
                                     wx.TE_PROCESS_ENTER)
        self.maxlim_tc.SetFont(wx.Font(6, 70, 90, 90, False, "Monospace"))
        self.maxlim_tc.SetToolTip(u"Max of Limit")

        max_hbox.Add(self.maxlim_tc, 0,
                     wx.ALIGN_CENTER_VERTICAL | wx.BOTTOM | wx.TOP, 1)
        lim_vbox.Add(max_hbox, 1, wx.EXPAND, 1)
        xylim_hbox.Add(lim_vbox, 0, wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 1)

        hbox.Add(xylim_hbox, 0, wx.EXPAND | wx.RIGHT, 5)

        # (x, y) pos label
        self.pos_st = wx.StaticText(self, label='')
        hbox.Add(self.pos_st, 0, wx.ALIGN_CENTER_VERTICAL)
        sizer.Add(hbox, 0, wx.EXPAND | wx.BOTTOM, 0)
        self.SetSizerAndFit(sizer)

    def _init_plot(self):
        if not hasattr(self, 'axes'):
            self.axes = self.figure.add_subplot(111, aspect=self.aspect)
        if self.type == 'image':  # draw image
            x = y = np.linspace(-np.pi, np.pi, 100)
            self.x, self.y = np.meshgrid(x, y)
            self.z = self._func_peaks(self.x, self.y)
            self.image = self.axes.imshow(self.z)
        else:  # draw line
            self.x = np.linspace(-10, 10, 200)
            self.y = np.sin(self.x)
            self.line, = self.axes.plot(self.x, self.y)

    def _post_init(self):
        self._set_xylim_flag(self.xylim_choice.GetStringSelection())

    def set_color(self, rgb_tuple):
        """ set figure and canvas with the same color.
        :param rgb_tuple: rgb color tuple,
                          e.g. (255, 255, 255) for white color
        """
        if rgb_tuple is None:
            #rgb_tuple = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get()
            rgb_tuple = wx.SystemSettings.GetColour(
                wx.SYS_COLOUR_DESKTOP).Get()
        clr = [c / 255.0 for c in rgb_tuple]
        self.figure.set_facecolor(clr)
        self.figure.set_edgecolor(clr)
        self.canvas.SetBackgroundColour(wx.Colour(*rgb_tuple))

    def on_size(self, event):
        self.fit_canvas()
        self.canvas.draw_idle()
        event.Skip()

    def on_press(self, event):
        pass

    def on_release(self, event):
        pass

    def on_pick(self, event):
        pass

    def on_motion(self, event):
        if event.inaxes is not None:
            self.pos_st.SetLabel("({x:<.4f}, {y:<.4f})".format(x=event.xdata,
                                                               y=event.ydata))

    def fit_canvas(self):
        """ tight fit canvas layout
        """
        #self.canvas.SetSize(self.GetSize())
        self.figure.set_tight_layout(True)

    def _func_peaks(self, x, y):
        return 3.0 * (1.0 - x)**2.0 * np.exp(-(x**2) - (y+1)**2) \
             - 10*(x/5 - x**3 - y**5) * np.exp(-x**2-y**2) \
             - 1.0/3.0*np.exp(-(x+1)**2 - y**2)

    def refresh(self):
        self.canvas.draw_idle()

    def xylim_choiceOnChoice(self, event):
        sel_str = self.xylim_choice.GetStringSelection()
        self._set_xylim_flag(sel_str)
        if sel_str == 'Auto':
            self.minlim_tc.Disable()
            self.maxlim_tc.Disable()
            self.minlim_st.Disable()
            self.maxlim_st.Disable()

            # auto set xy limit
            min_list = [
                np.vstack(line.get_data()).min(axis=1).tolist()
                for line in self.axes.get_lines()
            ]
            max_list = [
                np.vstack(line.get_data()).max(axis=1).tolist()
                for line in self.axes.get_lines()
            ]
            xmin, ymin = np.array(min_list).min(axis=0)
            xmax, ymax = np.array(max_list).max(axis=0)
            x0, xhw = (xmin + xmax) * 0.5, (xmax - xmin) * 0.5
            y0, yhw = (ymin + ymax) * 0.5, (ymax - ymin) * 0.5
            _xmin, _xmax = x0 - xhw * 1.1, x0 + xhw * 1.1
            _ymin, _ymax = y0 - yhw * 1.1, y0 + yhw * 1.1
            self.axes.set_xlim([_xmin, _xmax])
            self.axes.set_ylim([_ymin, _ymax])

            self.refresh()
        else:
            self.minlim_tc.Enable()
            self.maxlim_tc.Enable()
            self.minlim_st.Enable()
            self.maxlim_st.Enable()

            try:
                _xlim = self.axes.get_xlim()
                _ylim = self.axes.get_ylim()
            except:
                _xlim = [0, 100]
                _ylim = [0, 100]
            self._set_default_minlim(_xlim, _ylim)
            self._set_default_maxlim(_xlim, _ylim)

    def _set_default_minlim(self, xlim_array, ylim_array):
        if self._xylim == 'X-Limit':
            self.minlim_tc.SetValue("{xmin:.3g}".format(xmin=xlim_array[0]))
        elif self._xylim == 'Y-Limit':
            self.minlim_tc.SetValue("{ymin:.3g}".format(ymin=ylim_array[0]))

    def _set_default_maxlim(self, xlim_array, ylim_array):
        if self._xylim == 'X-Limit':
            self.maxlim_tc.SetValue("{xmax:.3g}".format(xmax=xlim_array[1]))
        elif self._xylim == 'Y-Limit':
            self.maxlim_tc.SetValue("{ymax:.3g}".format(ymax=ylim_array[1]))

    def minlim_tcOnTextEnter(self, event):
        xymin = float(self.minlim_tc.GetValue())
        xymax = float(self.maxlim_tc.GetValue())
        self._set_xylim_range(xymin, xymax)

    def maxlim_tcOnTextEnter(self, event):
        xymin = float(self.minlim_tc.GetValue())
        xymax = float(self.maxlim_tc.GetValue())
        self._set_xylim_range(xymin, xymax)

    def _set_xylim_flag(self, flag='X-Limit'):
        """ control x/y limit to be set
            :param flag: 'X-Limit' or 'Y-Limit'
        """
        self._xylim = flag

    def _set_xylim_range(self, vmin, vmax):
        """ set x/y limit according to _xylim value
            :param vmin: min of limit
            :param vmax: max of limit
        """
        if self._xylim == 'X-Limit':
            self.axes.set_xlim([vmin, vmax])
        elif self._xylim == 'Y-Limit':
            self.axes.set_ylim([vmin, vmax])
        self.refresh()
Ejemplo n.º 20
0
class GraphCanvasPanel(wx.Panel):
    def __init__(self, graphFrame, parent):
        super().__init__(parent)
        self.graphFrame = graphFrame

        # Remove matplotlib font cache, see #234
        try:
            cache_dir = mpl._get_cachedir()
        except:
            cache_dir = os.path.expanduser(os.path.join('~', '.matplotlib'))
        cache_file = os.path.join(cache_dir, 'fontList.cache')
        if os.access(cache_dir,
                     os.W_OK | os.X_OK) and os.path.isfile(cache_file):
            os.remove(cache_file)

        mainSizer = wx.BoxSizer(wx.VERTICAL)

        self.figure = Figure(figsize=(5, 3), tight_layout={'pad': 1.08})
        rgbtuple = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get()
        clr = [c / 255. for c in rgbtuple]
        self.figure.set_facecolor(clr)
        self.figure.set_edgecolor(clr)
        self.canvas = Canvas(self, -1, self.figure)
        self.canvas.SetBackgroundColour(wx.Colour(*rgbtuple))
        self.canvas.mpl_connect('button_press_event', self.OnMplCanvasClick)
        self.subplot = self.figure.add_subplot(111)
        self.subplot.grid(True)
        mainSizer.Add(self.canvas, 1, wx.EXPAND | wx.ALL, 0)

        self.SetSizer(mainSizer)

        self.xMark = None
        self.mplOnDragHandler = None
        self.mplOnReleaseHandler = None

    def draw(self, accurateMarks=True):
        self.subplot.clear()
        self.subplot.grid(True)
        allXs = set()
        allYs = set()
        plotData = {}
        legendData = []
        chosenX = self.graphFrame.ctrlPanel.xType
        chosenY = self.graphFrame.ctrlPanel.yType
        self.subplot.set(xlabel=self.graphFrame.ctrlPanel.formatLabel(chosenX),
                         ylabel=self.graphFrame.ctrlPanel.formatLabel(chosenY))

        mainInput, miscInputs = self.graphFrame.ctrlPanel.getValues()
        view = self.graphFrame.getView()
        sources = self.graphFrame.ctrlPanel.sources
        if view.hasTargets:
            iterList = tuple(
                itertools.product(sources, self.graphFrame.ctrlPanel.targets))
        else:
            iterList = tuple((f, None) for f in sources)

        # Draw plot lines and get data for legend
        for source, target in iterList:
            # Get line style data
            try:
                colorData = BASE_COLORS[source.colorID]
            except KeyError:
                pyfalog.warning('Invalid color "{}" for "{}"'.format(
                    source.colorID, source.name))
                continue
            color = colorData.hsl
            lineStyle = 'solid'
            if target is not None:
                try:
                    lightnessData = LIGHTNESSES[target.lightnessID]
                except KeyError:
                    pyfalog.warning('Invalid lightness "{}" for "{}"'.format(
                        target.lightnessID, target.name))
                    continue
                color = lightnessData.func(color)
                try:
                    lineStyleData = STYLES[target.lineStyleID]
                except KeyError:
                    pyfalog.warning('Invalid line style "{}" for "{}"'.format(
                        target.lightnessID, target.name))
                    continue
                lineStyle = lineStyleData.mplSpec
            color = hsv_to_rgb(hsl_to_hsv(color))

            # Get point data
            try:
                xs, ys = view.getPlotPoints(mainInput=mainInput,
                                            miscInputs=miscInputs,
                                            xSpec=chosenX,
                                            ySpec=chosenY,
                                            src=source,
                                            tgt=target)
                if not self.__checkNumbers(xs, ys):
                    pyfalog.warning(
                        'Failed to plot "{}" vs "{}" due to inf or NaN in values'
                        .format(source.name,
                                '' if target is None else target.name))
                    continue
                plotData[(source, target)] = (xs, ys)
                allXs.update(xs)
                allYs.update(ys)
                # If we have single data point, show marker - otherwise line won't be shown
                if len(xs) == 1 and len(ys) == 1:
                    self.subplot.plot(xs,
                                      ys,
                                      color=color,
                                      linestyle=lineStyle,
                                      marker='.')
                else:
                    self.subplot.plot(xs, ys, color=color, linestyle=lineStyle)
                # Fill data for legend
                if target is None:
                    legendData.append((color, lineStyle, source.shortName))
                else:
                    legendData.append(
                        (color, lineStyle,
                         '{} vs {}'.format(source.shortName,
                                           target.shortName)))
            except Exception:
                pyfalog.warning('Failed to plot "{}" vs "{}"'.format(
                    source.name, '' if target is None else target.name))
                self.canvas.draw()
                self.Refresh()
                return

        # Setting Y limits for canvas
        if self.graphFrame.ctrlPanel.showY0:
            allYs.add(0)
        canvasMinY, canvasMaxY = self._getLimits(allYs,
                                                 minExtra=0.05,
                                                 maxExtra=0.1)
        canvasMinX, canvasMaxX = self._getLimits(allXs,
                                                 minExtra=0.02,
                                                 maxExtra=0.02)
        self.subplot.set_ylim(bottom=canvasMinY, top=canvasMaxY)
        self.subplot.set_xlim(left=canvasMinX, right=canvasMaxX)
        # Process X marks line
        if self.xMark is not None:
            minX = min(allXs, default=None)
            maxX = max(allXs, default=None)
            if minX is not None and maxX is not None:
                minY = min(allYs, default=None)
                maxY = max(allYs, default=None)
                xMark = max(min(self.xMark, maxX), minX)
                # If in top 10% of X coordinates, align labels differently
                if xMark > canvasMinX + 0.9 * (canvasMaxX - canvasMinX):
                    labelAlignment = 'right'
                    labelPrefix = ''
                    labelSuffix = ' '
                else:
                    labelAlignment = 'left'
                    labelPrefix = ' '
                    labelSuffix = ''
                # Draw line
                self.subplot.axvline(x=xMark,
                                     linestyle='dotted',
                                     linewidth=1,
                                     color=(0, 0, 0))
                # Draw its X position
                if chosenX.unit is None:
                    xLabel = '{}{}{}'.format(labelPrefix,
                                             roundToPrec(xMark,
                                                         4), labelSuffix)
                else:
                    xLabel = '{}{} {}{}'.format(labelPrefix,
                                                roundToPrec(xMark, 4),
                                                chosenX.unit, labelSuffix)
                self.subplot.annotate(xLabel,
                                      xy=(xMark, canvasMaxY - 0.01 *
                                          (canvasMaxY - canvasMinY)),
                                      xytext=(0, 0),
                                      annotation_clip=False,
                                      textcoords='offset pixels',
                                      ha=labelAlignment,
                                      va='top',
                                      fontsize='small')
                # Get Y values
                yMarks = set()

                def addYMark(val):
                    if val is None:
                        return
                    # If due to some bug or insufficient plot density we're
                    # out of bounds, do not add anything
                    if minY <= val <= maxY:
                        if abs(val) < 0.0001:
                            val = 0
                        else:
                            val = roundToPrec(val, 4)
                        yMarks.add(val)

                for source, target in iterList:
                    xs, ys = plotData[(source, target)]
                    if not xs or xMark < min(xs) or xMark > max(xs):
                        continue
                    # Fetch values from graphs when we're asked to provide accurate data
                    if accurateMarks:
                        try:
                            y = view.getPoint(x=xMark,
                                              miscInputs=miscInputs,
                                              xSpec=chosenX,
                                              ySpec=chosenY,
                                              src=source,
                                              tgt=target)
                            addYMark(y)
                        except Exception:
                            pyfalog.warning(
                                'Failed to get X mark for "{}" vs "{}"'.format(
                                    source.name,
                                    '' if target is None else target.name))
                            # Silently skip this mark, otherwise other marks and legend display will fail
                            continue
                    # Otherwise just do linear interpolation between two points
                    else:
                        if xMark in xs:
                            # We might have multiples of the same value in our sequence, pick value for the last one
                            idx = len(xs) - xs[::-1].index(xMark) - 1
                            addYMark(ys[idx])
                            continue
                        idx = bisect(xs, xMark)
                        yMark = self._interpolateX(x=xMark,
                                                   x1=xs[idx - 1],
                                                   y1=ys[idx - 1],
                                                   x2=xs[idx],
                                                   y2=ys[idx])
                        addYMark(yMark)

                # Draw Y values
                for yMark in yMarks:
                    self.subplot.annotate('{}{}{}'.format(
                        labelPrefix, yMark, labelSuffix),
                                          xy=(xMark, yMark),
                                          xytext=(0, 0),
                                          textcoords='offset pixels',
                                          ha=labelAlignment,
                                          va='center',
                                          fontsize='small')

        legendLines = []
        for i, iData in enumerate(legendData):
            color, lineStyle, label = iData
            legendLines.append(
                Line2D([0], [0],
                       color=color,
                       linestyle=lineStyle,
                       label=label.replace('$', '\$')))

        if len(legendLines) > 0 and self.graphFrame.ctrlPanel.showLegend:
            legend = self.subplot.legend(handles=legendLines)
            for t in legend.get_texts():
                t.set_fontsize('small')
            for l in legend.get_lines():
                l.set_linewidth(1)

        self.canvas.draw()
        self.Refresh()

    def markXApproximate(self, x):
        if x is not None:
            self.xMark = x
            self.draw(accurateMarks=False)

    def unmarkX(self):
        self.xMark = None
        self.draw()

    @staticmethod
    def _getLimits(vals, minExtra=0, maxExtra=0):
        minVal = min(vals, default=0)
        maxVal = max(vals, default=0)
        # Extend range a little for some visual space
        valRange = maxVal - minVal
        minVal -= valRange * minExtra
        maxVal += valRange * maxExtra
        # Extend by % of value if we show function of a constant
        if minVal == maxVal:
            minVal -= minVal * 0.05
            maxVal += minVal * 0.05
        # If still equal, function is 0, spread out visual space as special case
        if minVal == maxVal:
            minVal -= 5
            maxVal += 5
        return minVal, maxVal

    @staticmethod
    def _interpolateX(x, x1, y1, x2, y2):
        pos = (x - x1) / (x2 - x1)
        y = y1 + pos * (y2 - y1)
        return y

    @staticmethod
    def __checkNumbers(xs, ys):
        for number in itertools.chain(xs, ys):
            if math.isnan(number) or math.isinf(number):
                return False
        return True

    # Matplotlib event handlers
    def OnMplCanvasClick(self, event):
        if event.button == 1:
            if not self.mplOnDragHandler:
                self.mplOnDragHandler = self.canvas.mpl_connect(
                    'motion_notify_event', self.OnMplCanvasDrag)
            if not self.mplOnReleaseHandler:
                self.mplOnReleaseHandler = self.canvas.mpl_connect(
                    'button_release_event', self.OnMplCanvasRelease)
            self.markXApproximate(event.xdata)
        elif event.button == 3:
            self.unmarkX()

    def OnMplCanvasDrag(self, event):
        self.markXApproximate(event.xdata)

    def OnMplCanvasRelease(self, event):
        if event.button == 1:
            if self.mplOnDragHandler:
                self.canvas.mpl_disconnect(self.mplOnDragHandler)
                self.mplOnDragHandler = None
            if self.mplOnReleaseHandler:
                self.canvas.mpl_disconnect(self.mplOnReleaseHandler)
                self.mplOnReleaseHandler = None
            # Do not write markX here because of strange mouse behavior: when dragging,
            # sometimes when you release button, x coordinate changes. To avoid that,
            # we just re-use coordinates set on click/drag and just request to redraw
            # using accurate data
            self.draw(accurateMarks=True)
Ejemplo n.º 21
0
class WxScatter(wx.Panel):
    def __init__(self, *args, **kwargs):
        self.mapwidget = kwargs.pop('map', None)
        self.timewidget = kwargs.pop('time', None)
        wx.Panel.__init__(self, *args, **kwargs)
        self.id = wx.NewId()
        self.gpxfig = Figure()
        self.ax = self.gpxfig.add_subplot(111, polar=True)
        self.ax.set_theta_zero_location("N")
        self.gpxfig.subplots_adjust(right=0.9, left=0.1)
        # canvas and events
        self.gpxcanvas = FigureCanvas(self, -1, self.gpxfig)
        self.gpxcanvas.mpl_connect('draw_event', self.OnDraw)
        self.gpxcanvas.mpl_connect('scroll_event', self.OnMouseWheel)
        self.gpxcanvas.mpl_connect('button_press_event', self.OnLeftMouseDown)
        self.gpxcanvas.mpl_connect('button_release_event', self.OnLeftMouseUp)
        self.gpxcanvas.mpl_connect('motion_notify_event', self.OnMouseMotion)
        self.gpxcanvas.mpl_connect('resize_event', self.OnSize)
        self.gpxcanvas.mpl_connect('figure_enter_event', self.OnMouseEnter)
        self.gpxcanvas.mpl_connect('figure_leave_event', self.OnMouseLeave)

        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.gpxcanvas, 1,
                       wx.LEFT | wx.TOP | wx.GROW | wx.EXPAND)
        self.SetSizer(self.sizer)

        msgwrap.register(self.OnSigCurChanged, "CurChanged")
        msgwrap.register(self.OnSigSelChanged, "SelChanged")
        msgwrap.register(self.OnSigValChanged, "ValChanged")

        #that code does not work on linux...
        color = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE)
        self.gpxfig.set_facecolor(
            (color.red / 255.0, color.green / 255.0, color.blue / 255.0))
        self.gpxfig.set_edgecolor(
            (color.red / 255.0, color.green / 255.0, color.blue / 255.0))
        self.gpxcanvas.SetBackgroundColour(color)

        #plugin specific initialization
        self.thetasrc = 'course'
        self.radiussrc = 'speed'
        self.autoscale = True
        self.grid = False
        self.kwargs = {'color': '#0000FF'}
        self.grid = False

    def Plot(self, xrange=None, yrange=None):
        self.ax.cla()
        self.ax.scatter(self.gpx[(self.thetasrc,1,1)]/360*2*np.pi,\
                            self.gpx[(self.radiussrc,1,1)],\
                            c=self.gpx[(self.radiussrc,1,1)],\
                            marker='o',
                            cmap=cm.jet)
        self.ax.set_theta_zero_location("N")
        self.ax.set_theta_direction(-1)
        self.ax.grid(self.grid)
        self.gpxcanvas.draw()
        self.OnSize(None)

    def AttachGpx(self, data):
        self.gpx = data
        self.Plot()
        self.OnSize(None)

    def DetachGpx(self):
        self.gpx = None

    def OnSigSelChanged(self, arg1, arg2, arg3):
        if arg1 == self.id:
            return

    def OnSigValChanged(self, arg1):
        if arg1 == self.id:
            return
        self.Plot()

    def OnSigCurChanged(self, arg1, arg2):
        if arg1 == self.id:
            return

    def OnDraw(self, event):
        pass

    def OnSize(self, event):
        pixels = self.GetClientSize()
        if pixels[0] < 20 or pixels[1] < 20:
            return
        self.gpxfig.set_size_inches(
            float(pixels[0]) / self.gpxfig.get_dpi(),
            float(pixels[1]) / self.gpxfig.get_dpi())
        self.gpxfig.subplots_adjust(right=0.85,
                                    left=0.15,
                                    top=0.85,
                                    bottom=0.15)

    def OnLeftMouseDown(self, event):
        if event.button == 1:
            if event.dblclick:
                try:
                    event.guiEvent.GetEventObject().ReleaseMouse()
                except:
                    pass
                self.OnLeftMouseDblClick(event)
                return

    def OnLeftMouseDblClick(self, event):
        (dummy,xlo,xhi,ylo,yhi,self.autoscale,self.grid,\
        dummy,self.thetasrc,self.radiussrc,extra)=\
            WxQuery("Graph Settings",\
                [('wxnotebook','Axes',None,None,None),
                 ('wxentry','Theta Low',None,self.ax.get_xlim()[0],'float'),
                 ('wxentry','Theta High',None,self.ax.get_xlim()[1],'float'),
                 ('wxentry','Radius Low',None,self.ax.get_ylim()[0],'float'),
                 ('wxentry','Radius High',None,self.ax.get_ylim()[1],'float'),
                 ('wxcheck','Autoscale',None,self.autoscale,'bool'),
                 ('wxcheck','Show Grid',None,self.grid,'bool'),
                 ('wxnotebook','Polar plot',None,None,None),
                 ('wxcombo','Theta',self.XAxisAllowed(),self.thetasrc,'str'),
                 ('wxcombo','Radius',self.XAxisAllowed(),self.radiussrc,'str'),
                 ('wxentry','Extra arguments',None,{},'str')
                ])
        self.kwargs.update(ast.literal_eval(extra))
        if self.autoscale:
            self.Plot()
        else:
            self.Plot((xlo, xhi), (ylo, yhi))

    def OnMouseWheel(self, event):
        scale_factor = 1.2 if event.button == 'down' else (1.0 / 1.2)
        rmin, rmax = self.ax.get_ylim()
        self.ax.set_ylim(rmin * scale_factor, rmax * scale_factor)
        self.gpxcanvas.draw()

    def OnLeftMouseUp(self, event):
        pass

    def OnMouseMotion(self, event):
        pass

    def OnMouseEnter(self, event):
        pass

    def OnMouseLeave(self, event):
        pass

    def XAxisAllowed(self):
        l = ''
        for name in self.gpx.get_header_names():
            if name not in ['time', 'ok'] and name[0] != '_':
                l += '|' + name
        return l[1:]
Ejemplo n.º 22
0
class Panel_Graphe(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, -1, style=wx.TAB_TRAVERSAL)
        self.afficher_valeurs = False

        self.panel = wx.Panel(self,
                              -1,
                              style=wx.TAB_TRAVERSAL | wx.SUNKEN_BORDER)

        self.figure = matplotlib.pyplot.figure()
        self.canvas = Canvas(self.panel, -1, self.figure)
        self.canvas.SetMinSize((20, 20))
        self.SetColor((255, 255, 255))

        # Boutons
        self.bouton_apercu = wx.BitmapButton(
            self, -1,
            wx.Bitmap(Chemins.GetStaticPath(u"Images/16x16/Apercu.png"),
                      wx.BITMAP_TYPE_ANY))
        self.bouton_options = wx.BitmapButton(
            self, -1,
            wx.Bitmap(Chemins.GetStaticPath(u"Images/16x16/Mecanisme.png"),
                      wx.BITMAP_TYPE_ANY))

        # Binds
        self.Bind(wx.EVT_BUTTON, self.Apercu, self.bouton_apercu)
        self.Bind(wx.EVT_BUTTON, self.Options, self.bouton_options)

        # Properties
        self.bouton_apercu.SetToolTipString(
            _(u"Cliquez ici pour ouvrir le visualiseur de graphe pour accéder aux fonctions d'export et d'impression"
              ))
        self.bouton_options.SetToolTipString(
            _(u"Cliquez ici pour accéder aux options du graphe"))

        # Layout
        grid_sizer_base = wx.FlexGridSizer(1, 2, 5, 5)

        sizer_canvas = wx.BoxSizer(wx.VERTICAL)
        sizer_canvas.Add(self.canvas, 1, wx.EXPAND, 0)
        self.panel.SetSizer(sizer_canvas)

        grid_sizer_base.Add(self.panel, 1,
                            wx.EXPAND | wx.TOP | wx.LEFT | wx.BOTTOM, 10)

        grid_sizer_boutons = wx.FlexGridSizer(5, 1, 5, 5)
        grid_sizer_boutons.Add(self.bouton_apercu, 0, 0, 0)
        grid_sizer_boutons.Add(self.bouton_options, 0, 0, 0)
        grid_sizer_base.Add(grid_sizer_boutons, 1,
                            wx.EXPAND | wx.TOP | wx.BOTTOM | wx.RIGHT, 10)

        grid_sizer_base.AddGrowableCol(0)
        grid_sizer_base.AddGrowableRow(0)

        self.SetSizer(grid_sizer_base)
        self.Layout()

    def SetColor(self, rgbtuple=None):
        """Set figure and canvas colours to be the same."""
        if rgbtuple is None:
            rgbtuple = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get()
        clr = [c / 255. for c in rgbtuple]
        self.figure.set_facecolor(clr)
        self.figure.set_edgecolor(clr)
        self.canvas.SetBackgroundColour(wx.Colour(*rgbtuple))

    def ConvertCouleur(self, couleur=None):
        return [c / 255. for c in couleur]

    def Apercu(self, event):
        import DLG_Zoom_graphe
        dlg = DLG_Zoom_graphe.Dialog(self, figure=self.figure)
        dlg.ShowModal()
        dlg.Destroy()

    def Options(self, event):
        # Création du menu contextuel
        menuPop = wx.Menu()

        item = wx.MenuItem(menuPop, 10, _(u"Afficher les valeurs"),
                           _(u"Afficher les valeurs"), wx.ITEM_CHECK)
        menuPop.AppendItem(item)
        self.Bind(wx.EVT_MENU, self.On_afficher_valeurs, id=10)
        if self.afficher_valeurs == True: item.Check(True)

        self.PopupMenu(menuPop)
        menuPop.Destroy()

    def On_afficher_valeurs(self, event):
        self.afficher_valeurs = not self.afficher_valeurs
        self.MAJ()

    def SetDictBudget(self, dictBudget=None):
        self.dictBudget = dictBudget
        self.MAJ()

    def MAJ(self):
        self.figure.clear()
        if self.dictBudget == None:
            wx.CallAfter(self.SendSizeEvent)
            return

        # Récupération des données
        from Ol import OL_Suivi_budget
        analyse = OL_Suivi_budget.Analyse(self.dictBudget)
        listeCategories = analyse.GetValeurs()

        listeRealise = []
        listeBudgete = []
        listeLabels = []

        for dictCategorie in listeCategories:
            listeRealise.append(dictCategorie["realise"])
            listeBudgete.append(dictCategorie["plafond"])
            listeLabels.append(dictCategorie["nomCategorie"])

##            if dictCategorie["typeCategorie"] == "debit" :
##                solde = plafond - realise
##            else :
##                solde = realise - plafond

##        # TEST
##        listeIndex = np.arange(len(listeLabels))
##        bar_width = 0.2
##        opacity = 0.4
##
##        ax = self.figure.add_subplot(111)
##        barres = ax.bar(listeIndex, listeRealise, width=bar_width, alpha=opacity, color="g", label=_(u"Réel"))
##        barres = ax.bar(listeIndex + bar_width, listeBudgete, width=bar_width, alpha=opacity, color="b", label=_(u"Budgété"))
##
##        # Formatage des montants sur y
##        majorFormatter = FormatStrFormatter(SYMBOLE + u" %d")
##        ax.yaxis.set_major_formatter(majorFormatter)
##
##        # Affichage des labels x
##        ax.set_xticks(listeIndex + bar_width)
##        ax.set_xticklabels(listeLabels)
##
##        labels = ax.get_xticklabels()
##        setp(labels, rotation=45)
##
##        # Légende
##        props = matplotlib.font_manager.FontProperties(size=10)
##        leg = ax.legend(loc='best', shadow=False, fancybox=True, prop=props)
##        leg.get_frame().set_alpha(0.5)
##
##        # Espaces autour du graph
##        self.figure.subplots_adjust(left=0.12, bottom=0.40, right=None, wspace=None, hspace=None)

# TEST
        listeIndex = np.arange(len(listeLabels))
        bar_height = 0.2
        opacity = 0.4

        ax = self.figure.add_subplot(111)
        barresRealise = ax.barh(listeIndex,
                                listeRealise,
                                height=bar_height,
                                alpha=opacity,
                                color="g",
                                label=_(u"Réel"))
        barresBudgete = ax.barh(listeIndex + bar_height,
                                listeBudgete,
                                height=bar_height,
                                alpha=opacity,
                                color="b",
                                label=_(u"Budgété"))

        # Formatage des montants sur x
        majorFormatter = FormatStrFormatter(u"%d " + SYMBOLE)
        ax.xaxis.set_major_formatter(majorFormatter)

        # Affichage des labels x
        ax.set_yticks(listeIndex + bar_height)
        ax.set_yticklabels(listeLabels)

        def autolabel(rects):
            # attach some text labels
            for rect in rects:
                width = rect.get_width()
                ax.text(width + 20,
                        rect.get_y() + rect.get_height() / 2.,
                        u"%.2f %s" % (int(width), SYMBOLE),
                        ha='left',
                        va='center',
                        fontsize=8,
                        color="grey")

        if self.afficher_valeurs == True:
            autolabel(barresRealise)
            autolabel(barresBudgete)

        # Recherche la largeur de texte max
        largeurMax = 0
        for label in listeLabels:
            if len(label) > largeurMax:
                largeurMax = len(label)

        # Espaces autour du graph
        margeGauche = 0.1 + largeurMax * 0.008
        self.figure.subplots_adjust(left=margeGauche,
                                    right=None,
                                    wspace=None,
                                    hspace=None)

        # Légende
        props = matplotlib.font_manager.FontProperties(size=10)
        leg = ax.legend(loc='best', shadow=False, fancybox=True, prop=props)
        leg.get_frame().set_alpha(0.5)

        # Finalisation
        ax.autoscale_view('tight')
        ##        ax.grid(True)
        ax.figure.canvas.draw()
        wx.CallAfter(self.SendSizeEvent)
        return
Ejemplo n.º 23
0
class plotTimeSeries(wx.Panel):
    def __init__(self, parent, id, pos, size, style, name):
        self._init_ctrls(parent)

    def _init_coll_boxSizer1_Items(self, parent):
        # generated method, don't edit

        parent.AddWindow(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        parent.AddWindow(self.toolbar, 0, wx.EXPAND)

    def _init_ctrls(self, parent):
        wx.Panel.__init__(self, parent, -1)
        self.parent = parent

        #init Plot
        # matplotlib.figure.Figure
        self.figure = plt.figure()

        # matplotlib.axes.AxesSubplot
        self.timeSeries = host_subplot(111, axes_class=AA.Axes)
        self.setTimeSeriesTitle("No Data to Plot")

        # matplotlib.backends.backend_wxagg.FigureCanvasWxAgg
        self.canvas = FigCanvas(self, -1, self.figure)

        self.canvas.SetFont(
            wx.Font(20, wx.SWISS, wx.NORMAL, wx.NORMAL, False, u'Tahoma'))
        self.isShowLegendEnabled = False

        self.canvas.mpl_connect('figure_leave_event', self._onFigureLeave)
        Publisher.subscribe(self.updateCursor, "updateCursor")

        # Create the navigation toolbar, tied to the canvas
        self.toolbar = NavigationToolbar(self.canvas, allowselect=True)
        self.toolbar.Realize()
        self.seriesPlotInfo = None

        #set properties
        self.fontP = FontProperties()
        self.fontP.set_size('x-small')

        self.format = '-o'
        self.alpha = 1
        self._setColor("WHITE")

        left = 0.125  # the left side of the subplots of the figure
        #right = 0.9  # the right side of the subplots of the figure
        #bottom = 0.51  # the bottom of the subplots of the figure
        #top = 1.2  # the top of the subplots of the figure
        #wspace = .8  # the amount of width reserved for blank space between subplots
        #hspace = .8  # the amount of height reserved for white space between subplots
        plt.subplots_adjust(
            left=
            left  #, bottom=bottom, right=right, top=top, wspace=wspace, hspace=hspace
        )
        plt.tight_layout()

        #init hover tooltip

        # create a long tooltip with newline to get around wx bug (in v2.6.3.3)
        # where newlines aren't recognized on subsequent self.tooltip.SetTip() calls
        self.tooltip = wx.ToolTip(
            tip='tip with a long %s line and a newline\n')
        self.canvas.SetToolTip(self.tooltip)
        self.tooltip.Enable(False)
        self.tooltip.SetDelay(0)

        #init lists
        #self.lines = {}
        self.lines = []
        self.axislist = {}
        self.curveindex = -1
        self.editseriesID = -1
        self.editCurve = None
        self.editPoint = None
        self.hoverAction = None
        self.selplot = None

        self.cursors = []

        self.canvas.draw()
        self._init_sizers()

    def _init_sizers(self):
        # generated method, don't edit
        self.boxSizer1 = wx.BoxSizer(orient=wx.VERTICAL)
        self._init_coll_boxSizer1_Items(self.boxSizer1)
        self.SetSizer(self.boxSizer1)

    '''
    def changePlotSelection(self, datetime_list=[]):
        cc= ColorConverter()
        # k black,    # r red
        # needs to have graph first
        selected = cc.to_rgba('r', 1)
        unselected = cc.to_rgba('k', 0.1)
        allunselected = cc.to_rgba('k', 1)
        if self.editPoint:
            colorlist=[allunselected] *len(self.editCurve.dataTable)
            if len(datetime_list)>0:
                for i in xrange(len(self.editCurve.dataTable)):
                    if  self.editCurve.dataTable[i][1] in datetime_list:
                        colorlist[i]=selected
                    else:
                        colorlist[i]=unselected

            self.editPoint.set_color(colorlist)
            #self.editPoint.set_color(['k' if x == 0 else 'r' for x in tflist])
            self.canvas.draw()

    '''

    ## TODO 10/15/2014 Change function so that it will accept a list of datavalues. This will remove the need to loop through the values currently plotted and we would instead plot the list of datetimes and datavalues together.

    def changePlotSelection(self, filtered_datetime):
        """
        Selected points have a scatter plot drawn over them to indicated the point being selected
        """
        if self.selplot:
            self.selplot.remove()
            del self.selplot
            self.selplot = None

        result = None
        if isinstance(filtered_datetime, pd.DataFrame):
            result = filtered_datetime.sort_index()

        if isinstance(filtered_datetime, list):
            df = self.editCurve.dataTable
            result = df[df['LocalDateTime'].isin(filtered_datetime)].astype(
                datetime.datetime)

        if isinstance(result, pd.DataFrame):
            if result.empty:
                self.canvas.draw()
                return
        else:
            if not result:
                self.canvas.draw()
                return

        values = result['DataValue'].values.tolist()
        dates = result.index.astype(datetime.datetime)
        self.selplot = self.axislist[self.editSeries.axisTitle].scatter(
            dates,
            values,
            s=35,
            c='red',
            edgecolors='none',
            zorder=12,
            marker='s',
            alpha=1)
        self.canvas.draw()

    def lassoChangeSelection(self, filtered_datetime):
        self.parent.record_service.select_points(dataframe=filtered_datetime)

    def onShowLegend(self, isVisible):
        if isVisible:
            self.isShowLegendEnabled = True
            plt.subplots_adjust(bottom=.1 + .1)
            leg = self.timeSeries.legend(loc='upper right',
                                         ncol=2,
                                         fancybox=True,
                                         prop=self.fontP)
            leg.get_frame().set_alpha(.5)
            leg.draggable(state=True)
        else:
            self.isShowLegendEnabled = False
            plt.subplots_adjust(bottom=.1)
            self.timeSeries.legend_ = None

        plt.gcf().autofmt_xdate()
        self.canvas.draw()

    def onPlotType(self, ptype):
        # self.timeSeries.clear()
        if ptype == "line":
            ls = '-'
            m = 'None'
        elif ptype == "point":
            ls = 'None'
            m = 'o'
        else:
            ls = '-'
            m = 'o'

        self.format = ls + m
        for k, v in self.axislist.iteritems():
            lines = v.get_lines()
            for line in lines:
                plt.setp(line, linestyle=ls, marker=m)

        if self.isShowLegendEnabled:
            self.onShowLegend(self.isShowLegendEnabled)

        plt.gcf().autofmt_xdate()
        self.canvas.draw()

    def stopEdit(self):
        self.clear()
        self.selectedlist = None

        self.selplot = None
        self.lman = None

        #self.canvas.mpl_disconnect(self.hoverAction)
        try:
            self.canvas.mpl_disconnect(self.pointPick)
            self.pointPick = None
        except AttributeError as e:
            logger.error(e)

        self.hoverAction = None
        self.xys = None
        self.alpha = 1

        self.curveindex = -1
        self.editCurve = None
        # self.RefreshPlot()
        if self.seriesPlotInfo and self.seriesPlotInfo.isPlotted(
                self.editseriesID):
            self.updatePlot()
        self.toolbar.stopEdit()
        self.editseriesID = -1

    def updateValues(self):
        # self.addEdit(self.editCursor, self.editSeries, self.editDataFilter)

        #clear current edit points and curve
        if self.editCurve:
            curraxis = self.axislist[self.editCurve.axisTitle]
            for l in curraxis.lines:
                if l.get_label() == self.editCurve.plotTitle:
                    curraxis.lines.remove(l)

            #redraw editpoints and curve
            self.seriesPlotInfo.updateEditSeries()
            self.editCurve = self.seriesPlotInfo.getEditSeriesInfo()
            self.drawEditPlot(self.editCurve)
            self.canvas.draw()

        Publisher.sendMessage("refreshTable", e=self.editCurve.dataTable)
        # self.parent.parent.dataTable.Refresh()
        plt.gcf().autofmt_xdate()
        self.canvas.draw()

    def drawEditPlot(self, oneSeries):
        self.axislist[oneSeries.axisTitle].set_zorder(10)
        self.lines[self.curveindex] = self.axislist[oneSeries.axisTitle]
        data = oneSeries.dataTable
        dates = data.index.astype(datetime.datetime)
        curraxis = self.axislist[oneSeries.axisTitle]

        curraxis.plot_date(dates,
                           data['DataValue'],
                           "-s",
                           color=oneSeries.color,
                           xdate=True,
                           label=oneSeries.plotTitle,
                           zorder=10,
                           alpha=1,
                           picker=5.0,
                           pickradius=5.0,
                           markersize=4.5)
        curraxis.set_xlabel('Date')

        convertedDates = matplotlib.dates.date2num(dates)
        self.xys = zip(convertedDates, oneSeries.dataTable['DataValue'])
        self.toolbar.editSeries(self.xys, self.editCurve)
        self.pointPick = self.canvas.mpl_connect('pick_event', self._onPick)
        self.editSeries = oneSeries

    def _setColor(self, color):
        """Set figure and canvas colours to be the same.
        :rtype : object
        """
        plt.gcf().set_facecolor(color)
        plt.gcf().set_edgecolor(color)
        self.canvas.SetBackgroundColour(color)

    def close(self):
        #plt.clf()
        #plt.close()
        pass

    def Plot(self, seriesPlotInfo):
        self.seriesPlotInfo = seriesPlotInfo
        self.updatePlot()
        # resets the home view - will remove any previous zooming
        self.toolbar.update()
        self.toolbar.push_current()

        #self._views.home()
        #self._positions.home()
        #self.set_history_buttons()

    #clear plot
    def clear(self):
        """

        :return:
        """

        lines = []
        for key, ax in self.axislist.items():
            ax.clear()
        self.axislist = {}
        #self.canvas.draw()
        # self.stopEdit()
        #print "TimeSeries: ", dir(self.timeSeries), type(self.timeSeries)
        #plt.cla()
        #plt.clf()
        #self.timeSeries.plot([], [], picker=5)

    def setUpYAxis(self):
        """ Setting up multiple axes

        :return:
        """

        self.axislist = {}
        left = 0
        right = 0
        adj = .05
        editaxis = None

        ## Identify Axes and save them to axislist
        #loop through the list of curves and add an axis for each
        for oneSeries in self.seriesPlotInfo.getAllSeries():
            #test to see if the axis already exists
            if oneSeries.edit:
                editaxis = oneSeries.axisTitle
            if not oneSeries.axisTitle in self.axislist:
                self.axislist[oneSeries.axisTitle] = None
        keys = self.axislist.keys()

        ## Put editing axis at the beginning of the list
        if editaxis:
            for i in range(len(keys)):
                if keys[i] == editaxis:
                    keys.pop(i)
                    break
            keys.insert(0, editaxis)

        leftadjust = -30
        for i, axis in zip(range(len(self.axislist)), keys):
            if i % 2 == 0:
                left = left + 1
                #add to the left(yaxis)
                if i == 0:
                    #if first plot use the orig axis
                    newAxis = self.timeSeries
                else:
                    newAxis = self.timeSeries.twinx()
                    '''
                    Spines idea
                    #newAxis.spines["left"].set_position(("axes", leftadjust * left))
                    newAxis.spines["left"].set_position(("axes", -.1))
                    newAxis.spines["left"].set_visible(True)
                    newAxis.yaxis.set_label_position("left")
                    newAxis.yaxis.set_ticks_position("left")
                    '''

                    new_fixed_axis = newAxis.get_grid_helper().new_fixed_axis
                    newAxis.axis['left'] = new_fixed_axis(loc='left',
                                                          axes=newAxis,
                                                          offset=(leftadjust *
                                                                  left, 0))
                    newAxis.axis["left"].toggle(all=True)
                    newAxis.axis["right"].toggle(all=False)

                    leftadjust -= 15

            else:
                right = right + 1
                #add to the right(y2axis)
                newAxis = self.timeSeries.twinx()
                '''
                Spines idea
                #newAxis.spines["right"].set_position(("axes", -1*60*(right - 1)))
                newAxis.spines["right"].set_position(("axes", 1.0))
                newAxis.spines["right"].set_visible(True)
                newAxis.yaxis.set_label_position("right")
                newAxis.yaxis.set_ticks_position("right")
                '''

                new_fixed_axis = newAxis.get_grid_helper().new_fixed_axis
                newAxis.axis['right'] = new_fixed_axis(loc='right',
                                                       axes=newAxis,
                                                       offset=(60 *
                                                               (right - 1), 0))
                newAxis.axis['right'].toggle(all=True)

            a = newAxis.set_ylabel(axis, picker=True)
            a.set_picker(True)

            #logger.debug("axis label: %s" % (axis))
            self.axislist[axis] = newAxis
            plt.tight_layout()
            self.canvas.draw()

    def updatePlot(self):
        self.clear()
        count = self.seriesPlotInfo.count()
        self.setUpYAxis()
        self.lines = []

        ## Spine initialization ##
        for oneSeries in self.seriesPlotInfo.getAllSeries():
            if oneSeries.seriesID == self.seriesPlotInfo.getEditSeriesID():
                """

                Edited Series

                """
                self.curveindex = len(self.lines)
                self.lines.append("")
                self.editCurve = oneSeries
                self.drawEditPlot(oneSeries)

            else:
                """

                Plotted Series

                """
                curraxis = self.axislist[oneSeries.axisTitle]
                curraxis.set_zorder(1)

                data = oneSeries.dataTable
                dates = data.index.astype(datetime.datetime)
                #data.plot(ax=curraxis)
                curraxis.plot_date(dates,
                                   data['DataValue'],
                                   color=oneSeries.color,
                                   fmt=self.format,
                                   xdate=True,
                                   tz=None,
                                   antialiased=True,
                                   label=oneSeries.plotTitle,
                                   alpha=self.alpha,
                                   picker=5.0,
                                   pickradius=5.0,
                                   markersize=4)

                curraxis.set_xlabel('Date')
                '''
                data = oneSeries.dataTable
                #dates = data['LocalDateTime'].astype(datetime.datetime)

                data['LocalDateTime'] = pd.to_datetime(data['LocalDateTime'])
                data['LocalDateTime'].astype(datetime.datetime)

                data.plot(ax=curraxis)
                oneSeries.dataTable.plot(ax=curraxis)
                curraxis.set_xlabel('Date')
                '''

        if count > 1:
            self.setTimeSeriesTitle("")
            plt.subplots_adjust(bottom=.1 + .1)
            # self.timeSeries.legend(loc='upper center', bbox_to_anchor=(0.5, -0.05),
            #      ncol=2, prop = self.fontP)
            self.timeSeries.legend(loc='upper center',
                                   bbox_to_anchor=(0.5, -1.75),
                                   ncol=2,
                                   prop=self.fontP)

        elif count == 0:
            self.setTimeSeriesTitle("")
            self.timeSeries.legend_ = None
        else:
            self.setTimeSeriesTitle(oneSeries.siteName)
            plt.subplots_adjust(bottom=.1)
            self.timeSeries.legend_ = None

        self.timeSeries.set_xlabel("Date", picker=True)
        #self.timeSeries.set_xlim(matplotlib.dates.date2num([self.seriesPlotInfo.currentStart, self.seriesPlotInfo.currentEnd]))

        #self.timeSeries.axis[:].set_major_formatter(FormatStrFormatter('%.2f'))

        self.timeSeries.axis[:].major_ticks.set_tick_out(True)
        self.timeSeries.axis["bottom"].label.set_pad(20)
        self.timeSeries.axis["bottom"].major_ticklabels.set_pad(15)
        self.timeSeries.axis["bottom"].major_ticklabels.set_rotation(15)
        self.timeSeries.axis[:].major_ticklabels.set_picker(True)

        plt.gcf().autofmt_xdate()

        #self.figure.tight_layout()
        if not self.toolbar._views.empty():
            for v in self.toolbar._views:
                del (v)
            self.toolbar.push_current()

        self.canvas.draw()

    def updateCursor(self, selectedObject=None, deselectedObject=None):
        """
        :param selectedObject:
        """

        try:
            if selectedObject:
                """
                Activate Cursor. Happens when a plot is selected
                """
                if self.seriesPlotInfo:
                    seriesInfo = self.seriesPlotInfo.getSeries(
                        selectedObject.id)

                    if seriesInfo:
                        currentAxis = None
                        # If there a key with the axisTitle we are interested in, set currentaxis to that.
                        if seriesInfo.axisTitle in self.axislist.keys():
                            currentAxis = self.axislist[seriesInfo.axisTitle]
                        # If nothing is in the axislist, we don't care about it
                        elif len(self.axislist) < 1:
                            currentAxis = None
                        self.configureCursor(currentAxis=currentAxis)
            elif deselectedObject:
                """
                Deactivate Cursor. This happens when the plot is deselected
                """
                self.deactivateCursor(deselectedObject)

        except AttributeError as e:
            print "Ignoring Attribute Error", e

    def deactivateCursor(self, deselectedObject=None):
        # Remove an object if supplied
        if deselectedObject:
            for i in self.cursors:
                if i.selected == deselectedObject:
                    i.disable()
                    break

        # Disable existing Cursors
        elif self.cursors:
            for i in self.cursors:
                i.disable()

    def configureCursor(self, currentAxis=None):
        """Creates the cursors for each axes in order to provide data hovering"""

        self.deactivateCursor()

        self.cursors = []

        # initialize cursors for axes from currently selected axes
        for k, v in self.axislist.iteritems():
            i = Cursor(self.canvas, self.toolbar, v, k)
            ## If I have selected an axis that is in the axislist
            if v == currentAxis:
                i.enable()
                i.setSelected(currentAxis)
            # If there is only one axis in the axislist, default to the first axis
            elif len(self.axislist) == 1:
                i.enable()
                i.setSelected(self.axislist.values()[0])
            # Else I disable the other axes that I don't care about
            else:
                i.setSelected(None)
                i.disable()

            self.cursors.append(i)

    def setTimeSeriesTitle(self, title=""):
        """Set the title of the TimeSeries plot"""
        self.timeSeries.set_title(title, picker=True)

    def setEdit(self, id):
        self.editseriesID = id
        self.alpha = .5

        if self.seriesPlotInfo and self.seriesPlotInfo.isPlotted(
                self.editseriesID):
            self.editCurve = self.seriesPlotInfo.getSeries(self.editseriesID)

            ## TODO Duplicate UpdatePlot?
            logger.debug("Called duplicate updateplot")
            self.updatePlot()

    def make_patch_spines_invisible(self, ax):
        ax.set_frame_on(True)
        ax.patch.set_visible(False)
        for sp in ax.spines.itervalues():
            sp.set_visible(False)

    def _onMotion(self, event):
        """

        :type event: matplotlib.backend_bases.MouseEvent
        :return:
        """
        try:
            if event.xdata and event.ydata:
                xValue = matplotlib.dates.num2date(
                    event.xdata).replace(tzinfo=None)
                #self.toolbar.msg.SetLabelText("X= %s,  Y= %.2f" % (xValue.strftime("%Y-%m-%d %H:%M:%S"), event.ydata))
                #self.toolbar.msg.SetLabelText("X= %s,  Y= %.2f" % (xValue.strftime("%b %d, %Y %H:%M:%S"), event.ydata))
                self.toolbar.msg.SetLabelText(
                    "X= %s,  Y= %.2f" %
                    (xValue.strftime("%b %d, %Y %H:%M"), event.ydata))
                self.toolbar.msg.SetForegroundColour((66, 66, 66))
            else:
                self.toolbar.msg.SetLabelText("")
        except ValueError:
            pass

    def _onPick(self, event):
        """

        :param event:
        :return:
        """

        if isinstance(event.artist, Line2D):
            thisline = event.artist
            xdata = thisline.get_xdata()
            ydata = thisline.get_ydata()
            ind = event.ind

            xValue = xdata[ind][0]
            yValue = ydata[ind][0]
            #tip = '(%s, %s)' % (xValue.strftime("%Y-%m-%d %H:%M:%S"), yValue)
            #tip = '(%s, %s)' % (xValue.strftime("%b %d, %Y %H:%M:%S"), yValue)
            tip = '(%s, %s)' % (xValue.strftime("%b %d, %Y %H:%M"), yValue)

            self.tooltip.SetTip(tip)
            self.tooltip.Enable(True)
            self.tooltip.SetAutoPop(10000)

        elif isinstance(event.artist, Text):
            text = event.artist
            #print "Picking Label: ", text.get_text()

    def _onFigureLeave(self, event):
        """Catches mouse leaving the figure

        :param event:
        :return:
        """

        if self.tooltip.Window.Enabled:
            self.tooltip.SetTip("")
Ejemplo n.º 24
0
class AbstractPlot(wx.Panel):
	def __init__(self, parent, color=None, dpi=None, **kwargs):
		from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
		from matplotlib.figure import Figure
		
		# set default matplotlib parameters
		import matplotlib as mpl
		fontSize = 10
		mpl.rcParams['font.size'] = fontSize
		mpl.rcParams['axes.titlesize'] = fontSize
		mpl.rcParams['axes.labelsize'] = fontSize
		mpl.rcParams['xtick.labelsize'] = fontSize
		mpl.rcParams['ytick.labelsize'] = fontSize
		mpl.rcParams['legend.fontsize'] = fontSize

		# initialize Panel
		if 'id' not in kwargs.keys():
				kwargs['id'] = wx.ID_ANY
		if 'style' not in kwargs.keys():
				kwargs['style'] = wx.NO_FULL_REPAINT_ON_RESIZE
		wx.Panel.__init__(self, parent, **kwargs)

		# initialize matplotlib stuff
		self.figure = Figure(None, dpi)
		self.canvas = FigureCanvasWxAgg(self, -1, self.figure)
		self.SetColor( color )

		self.SetPlotSize()
		
		self._resizeFlag = False
		
		parent.Bind(wx.EVT_SIZE, self._OnSize)
		self.Bind(wx.EVT_IDLE, self._OnIdle)
		
	def _OnSize(self, event):
		self._resizeFlag = True
		
	def _OnIdle(self, event):
		if self._resizeFlag:
			self._resizeFlag = False
			self.SetPlotSize()

	def SetColor( self, rgbtuple=None ):
		"""Set figure and canvas colours to be the same."""
		if rgbtuple is None:
				rgbtuple = wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ).Get()
		clr = [c/255. for c in rgbtuple]
		self.figure.set_facecolor( clr )
		self.figure.set_edgecolor( clr )
		self.canvas.SetBackgroundColour( wx.Colour( *rgbtuple ) )

	def SetPlotSize( self ):
		""" Set plot to fill entire frame. """
		pixels = tuple( self.GetParent().GetClientSize() )
		self.SetSize( pixels )
		self.canvas.SetSize( pixels )
		self.figure.set_size_inches( float( pixels[0] )/self.figure.get_dpi(),
																 float( pixels[1] )/self.figure.get_dpi() )

	def Draw(self):
		"""Function to be overridden in derived class."""
		pass
		
	def DrawEmptyPlot(self):
		"""Draw empty plot."""
		self.figure.clf()
		
		emptyAxis = self.figure.add_axes([0.1,0.1,0.85,0.85]) 
		
		emptyAxis.set_ylabel('y axis')
		emptyAxis.set_xlabel('x axis')
																		 
		self.canvas.draw()
		
	def Clear(self):
		""" Clear current figure. """
		self.figure.clf()
		
	def SavePlot(self, dpi=300):
		"""Save plot to file."""
		saveImageDlg = SaveImageDlg(self)

		if saveImageDlg.ShowModal() == wx.ID_OK:
			if saveImageDlg.filename != None:
				self.figure.savefig(saveImageDlg.filename, format=saveImageDlg.format, dpi=saveImageDlg.DPI, facecolor='white', edgecolor='white')
	
		saveImageDlg.Destroy()
Ejemplo n.º 25
0
class GraphFrame(wx.Frame):
    def __init__(self,
                 parent,
                 style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE
                 | wx.FRAME_FLOAT_ON_PARENT):
        global graphFrame_enabled
        global mplImported
        global mpl_version

        self.legendFix = False

        if not graphFrame_enabled:
            pyfalog.warning(
                "Matplotlib is not enabled. Skipping initialization.")
            return

        try:
            cache_dir = mpl._get_cachedir()
        except:
            cache_dir = os.path.expanduser(os.path.join("~", ".matplotlib"))

        cache_file = os.path.join(cache_dir, 'fontList.cache')

        if os.access(cache_dir,
                     os.W_OK | os.X_OK) and os.path.isfile(cache_file):
            # remove matplotlib font cache, see #234
            os.remove(cache_file)
        if not mplImported:
            mpl.use('wxagg')

        graphFrame_enabled = True
        if int(mpl.__version__[0]) < 1:
            pyfalog.warning(
                "pyfa: Found matplotlib version {} - activating OVER9000 workarounds"
                .format(mpl.__version__))
            pyfalog.warning(
                "pyfa: Recommended minimum matplotlib version is 1.0.0")
            self.legendFix = True

        mplImported = True

        wx.Frame.__init__(self,
                          parent,
                          title="pyfa: Graph Generator",
                          style=style,
                          size=(520, 390))

        i = wx.Icon(BitmapLoader.getBitmap("graphs_small", "gui"))
        self.SetIcon(i)
        self.mainFrame = gui.mainFrame.MainFrame.getInstance()
        self.CreateStatusBar()

        self.mainSizer = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(self.mainSizer)

        sFit = Fit.getInstance()
        fit = sFit.getFit(self.mainFrame.getActiveFit())
        self.fits = [fit] if fit is not None else []
        self.fitList = FitList(self)
        self.fitList.SetMinSize((270, -1))

        self.fitList.fitList.update(self.fits)

        self.graphSelection = wx.Choice(self, wx.ID_ANY, style=0)
        self.mainSizer.Add(self.graphSelection, 0, wx.EXPAND)

        self.figure = Figure(figsize=(4, 3))

        rgbtuple = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get()
        clr = [c / 255. for c in rgbtuple]
        self.figure.set_facecolor(clr)
        self.figure.set_edgecolor(clr)

        self.canvas = Canvas(self, -1, self.figure)
        self.canvas.SetBackgroundColour(wx.Colour(*rgbtuple))

        self.subplot = self.figure.add_subplot(111)
        self.subplot.grid(True)

        self.mainSizer.Add(self.canvas, 1, wx.EXPAND)
        self.mainSizer.Add(
            wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize,
                          wx.LI_HORIZONTAL), 0, wx.EXPAND)

        self.gridPanel = wx.Panel(self)
        self.mainSizer.Add(self.gridPanel, 0, wx.EXPAND)

        dummyBox = wx.BoxSizer(wx.VERTICAL)
        self.gridPanel.SetSizer(dummyBox)

        self.gridSizer = wx.FlexGridSizer(0, 4, 0, 0)
        self.gridSizer.AddGrowableCol(1)
        dummyBox.Add(self.gridSizer, 0, wx.EXPAND)

        for view in Graph.views:
            view = view()
            self.graphSelection.Append(view.name, view)

        self.graphSelection.SetSelection(0)
        self.fields = {}
        self.select(0)
        self.sl1 = wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition,
                                 wx.DefaultSize, wx.LI_HORIZONTAL)
        self.mainSizer.Add(self.sl1, 0, wx.EXPAND)
        self.mainSizer.Add(self.fitList, 0, wx.EXPAND)

        self.fitList.fitList.Bind(wx.EVT_LEFT_DCLICK, self.removeItem)
        self.mainFrame.Bind(GE.FIT_CHANGED, self.draw)
        self.Bind(wx.EVT_CLOSE, self.closeEvent)
        self.Bind(wx.EVT_CHAR_HOOK, self.kbEvent)

        self.Fit()
        self.SetMinSize(self.GetSize())

    def handleDrag(self, type, fitID):
        if type == "fit":
            self.AppendFitToList(fitID)

    def closeEvent(self, event):
        self.closeWindow()
        event.Skip()

    def kbEvent(self, event):
        keycode = event.GetKeyCode()
        if keycode == wx.WXK_ESCAPE:
            self.closeWindow()
            return
        event.Skip()

    def closeWindow(self):
        self.fitList.fitList.Unbind(wx.EVT_LEFT_DCLICK,
                                    handler=self.removeItem)
        self.mainFrame.Unbind(GE.FIT_CHANGED, handler=self.draw)
        self.Destroy()

    def getView(self):
        return self.graphSelection.GetClientData(
            self.graphSelection.GetSelection())

    def getValues(self):
        values = {}
        for fieldName, field in self.fields.items():
            values[fieldName] = field.GetValue()

        return values

    def select(self, index):
        view = self.getView()
        icons = view.getIcons()
        labels = view.getLabels()
        sizer = self.gridSizer
        self.gridPanel.DestroyChildren()
        self.fields.clear()

        # Setup textboxes
        for field, defaultVal in view.getFields().items():

            textBox = wx.TextCtrl(self.gridPanel, wx.ID_ANY, style=0)
            self.fields[field] = textBox
            textBox.Bind(wx.EVT_TEXT, self.onFieldChanged)
            sizer.Add(textBox, 1,
                      wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 3)
            if defaultVal is not None:
                if not isinstance(defaultVal, str):
                    defaultVal = ("%f" % defaultVal).rstrip("0")
                    if defaultVal[-1:] == ".":
                        defaultVal += "0"

                textBox.ChangeValue(defaultVal)

            imgLabelSizer = wx.BoxSizer(wx.HORIZONTAL)
            if icons:
                icon = icons.get(field)
                if icon is not None:
                    static = wx.StaticBitmap(self.gridPanel)
                    static.SetBitmap(icon)
                    imgLabelSizer.Add(static, 0,
                                      wx.ALL | wx.ALIGN_CENTER_VERTICAL, 1)

            if labels:
                label = labels.get(field)
                label = label if label is not None else field
            else:
                label = field

            imgLabelSizer.Add(wx.StaticText(self.gridPanel, wx.ID_ANY,
                                            label), 0,
                              wx.LEFT | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, 3)
            sizer.Add(imgLabelSizer, 0, wx.ALIGN_CENTER_VERTICAL)
        self.draw()

    def draw(self, event=None):
        global mpl_version

        if event is not None:
            event.Skip()

        # todo: FIX THIS, see #1430. draw() is not being unbound properly when the window closes, this is an easy fix,
        # but not a proper solution
        if not self:
            pyfalog.warning(
                "GraphFrame handled event, however GraphFrame no longer exists. Ignoring event"
            )
            return

        values = self.getValues()
        view = self.getView()
        self.subplot.clear()
        self.subplot.grid(True)
        legend = []

        for fit in self.fits:
            try:
                success, status = view.getPoints(fit, values)
                if not success:
                    # TODO: Add a pwetty statys bar to report errors with
                    self.SetStatusText(status)
                    return

                x, y = success, status

                self.subplot.plot(x, y)
                legend.append(fit.name)
            except Exception as ex:
                pyfalog.warning("Invalid values in '{0}'", fit.name)
                self.SetStatusText("Invalid values in '%s'" % fit.name)
                self.canvas.draw()
                return

        if mpl_version < 2:
            if self.legendFix and len(legend) > 0:
                leg = self.subplot.legend(tuple(legend),
                                          "upper right",
                                          shadow=False)
                for t in leg.get_texts():
                    t.set_fontsize('small')

                for l in leg.get_lines():
                    l.set_linewidth(1)

            elif not self.legendFix and len(legend) > 0:
                leg = self.subplot.legend(tuple(legend),
                                          "upper right",
                                          shadow=False,
                                          frameon=False)
                for t in leg.get_texts():
                    t.set_fontsize('small')

                for l in leg.get_lines():
                    l.set_linewidth(1)
        elif mpl_version >= 2:
            legend2 = []
            legend_colors = {
                0: "blue",
                1: "orange",
                2: "green",
                3: "red",
                4: "purple",
                5: "brown",
                6: "pink",
                7: "grey",
            }

            for i, i_name in enumerate(legend):
                try:
                    selected_color = legend_colors[i]
                except:
                    selected_color = None
                legend2.append(Patch(color=selected_color, label=i_name), )

            if len(legend2) > 0:
                leg = self.subplot.legend(handles=legend2)
                for t in leg.get_texts():
                    t.set_fontsize('small')

                for l in leg.get_lines():
                    l.set_linewidth(1)

        self.canvas.draw()
        self.SetStatusText("")

    def onFieldChanged(self, event):
        self.draw()

    def AppendFitToList(self, fitID):
        sFit = Fit.getInstance()
        fit = sFit.getFit(fitID)
        if fit not in self.fits:
            self.fits.append(fit)

        self.fitList.fitList.update(self.fits)
        self.draw()

    def removeItem(self, event):
        row, _ = self.fitList.fitList.HitTest(event.Position)
        if row != -1:
            del self.fits[row]
            self.fitList.fitList.update(self.fits)
            self.draw()
Ejemplo n.º 26
0
class plotBox(wx.Panel):
    def _init_coll_boxSizer1_Items(self, parent):
        # generated method, don't edit

        parent.AddWindow(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        parent.AddWindow(self.toolbar, 0, wx.EXPAND)

    def _init_sizers(self):
        # generated method, don't edit
        self.boxSizer1 = wx.BoxSizer(orient=wx.VERTICAL)
        self._init_coll_boxSizer1_Items(self.boxSizer1)
        self.SetSizer(self.boxSizer1)

    def _init_ctrls(self, prnt):
        #matplotlib.figure.Figure.__init__(self)
        wx.Panel.__init__(self, prnt, -1)

        Publisher.subscribe(self.monthly, ("box.Monthly"))
        Publisher.subscribe(self.yearly, ("box.Yearly"))
        Publisher.subscribe(self.seasonaly, ("box.Seasonal"))
        Publisher.subscribe(self.overall, ("box.Overall"))

        self.figure = matplotlib.figure.Figure()
        self.plot = self.figure.add_subplot(111)
        self.plot.axis([0, 1, 0, 1])  #
        self.plot.set_title("No Data To Plot")

        self.canvas = FigCanvas(self, -1, self.figure)
        # Create the navigation toolbar, tied to the canvas
        self.toolbar = NavigationToolbar(self.canvas, True)
        self.toolbar.Realize()

        #self.canvas.SetCursor(wx.StockCursor(wx.CURSOR_CROSS))
        #self.canvas.SetScrollbar(wx.HORIZONTAL, 0,5, 1000)
        self.SetColor("WHITE")
        self.canvas.SetFont(
            wx.Font(20, wx.SWISS, wx.NORMAL, wx.NORMAL, False, u'Tahoma'))
        self.canvas.draw()
        self._init_sizers()

    def Clear(self):
        self.figure.clear()

    def GridSize(self, cells):
        rows = 1
        cols = 1
        while rows * cols < cells:
            if rows == cols:
                cols = cols + 1
            else:
                rows = rows + 1
        return rows, cols

    def textSize(self, cells):
        wrap = 50
        wrap = wrap - (cells * 3)
        text = 20 - cells
        return wrap, text

    def Plot(self, seriesPlotInfo):
        self.seriesPlotInfo = seriesPlotInfo
        self.updatePlot()

    def updatePlot(self):
        self.Clear()
        count = self.seriesPlotInfo.count()
        rows, cols = self.GridSize(count)
        self.plots = []
        i = 1
        for oneSeries in self.seriesPlotInfo.GetSeriesInfo():
            self.plots.append(
                self.figure.add_subplot(repr(rows) + repr(cols) + repr(i)))

            wrap, text = self.textSize(count)
            self.plots[i - 1].set_xlabel("\n".join(
                textwrap.wrap(oneSeries.BoxWhisker.currinterval.title, wrap)))
            self.plots[i - 1].set_ylabel("\n".join(
                textwrap.wrap(
                    oneSeries.variableName + "(" + oneSeries.variableUnits +
                    ")", wrap)))
            self.plots[i - 1].set_title("\n".join(
                textwrap.wrap(
                    oneSeries.siteName + " " + oneSeries.variableName, wrap)))

            self.canvas.SetFont(
                wx.Font(text, wx.SWISS, wx.NORMAL, wx.NORMAL, False,
                        u'Tahoma'))

            med = oneSeries.BoxWhisker.currinterval.medians
            cl = oneSeries.BoxWhisker.currinterval.confint
            mean = oneSeries.BoxWhisker.currinterval.means
            ci = oneSeries.BoxWhisker.currinterval.conflimit
            bp = self.plots[i - 1].boxplot(
                oneSeries.BoxWhisker.currinterval.data,
                sym="-gs",
                notch=True,
                bootstrap=5000,
                conf_intervals=cl)

            # Plot Mean and its confidence interval
            for x in range(len(mean)):
                self.plots[i - 1].vlines(x + 1,
                                         ci[x][0],
                                         ci[x][1],
                                         color='r',
                                         linestyle="solid")
            self.plots[i - 1].scatter([range(1,
                                             len(mean) + 1)],
                                      mean,
                                      marker='o',
                                      c='r',
                                      s=10)

            # Plot Median
            self.plots[i - 1].scatter([range(1,
                                             len(med) + 1)],
                                      med,
                                      marker='s',
                                      c="k",
                                      s=10)

            # Set Colors of the Box Whisker plot
            plt.setp(bp['whiskers'], color='k', linestyle='-')
            plt.setp(bp['medians'], color='k', linestyle='-')
            plt.setp(bp['boxes'], color='GREY', linestyle='-')
            plt.setp(bp['caps'], color='k')
            plt.setp(bp['fliers'], markersize=3.5)

            # self.plot.set_ybound(min(data),max(data))
            self.plots[i - 1].set_autoscale_on(True)
            self.plots[i - 1].set_xticklabels(
                oneSeries.BoxWhisker.currinterval.xlabels)

            i = i + 1

        self.canvas.draw()

    def SetColor(self, color):
        # """Set figure and canvas colours to be the same."""
        self.figure.set_facecolor(color)
        self.figure.set_edgecolor(color)
        self.canvas.SetBackgroundColour(color)

    def monthly(self, str):
        # print "monthly"
        self.seriesPlotInfo.SetBoxInterval("Monthly")
        self.updatePlot()

    def seasonaly(self, str):
        # print"seasonal"
        self.seriesPlotInfo.SetBoxInterval("Seasonally")
        self.updatePlot()

    def yearly(self, str):
        # print "yearly"
        self.seriesPlotInfo.SetBoxInterval("Yearly")
        self.updatePlot()

    def overall(self, str):
        # print "overall"
        self.seriesPlotInfo.SetBoxInterval("Overall")
        self.updatePlot()

    def __init__(self, parent, id, pos, size, style, name):
        self._init_ctrls(parent)
Ejemplo n.º 27
0
class CTRL(wx.Panel):
    def __init__(self, parent, style=wx.TAB_TRAVERSAL):
        wx.Panel.__init__(self, parent, id=-1, style=style)
        self.IDcompte = None
        self.date_debut = None
        self.date_fin = None
        
        self.figure = matplotlib.pyplot.figure()
        self.canvas = Canvas(self, -1, self.figure)
        self.SetColor( (255,255,255) )
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.canvas,1,wx.EXPAND|wx.ALL, 0)
        self.SetSizer(sizer)
            
    def convertCouleur(self, RGB) :
        couleur = []
        for valeur in RGB :
            couleur.append(valeur/255.0)
        return couleur

    def SetColor(self, rgbtuple=None):
        """Set figure and canvas colours to be the same."""
        if rgbtuple is None:
            rgbtuple = wx.SystemSettings.GetColour( wx.SYS_COLOUR_BTNFACE ).Get()
        clr = [c/255. for c in rgbtuple]
        self.figure.set_facecolor(clr)
        self.figure.set_edgecolor(clr)
        self.canvas.SetBackgroundColour(wx.Colour(*rgbtuple))
    
    def SetCompte(self, IDcompte=None):
        self.IDcompte = IDcompte
        
    def SetPeriode(self, code="", date_debut=None, date_fin=None):
        """ Attribue la période """
        dateJour = datetime.date.today() 
        self.date_debut = None
        self.date_fin = None

        if code == "actuellement" :
            self.date_debut = dateJour + relativedelta.relativedelta(days=-25)
            self.date_fin = dateJour + relativedelta.relativedelta(days=+30)
        if code == "7_prochains_jours" :
            self.date_debut = dateJour
            self.date_fin = dateJour + relativedelta.relativedelta(days=+7)
        if code == "14_prochains_jours" :
            self.date_debut = dateJour
            self.date_fin = dateJour + relativedelta.relativedelta(days=+14)
        if code == "30_prochains_jours" :
            self.date_debut = dateJour
            self.date_fin = dateJour + relativedelta.relativedelta(days=+30)
        if code == "90_prochains_jours" :
            self.date_debut = dateJour
            self.date_fin = dateJour + relativedelta.relativedelta(days=+90)
        if code == "6_prochains_mois" :
            self.date_debut = dateJour
            self.date_fin = dateJour + relativedelta.relativedelta(months=+6)
        if code == "12_prochains_mois" :
            self.date_debut = dateJour
            self.date_fin = dateJour + relativedelta.relativedelta(months=+12)
        if code == "mois_actuel" :
            self.date_debut = datetime.date(dateJour.year, dateJour.month, 1)
            self.date_fin = datetime.date(dateJour.year, dateJour.month, 1) + relativedelta.relativedelta(months=+1) - relativedelta.relativedelta(days=+1)
        if code == "annee_actuelle" :
            self.date_debut = datetime.date(dateJour.year, 1, 1)
            self.date_fin = datetime.date(dateJour.year, 12, 31)
        if code == "personnalise" :
            self.date_debut = date_debut
            self.date_fin = date_fin
        
        self.MAJ() 
    
    def GetDonnees(self):
        DB = GestionDB.DB()
        req = """SELECT IDoperation, type, date, IDreleve, montant
        FROM compta_operations 
        WHERE IDcompte_bancaire=%d
        ORDER BY date, IDoperation;""" % self.IDcompte
        DB.ExecuterReq(req)
        listeOperations = DB.ResultatReq()
        DB.Close()
        
        # Analyse des opérations
        listeDonnees = []
        solde = 0.0
        for IDoperation, typeOperation, date, IDreleve, montant in listeOperations :
            date = UTILS_Dates.DateEngEnDateDD(date)
            if typeOperation == "debit" :
                solde -= montant
            else :
                solde += montant
            listeDonnees.append((date, solde))
        return listeDonnees

    def MAJ(self) :
        self.figure.clear()
        
        if self.IDcompte == None or self.date_debut == None or self.date_fin == None :
            wx.CallAfter(self.SendSizeEvent)
            return
        
        listeDates = []
        listeValeurs = []
        for date, valeur in self.GetDonnees() :
            if date >= self.date_debut and date <= self.date_fin :
                listeDates.append(date)
                listeValeurs.append(valeur)

        if len(listeDates) < 2 :
            wx.CallAfter(self.SendSizeEvent)
            return
            
        ax = self.figure.add_subplot(111)
                
        # Sélection du mode d'affichage
        mode = None
        nbreJours = (self.date_fin - self.date_debut).days #(max(listeDates) - min(listeDates)).days
        if nbreJours < 60 :
            mode = "jour"
        elif nbreJours < 400 :
            mode = "mois"
        else :
            mode = "annee"
        
        # Affichage par année
        if mode == "annee" :
            anneeMin = self.date_debut.year
            anneeMax = self.date_max.year + 1
            ax.xaxis.set_major_locator(mdates.YearLocator())
            ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y'))
            ax.xaxis.set_minor_locator(mdates.MonthLocator())
            datemin = datetime.date(anneeMin, 1, 1)
            datemax = datetime.date(anneeMax, 1, 1)
            ax.set_xlim(datemin, datemax)

##        ax.xaxis.set_major_locator(mdates.AutoDateLocator())
##        ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))

##        ax.xaxis.set_major_locator(mdates.DayLocator())
##        ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))

        if mode ==  "mois" :
            ax.xaxis.set_major_locator(mdates.MonthLocator())
            ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %Y'))

        if mode == "jour" :
            ax.xaxis.set_major_locator(mdates.AutoDateLocator())
##            ax.xaxis.set_minor_locator(mdates.DayLocator())      
            ax.xaxis.set_major_formatter(mdates.DateFormatter('%d/%m/%Y'))
##            ax.set_xlim([min(listeDates), max(listeDates)])      
            ax.set_xlim([self.date_debut, self.date_fin])      

        ax.fill_between(listeDates, 0, listeValeurs, facecolor='blue', alpha=0.5, label=_(u"Trésorerie"))
        
        self.figure.autofmt_xdate()

        ax.grid(True)
        ax.figure.canvas.draw()
        wx.CallAfter(self.SendSizeEvent)
        return
        
        
        
        
        
        

        x = [0, 0, 3.5, 4, 5]#np.linspace(0, 1)
        y = [0, 10, 2, 3, 4]

        ax.fill(x, y, 'r')
        ax.grid(True)
        ax.figure.canvas.draw()
        
        return
        # Création du graph
        ind = arange(len(listeLabels)) + 0.25  # the x locations for the groups
        width = 0.5
        for x in range(len(listeLabels)) :
##            couleur = MODELES.ConvertitCouleur2(MODELES.COULEUR_VERT_POMME)
            barre = ax.bar(ind[x], listeValeurs[x], width)#, color=couleur)
        
##        # Axe horizontal
##        ind = arange(len(listeLabels)) 
##        ax.set_xticks(ind + width) 
##        ax.set_xticklabels(listeLabels)
##        labelsx = ax.get_xticklabels()
##        labelsy = ax.get_yticklabels()
##        matplotlib.pyplot.setp(labelsx, rotation=45, fontsize=9, horizontalalignment='right')
##        
##        # Axe vertical
##        ax.set_ylabel("Nbre de familles", fontsize=8)
        
        labels = ax.get_yticklabels()
        matplotlib.pyplot.setp(labels, rotation=0, fontsize=9) 
        
        # Titre
        title = ax.set_title(_(u"Comparatif du nombre de familles"), weight="bold", horizontalalignment = 'center')#, position=(0.5, 0.97))
        matplotlib.pyplot.setp(title, rotation=0, fontsize=9)
        
        self.figure.subplots_adjust(left=None, bottom=0.4, right=None, wspace=None, hspace=None)
        
        # Affiche les grilles
        ax.grid(True)

        # Re-dessine le canvas
        ax.figure.canvas.draw()
Ejemplo n.º 28
0
class MyPlotPanel(wx.Panel):
    def __init__(self, parent, figsize=None, dpi=None,
                 bgcolor=None, type=None, toolbar=None, aspect=1,
                 **kwargs):
        """ construction method of MyPlotPanel class
        :param parent: parent object
        :param figsize: plot figure size, (w, h)
        :param dpi: figure dpi,
        :parma bgcolor: background color of figure and canvas
        :param type: type of initial figure, 'image' or 'line'
        :param toolbar: show toolbar if not set None
        """
        wx.Panel.__init__(self, parent, **kwargs)
        self.parent = parent
        self.figsize = figsize
        self.dpi = dpi
        self.bgcolor = bgcolor
        self.type = type
        self.toolbar = toolbar
        self.aspect = aspect
        self.figure = Figure(self.figsize, self.dpi)
        self.canvas = FigureCanvas(self, -1, self.figure)

        # figure background color
        self.set_color(self.bgcolor)

        # initialize plot
        self._init_plot()

        # set layout
        self.set_layout()

        # binding events
        self.canvas.mpl_connect('button_press_event', self.on_press)
        self.canvas.mpl_connect('button_release_event', self.on_release)
        self.canvas.mpl_connect('motion_notify_event', self.on_motion)
        self.Bind(wx.EVT_SIZE, self.on_size)

    def set_layout(self):
        """ set panel layout
        """
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.canvas, 1, wx.EXPAND)
        hbox = wx.BoxSizer(wx.HORIZONTAL)
        if self.toolbar is not None:
            self.toobar = MyToolbar(self.canvas)
            self.toobar.Realize()
            hbox.Add(self.toobar, 0, wx.EXPAND | wx.RIGHT, 10)
        self.pos_st = wx.StaticText(self, label='')
        hbox.Add(self.pos_st, 0, wx.ALIGN_CENTER_VERTICAL)
        sizer.Add(hbox, 0, wx.EXPAND | wx.BOTTOM, 0)
        self.SetSizerAndFit(sizer)

    def _init_plot(self):
        if not hasattr(self, 'axes'):
            self.axes = self.figure.add_subplot(111, aspect=self.aspect)
        if self.type == 'image':  # draw image
            x = y = np.linspace(-np.pi, np.pi, 100)
            self.x, self.y = np.meshgrid(x, y)
            self.z = self._func_peaks(self.x, self.y)
            self.image = self.axes.imshow(self.z)
        else:  # draw line
            self.x = np.linspace(-10, 10, 200)
            self.y = np.sin(self.x)
            self.line, = self.axes.plot(self.x, self.y)

    def set_color(self, rgb_tuple):
        """ set figure and canvas with the same color.

        :param rgb_tuple: rgb color tuple, e.g. (255, 255, 255) for white color
        """
        if rgb_tuple is None:
            rgb_tuple = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get()
        clr = [c / 255.0 for c in rgb_tuple]
        self.figure.set_facecolor(clr)
        self.figure.set_edgecolor(clr)
        self.canvas.SetBackgroundColour(wx.Colour(*rgb_tuple))

    def on_size(self, event):
        self.fit_canvas()
        self.canvas.draw_idle()
        event.Skip()

    def on_press(self, event):
        pass

    def on_release(self, event):
        pass

    def on_motion(self, event):
        if event.inaxes is not None:
            self.pos_st.SetLabel("({x:<.4f}, {y:<.4f})".format(x=event.xdata, y=event.ydata))

    def fit_canvas(self):
        """ tight fit canvas layout
        """
        # self.canvas.SetSize(self.GetSize())
        self.figure.set_tight_layout(True)

    def _func_peaks(self, x, y):
        return 3.0 * (1.0 - x) ** 2.0 * np.exp(-(x ** 2) - (y + 1) ** 2) \
               - 10 * (x / 5 - x ** 3 - y ** 5) * np.exp(-x ** 2 - y ** 2) \
               - 1.0 / 3.0 * np.exp(-(x + 1) ** 2 - y ** 2)
Ejemplo n.º 29
0
class plotHist(wx.Panel):


  def _init_coll_boxSizer1_Items(self, parent):
      # generated method, don't edit

      parent.AddWindow(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
      parent.AddWindow(self.toolbar, 0,  wx.EXPAND)


  def _init_sizers(self):
      # generated method, don't edit
      self.boxSizer1 = wx.BoxSizer(orient=wx.VERTICAL)
      self._init_coll_boxSizer1_Items(self.boxSizer1)
      self.SetSizer(self.boxSizer1)



  def _init_ctrls(self, prnt):
      #matplotlib.figure.Figure.__init__(self)
      wx.Panel.__init__(self, prnt, -1)

      self.figure = matplotlib.figure.Figure()
      self.plot=self.figure.add_subplot(111)

      self.plot.set_title("No Data To Plot")

      self.canvas = FigCanvas(self, -1, self.figure)
      
      # Create the navigation toolbar, tied to the canvas
      self.toolbar = NavigationToolbar(self.canvas, True)
      self.toolbar.Realize()


      self.SetColor("WHITE")
      self.canvas.SetFont(wx.Font(20, wx.SWISS, wx.NORMAL, wx.NORMAL,
            False, u'Tahoma'))


      self.canvas.draw()
      self._init_sizers()
      self.hist=[]
      self.bins=50



  def ChangeNumOfBins(self, bins):
      self.bins = bins
      self.updatePlot()


  def Clear(self):
      self.figure.clear()
      self.hist=[]

  def GridSize(self, cells):
      rows = 1
      cols = 1
      while rows * cols < cells:
        if rows == cols:
          cols = cols + 1
        else:
          rows = rows + 1
      return rows, cols

  def textSize(self, cells):
      wrap = 50
      wrap = wrap-(cells*3)
      text= 20 -cells
      return wrap, text

  def Plot(self, seriesPlotInfo):
      self.seriesPlotInfo= seriesPlotInfo
      self.updatePlot()

  def updatePlot(self):
      self.Clear()
      count = self.seriesPlotInfo.count()
      rows, cols = self.GridSize(count)
      self.plots=[]
      i=1
      for oneSeries in self.seriesPlotInfo.GetSeriesInfo():
        self.plots.append(self.figure.add_subplot(repr(rows)+repr(cols)+repr(i)))

        wrap, text = self.textSize(count)
        self.plots[i-1].set_xlabel("\n".join(textwrap.wrap(oneSeries.variableName,wrap)))
        self.plots[i-1].set_ylabel("Number of Observations")

        self.canvas.SetFont(wx.Font(text, wx.SWISS, wx.NORMAL, wx.NORMAL,
            False, u'Tahoma'))

        self.plots[i-1].set_title("\n".join(textwrap.wrap(oneSeries.siteName+" "+oneSeries.variableName,wrap)))


        self.hist.append(self.plots[i-1].hist([x[0] for x in oneSeries.dataTable], bins=self.bins, normed=False, facecolor='g', alpha=0.75, label = oneSeries.siteName+" "+oneSeries.variableName))
        i=i+1

      self.canvas.draw()


  def SetColor( self, color):
      """Set figure and canvas colours to be the same."""
      self.figure.set_facecolor( color )
      self.figure.set_edgecolor( color )
      self.canvas.SetBackgroundColour( color )







  def __init__(self, parent, id, pos, size, style, name):
      self._init_ctrls(parent)
Ejemplo n.º 30
0
class PlotPanelMPL(wx.Panel):
    def __init__(self, parent):
        global graphFrame_enabled
        global mplImported
        global mpl_version

        if not graphFrame_enabled:
            pyfalog.warning(
                "Matplotlib is not enabled. Skipping initialization.")
            raise Exception()

        try:
            cache_dir = mpl._get_cachedir()
        except:
            cache_dir = os.path.expanduser(os.path.join("~", ".matplotlib"))
        cache_file = os.path.join(cache_dir, 'fontList.cache')
        if os.access(cache_dir,
                     os.W_OK | os.X_OK) and os.path.isfile(cache_file):
            # remove matplotlib font cache, see #234
            os.remove(cache_file)
        if not mplImported:
            mpl.use('wxagg')

        graphFrame_enabled = True
        self.legendFix = False
        if int(mpl.__version__[0]) < 1:
            print("pyfa: Found matplotlib version ", mpl.__version__,
                  " - activating OVER9000 workarounds")
            print("pyfa: Recommended minimum matplotlib version is 1.0.0")
            self.legendFix = True
        mplImported = True

        wx.Panel.__init__(self, parent)

        self.sizer = wx.FlexGridSizer(2, 2)
        self.sizer.AddGrowableRow(0)
        self.sizer.AddGrowableCol(1)
        self.SetSizer(self.sizer)

        self.labelY = wx.StaticText(
            self, label="")  # TODO custom control for rotated text?
        self.sizer.Add(self.labelY, flag=wx.ALIGN_CENTER | wx.ALL, border=3)

        self.figure = Figure(figsize=(4, 3))
        colorByte = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get()
        colorFloat = [c / 255. for c in colorByte]
        self.figure.set_facecolor(colorFloat)
        self.figure.set_edgecolor(colorFloat)
        self.subplot = self.figure.add_axes([0, 0, 1, 1])

        self.canvas = Canvas(self, -1, self.figure)
        self.canvas.SetBackgroundColour(wx.Colour(*colorByte))
        self.canvas.mpl_connect('pick_event', lambda event: self.onPick(event))
        self.canvas.mpl_connect('button_press_event',
                                lambda event: self.onPlotClick(event))
        self.sizer.Add(self.canvas, proportion=1, flag=wx.EXPAND)

        self.sizer.Add(wx.StaticText(self, label=""),
                       flag=wx.ALIGN_CENTER | wx.ALL,
                       border=3)

        self.labelX = wx.StaticText(self, label="")
        self.sizer.Add(self.labelX, flag=wx.ALIGN_CENTER | wx.ALL, border=3)

        self._parent = parent
        self._lines = {}
        self.ondrag = None
        self.onrelease = None

    def draw(self, lineData, markerX=None):
        self._lines.clear()
        self.maxX = 1
        self.maxY = 1
        self.subplot.clear()
        self.subplot.grid(True)

        for lineID, xdata, ydata, markerY, color, selected in lineData:
            self._lines[lineID], = self.subplot.plot(
                xdata,
                ydata,
                color=color,
                linewidth=(2 if selected else 1),
                picker=5)
            self.maxX = max(self.maxX, max(xdata))
            self.maxY = max(self.maxY, max(ydata))
            if markerX and (markerY is not None):
                self.subplot.annotate("%.1f" % (markerY, ),
                                      xy=(markerX, markerY),
                                      xytext=(-1, 1),
                                      textcoords="offset pixels",
                                      ha="right",
                                      va="bottom",
                                      fontsize="small")
        if markerX:
            self.subplot.axvline(x=markerX,
                                 linestyle="dotted",
                                 linewidth=1,
                                 color=(0, 0, 0))
            self.subplot.annotate("@ %.1f" % (markerX, ),
                                  xy=(markerX, self.maxY * 1.1),
                                  xytext=(-1, -1),
                                  textcoords="offset pixels",
                                  ha="right",
                                  va="top",
                                  fontsize="small")

        self.subplot.set_xlim(left=0, right=self.maxX * 1.05)
        self.subplot.set_ylim(bottom=0, top=self.maxY * 1.1)
        self.subplot.tick_params(direction="in", width=2, length=6)

        self.subplot.tick_params(axis="x", pad=-5.0)
        tickvalues = mpl.ticker.MaxNLocator(nbins=15,
                                            steps=[1, 2, 5, 10],
                                            integer=True,
                                            min_n_ticks=10,
                                            prune="lower").tick_values(
                                                0, self.maxX * 1.025)
        xticks = list(int(v) for v in tickvalues)
        self.subplot.set_xticks(xticks)
        self.subplot.set_xticklabels(xticks, va="bottom")

        self.subplot.tick_params(axis="y", pad=-8.0)
        tickvalues = mpl.ticker.MaxNLocator(nbins=12,
                                            steps=[1, 2, 5, 10],
                                            integer=True,
                                            min_n_ticks=8,
                                            prune="lower").tick_values(
                                                0, self.maxY * 1.05)
        yticks = list(int(v) for v in tickvalues)
        self.subplot.set_yticks(yticks)
        self.subplot.set_yticklabels(yticks, ha="left")

        self.canvas.draw()

    def onPlotClick(self, event):
        if event.button == 3:
            self._parent.setMarkerX(event.xdata)
            if not self.ondrag:
                self.ondrag = self.canvas.mpl_connect(
                    'motion_notify_event',
                    lambda event: self.onPlotDrag(event))
            if not self.onrelease:
                self.onrelease = self.canvas.mpl_connect(
                    'button_release_event',
                    lambda event: self.onPlotRelease(event))

    def onPlotDrag(self, event):
        self._parent.setMarkerX(event.xdata)

    def onPlotRelease(self, event):
        if event.button == 3:
            self._parent.setMarkerX(event.xdata)
            if self.ondrag:
                self.canvas.mpl_disconnect(self.ondrag)
                self.ondrag = None
            if self.onrelease:
                self.canvas.mpl_disconnect(self.onrelease)
                self.onrelease = None

    def onPick(self, event):
        for lineID, line in self._lines.iteritems():
            if line == event.artist:
                self._parent.setSelectedLine(lineID)