Beispiel #1
0
    def __init__(self, masterWindow, style=None, scheme=None):
        self.masterWindow = masterWindow
        self.legend = False

        plotArea = masterWindow.ui.plotArea

        #create the plotting canvas and its toolbar and add them
        tfig = Figure()
        tfig.set_facecolor('white')
        self.canvas = FigureCanvasQTAgg(tfig)
        self.navbar = AstonNavBar(self.canvas, masterWindow)
        plotArea.addWidget(self.navbar)
        plotArea.addWidget(self.canvas)

        #TODO this next line is the slowest in this module
        #self.plt = tfig.add_subplot(111, frameon=False)
        self.plt = tfig.add_axes((0.05, 0.1, 0.9, 0.85), frame_on=False)
        self.plt.xaxis.set_ticks_position('none')
        self.plt.yaxis.set_ticks_position('none')
        self.patches = []
        self.cb = None

        #TODO: find a way to make the axes fill the figure properly
        #tfig.subplots_adjust(left=0.05, right=0.95, bottom=0.05, top=0.95)
        #tfig.tight_layout(pad=2)

        self.canvas.setFocusPolicy(Qt.ClickFocus)
        self.canvas.mpl_connect('button_press_event', self.mousedown)
        self.canvas.mpl_connect('button_release_event', self.mouseup)
        self.canvas.mpl_connect('scroll_event', self.mousescroll)

        self.highlight = None
Beispiel #2
0
class Plotter(object):
    def __init__(self, masterWindow, style=None, scheme=None):
        self.masterWindow = masterWindow
        self.legend = False

        plotArea = masterWindow.ui.plotArea

        #create the plotting canvas and its toolbar and add them
        tfig = Figure()
        tfig.set_facecolor('white')
        self.canvas = FigureCanvasQTAgg(tfig)
        self.navbar = AstonNavBar(self.canvas, masterWindow)
        plotArea.addWidget(self.navbar)
        plotArea.addWidget(self.canvas)

        #TODO this next line is the slowest in this module
        #self.plt = tfig.add_subplot(111, frameon=False)
        self.plt = tfig.add_axes((0.05, 0.1, 0.9, 0.85), frame_on=False)
        self.plt.xaxis.set_ticks_position('none')
        self.plt.yaxis.set_ticks_position('none')
        self.patches = []
        self.cb = None

        #TODO: find a way to make the axes fill the figure properly
        #tfig.subplots_adjust(left=0.05, right=0.95, bottom=0.05, top=0.95)
        #tfig.tight_layout(pad=2)

        self.canvas.setFocusPolicy(Qt.ClickFocus)
        self.canvas.mpl_connect('button_press_event', self.mousedown)
        self.canvas.mpl_connect('button_release_event', self.mouseup)
        self.canvas.mpl_connect('scroll_event', self.mousescroll)

        self.highlight = None

    def availStyles(self):
        l_ord = ['default', 'scaled', 'stacked', 'scaled stacked', '2d']
        return [self._styles[s] for s in l_ord]

    def plot_data(self, plots, update_bounds=True):
        if not update_bounds:
            bnds = self.plt.get_xlim(), self.plt.get_ylim()

        # clean up anything on the graph already
        self.plt.cla()
        if self.cb is not None:
            #TODO: this should work? need way to update size of mappable axes
            #self.plt.figure.delaxes(self.cb.ax)
            #self.cb.mappable.axes.autoscale()
            #self.cb = None
            #the next two lines used to work?
            self.plt.figure.delaxes(self.cb.ax)
            self.cb = None
            tfig = self.plt.figure
            tfig.clf()
            self.plt = tfig.add_subplot(111, frameon=False)
            self.plt.xaxis.set_ticks_position('none')
            self.plt.yaxis.set_ticks_position('none')
            self.cb = None
        self.plt.figure.subplots_adjust(left=0.05, right=0.95)
        self.patches = []

        #plot all of the datafiles
        if len(plots) == 0:
            self.canvas.draw()
            return

        ## make up a factor to separate plots by
        #if 'stacked' in self._style:
        #    fts = datafils[0].trace(datafiles[0].info['traces'].split(',')[0])
        #    sc_factor = (max(fts.data[:, 0]) - min(fts.data[:, 0])) / 5.

        ## count the number of traces that will be displayed
        #trs = sum(1 for x in datafiles for _ in x.info['traces'].split(','))
        nplots = len(plots)
        if nplots < 6:
            alpha = 0.75 - nplots * 0.1
        else:
            alpha = 0.15
        #FIXME: read this from the menu
        colors = get_cmap('Spectral')

        #TODO: determine the number of axes to use
        #TODO: should be filtering out invalid plots before here
        for pnum, plot in enumerate(plots):
            if plot.style == 'auto':
                #FIXME: style for auto needs to be drawn from somewhere
                style = 'solid'
            else:
                style = plot.style
            if plot.color == 'auto':
                if style in {'heatmap', 'colors'}:
                    c = colors
                elif nplots > 7:
                    c = colors(int(pnum % 7) / 6.0, 1)
                elif nplots == 1:
                    c = colors(0, 1)
                else:
                    c = colors(int(pnum % nplots) / float(nplots - 1), 1)
            else:
                c = plot.color

            #FIXME: auto style could be "color strips"
            if style == 'heatmap':
                plot.plot(style=style, color=c, ax=self.plt)
                if self.legend:
                    self.cb = self.plt.figure.colorbar(self.plt.images[0])
            elif style == 'colors':
                plot.plot(style=style, color=c, ax=self.plt)
            else:
                plot.plot(style=style, color=c, ax=self.plt)

                # plot the peaks
                for pk in plot.peaks:
                    if pk.color == 'auto':
                        pc = c
                    else:
                        pc = pk.color

                    if pk.vis:
                        pk_pa = pk.plot(ax=self.plt, color=pc, alpha=alpha)
                        self.patches.append(pk_pa)

                #add a legend and make it pretty
                if self.legend:
                    leg = self.plt.legend(frameon=False)
                    clrs = [i.get_color() for i in leg.get_lines()]
                    for i, j in enumerate(clrs):
                        leg.get_texts()[i].set_color(j)
                    for i in leg.get_lines():
                        i.set_linestyle('')

        #        if 'scaled' in self._style:
        #            #TODO: fails at negative chromatograms
        #            trace -= min(trace)
        #            trace /= max(trace)
        #            trace *= 100
        #        if 'stacked' in self._style:
        #            trace += tnum * sc_factor
        #        # stretch out the color spectrum if there are under 7
        #        if trs > 7:
        #            c = self._color(int(tnum % 7) / 6.0, 1)
        #        elif trs == 1:
        #            c = self._color(0, 1)
        #        else:
        #            c = self._color(int(tnum % trs) / float(trs - 1), 1)
        #        ls = self._linestyle[int(np.floor((tnum % 28) / 7))]
        #        nm = dt.info['name'].strip('_') + ' ' + ts.ions[0]
        #        self.plt.plot(ts.times, trace, color=c, \
        #          ls=ls, lw=1.2, label=nm)
        #        tnum += 1

            ## for heatmap plots
            #if self.legend:
            #    self.cb = self.plt.figure.colorbar(img)

        #update the view bounds in the navbar's history
        if update_bounds:
            self.navbar._views.clear()
            self.navbar._positions.clear()
            self.navbar.push_current()
        else:
            self.plt.set_xlim(bnds[0])
            self.plt.set_ylim(bnds[1])
            #if type(self.highlight) == Polygon:
            #    self.plt.add_patch(self.highlight)
            #elif self.highlight is not None:
            #    self.plt.add_line(self.highlight)

        # plot events on the bottom of the graph
        #evts = []
        #if self.masterWindow.ui.actionGraphFxnCollection.isChecked():
        #    evts += datafiles[0].events('fxn')
        #if self.masterWindow.ui.actionGraphFIA.isChecked():
        #    evts += datafiles[0].events('fia')
        #if self.masterWindow.ui.actionGraphIRMS.isChecked():
        #    evts += datafiles[0].events('refgas')
        #if self.masterWindow.ui.actionGraph_Peaks_Found.isChecked():
        #    dt = self.masterWindow.obj_tab.active_file()
        #    tss = dt.active_plots(n=0)
        #    pevts = self.masterWindow.find_peaks(tss, dt)
        #    for i, p in enumerate(pevts[0]):
        #        p[2]['name'] = 'P' + str(i + 1)
        #    evts += pevts[0]

        #if evts != []:
        #    # TODO: save the text and lines to delete later?
        #    # TODO: make this prettier

        #    trans = self.plt.get_xaxis_transform()
        #    transText = offset_copy(trans, fig=self.plt.figure, \
        #                            x=3, units='points')
        #    for ev in evts:
        #        t0, t1, ta = ev[0], ev[1], (ev[1] + ev[0]) / 2.
        #        self.plt.vlines(t1, 0, 0.1, color='0.75', transform=trans)
        #        self.plt.vlines(t0, 0, 0.1, transform=trans)
        #        self.plt.text(ta, 0, ev[2]['name'], \
        #                      ha='center', transform=transText)

        # draw the y axis as log
        if self.masterWindow.ui.actionGraphLogYAxis.isChecked():
            self.plt.set_yscale('log')

        #draw grid lines
        if self.masterWindow.ui.actionGraphGrid.isChecked():
            self.plt.grid(c='black', ls='-', alpha=0.05)

        #update the canvas
        self.canvas.draw()

    def redraw(self):
        self.canvas.draw()

    def clear_highlight(self):
        #try to remove the line from the previous spectrum (if it exists)
        if self.highlight is not None:
            if self.highlight in self.plt.lines:
                self.plt.lines.remove(self.highlight)
            if self.highlight in self.plt.patches:
                self.plt.patches.remove(self.highlight)
            self.redraw()
        self.highlight = None

    def draw_highlight(self, x1, x2, color='black', linestyle='-'):
        """
        Draw the line that indicates where the spectrum came from.
        """
        self.clear_highlight()
        #draw a new line
        if x1 is None:
            self.highlight = None
        elif x1 == x2:
            self.highlight = self.plt.axvline(x1, color=color, ls=linestyle)
        else:
            self.highlight = self.plt.axvspan(x1, x2, alpha=0.25, color=color)
        #redraw the canvas
        self.canvas.draw()

    def draw_highlight_peak(self, pk, color='white'):
        coords = pk.as_poly().T
        self.highlight = self.plt.fill(coords[0], coords[1], \
                                       fc=color, alpha=0.5)[0]
        #redraw the canvas
        self.canvas.draw()

    def mousedown(self, event):
        if event.button == 3 and self.navbar.mode in ['peak', 'spectrum']:
            event.button = 1
            self.navbar.mode += '_pan'
            self.navbar.press_pan(event)

    def mouseup(self, event):
        if event.button == 3 and self.navbar.mode[-4:] == '_pan':
            event.button = 1
            self.navbar.release_pan(event)
            self.navbar.mode = self.navbar.mode[:-4]

    def mousescroll(self, event):
        if event.xdata is None or event.ydata is None:
            return
        xmin, xmax = self.plt.get_xlim()
        ymin, ymax = self.plt.get_ylim()
        if event.button == 'up':  # zoom in
            self.plt.set_xlim(event.xdata - (event.xdata - xmin) / 2.,
              event.xdata + (xmax - event.xdata) / 2.)
            self.plt.set_ylim(event.ydata - (event.ydata - ymin) / 2.,
              event.ydata + (ymax - event.ydata) / 2.)
        elif event.button == 'down':  # zoom out
            xmin = event.xdata - 2 * (event.xdata - xmin)
            xmax = event.xdata + 2 * (xmax - event.xdata)
            xmin = max(xmin, self.navbar._views.home()[0][0])
            xmax = min(xmax, self.navbar._views.home()[0][1])
            ymin = event.ydata - 2 * (event.ydata - ymin)
            ymax = event.ydata + 2 * (ymax - event.ydata)
            ymin = max(ymin, self.navbar._views.home()[0][2])
            ymax = min(ymax, self.navbar._views.home()[0][3])
            self.plt.axis([xmin, xmax, ymin, ymax])
        self.redraw()