Exemplo n.º 1
0
Arquivo: bar.py Projeto: JoonyLi/veusz
    def draw(self, parentposn, phelper, outerbounds=None):
        """Plot the data on a plotter."""

        widgetposn = GenericPlotter.draw(self, parentposn, phelper,
                                         outerbounds=outerbounds)
        s = self.settings

        # exit if hidden
        if s.hide:
            return

        # get data
        doc = self.document
        positions = s.get('posn').getData(doc)
        lengths = s.get('lengths').getData(doc)
        if not lengths:
            return

        # get axes widgets
        axes = self.parent.getAxes( (s.xAxis, s.yAxis) )

        # return if there are no proper axes
        if ( None in axes or
             axes[0].settings.direction != 'horizontal' or
             axes[1].settings.direction != 'vertical' ):
            return

        # where the bars are to be placed horizontally
        barposns, maxwidth = self.findBarPositions(lengths, positions,
                                                   axes, widgetposn)
        
        # only use finite positions
        origposnlen = len(barposns)
        validposn = N.isfinite(barposns)
        barposns = barposns[validposn]

        # this is a bit rubbish - we take the datasets and
        # make sure they have the same lengths as posns and remove NaNs
        # Datasets are stored as dicts
        dsvals = []
        for dataset in lengths:
            vals = {}
            for key in ('data', 'serr', 'nerr', 'perr'):
                v = getattr(dataset, key)
                if v is not None:
                    vals[key] = extend1DArray(N.nan_to_num(v),
                                              origposnlen)[validposn]
            dsvals.append(vals)

        # clip data within bounds of plotter
        clip = self.clipAxesBounds(axes, widgetposn)
        painter = phelper.painter(self, widgetposn, clip=clip)

        # actually do the drawing
        fn = {'stacked': self.barDrawStacked,
              'stacked-area': self.areaDrawStacked,
              'grouped': self.barDrawGroup}[s.mode]
        fn(painter, barposns, maxwidth, dsvals, axes, widgetposn, clip)
Exemplo n.º 2
0
    def draw(self, parentposn, painthelper, outerbounds = None):
        """Draw the function."""

        posn = GenericPlotter.draw(self, parentposn, painthelper,
                                   outerbounds = outerbounds)
        x1, y1, x2, y2 = posn
        s = self.settings

        # exit if hidden or function blank
        if s.hide or s.function.strip() == '':
            return

        # get axes widgets
        axes = self.parent.getAxes( (s.xAxis, s.yAxis) )

        # return if there's no proper axes
        if ( None in axes or
             axes[0].settings.direction != 'horizontal' or
             axes[1].settings.direction != 'vertical' ):
            return

        # clip data within bounds of plotter
        cliprect = self.clipAxesBounds(axes, posn)
        painter = painthelper.painter(self, posn, clip=cliprect)

        # get the points to plot by evaluating the function
        (xpts, ypts), (pxpts, pypts) = self.calcFunctionPoints(axes, posn)

        # draw the function line
        if pxpts is None or pypts is None:
            # not sure how to deal with errors here
            painter.setPen( setting.settingdb.color('error') )
            f = qt4.QFont()
            f.setPointSize(20)
            painter.setFont(f)
            painter.drawText( qt4.QRectF(x1, y1, x2-x1, y2-y1),
                              qt4.Qt.AlignCenter,
                              "Cannot evaluate '%s'" % s.function )
        else:
            if not s.FillBelow.hide:
                painter.setBrush( s.FillBelow.makeQBrush() )
                painter.setPen( qt4.QPen(qt4.Qt.NoPen) )
                self._fillRegion(painter, pxpts, pypts, posn, True, cliprect)

            if not s.FillAbove.hide:
                painter.setBrush( s.FillAbove.makeQBrush() )
                painter.setPen( qt4.QPen(qt4.Qt.NoPen) )
                self._fillRegion(painter, pxpts, pypts, posn, False, cliprect)

            if not s.Line.hide:
                painter.setBrush( qt4.QBrush() )
                painter.setPen( s.Line.makeQPen(painter) )
                self._plotLine(painter, pxpts, pypts, posn, cliprect)
Exemplo n.º 3
0
    def draw(self, parentposn, painthelper, outerbounds=None):
        """Draw the function."""

        posn = GenericPlotter.draw(self,
                                   parentposn,
                                   painthelper,
                                   outerbounds=outerbounds)
        x1, y1, x2, y2 = posn
        s = self.settings

        # exit if hidden or function blank
        if s.hide or s.function.strip() == '':
            return

        # get axes widgets
        axes = self.parent.getAxes((s.xAxis, s.yAxis))

        # return if there's no proper axes
        if (None in axes or axes[0].settings.direction != 'horizontal'
                or axes[1].settings.direction != 'vertical'):
            return

        # clip data within bounds of plotter
        cliprect = self.clipAxesBounds(axes, posn)
        painter = painthelper.painter(self, posn, clip=cliprect)

        # get the points to plot by evaluating the function
        (xpts, ypts), (pxpts, pypts) = self.calcFunctionPoints(axes, posn)

        # draw the function line
        if pxpts is None or pypts is None:
            # not sure how to deal with errors here
            painter.setPen(setting.settingdb.color('error'))
            f = qt4.QFont()
            f.setPointSize(20)
            painter.setFont(f)
            painter.drawText(qt4.QRectF(x1, y1, x2 - x1,
                                        y2 - y1), qt4.Qt.AlignCenter,
                             "Cannot evaluate '%s'" % s.function)
        else:
            if not s.FillBelow.hide:
                self._fillRegion(painter, pxpts, pypts, posn, True, cliprect,
                                 s.FillBelow)

            if not s.FillAbove.hide:
                self._fillRegion(painter, pxpts, pypts, posn, False, cliprect,
                                 s.FillAbove)

            if not s.Line.hide:
                painter.setBrush(qt4.QBrush())
                painter.setPen(s.Line.makeQPen(painter))
                self._plotLine(painter, pxpts, pypts, posn, cliprect)
Exemplo n.º 4
0
    def draw(self, parentposn, phelper, outerbounds=None):
        """Plot the data on a plotter."""

        widgetposn = GenericPlotter.draw(self, parentposn, phelper,
                                         outerbounds=outerbounds)
        s = self.settings

        # exit if hidden
        if s.hide:
            return

        # get data
        doc = self.document
        positions = self.getPosns()
        if s.calculate:
            # calculate from data
            values = s.get('values').getData(doc)
            if values is None:
                return
        else:
            # use manual datasets
            datasets = [ s.get(x).getData(doc) for x in
                         ('whiskermin', 'whiskermax', 'boxmin',
                          'boxmax', 'mean', 'median') ]
            if None in datasets:
                return

        # get axes widgets
        axes = self.parent.getAxes( (s.xAxis, s.yAxis) )

        # return if there are no proper axes
        if ( None in axes or
             axes[0].settings.direction != 'horizontal' or
             axes[1].settings.direction != 'vertical' ):
            return

        clip = self.clipAxesBounds(axes, widgetposn)
        painter = phelper.painter(self, widgetposn, clip=clip)

        # get boxes visible along direction of boxes to work out width
        horz = (s.direction == 'horizontal')
        plotposns = axes[horz].dataToPlotterCoords(widgetposn, positions)

        if horz:
            inplot = (plotposns > widgetposn[1]) & (plotposns < widgetposn[3])
        else:
            inplot = (plotposns > widgetposn[0]) & (plotposns < widgetposn[2])
        inplotposn = plotposns[inplot]
        if inplotposn.shape[0] < 2:
            if horz:
                width = (widgetposn[3]-widgetposn[1])*0.5
            else:
                width = (widgetposn[2]-widgetposn[0])*0.5
        else:
            # use minimum different between points to get width
            inplotposn.sort()
            width = N.nanmin(inplotposn[1:] - inplotposn[:-1])

        # adjust width
        width = width * s.fillfraction

        if s.calculate:
            # calculated boxes
            for vals, plotpos in izip(values, plotposns):
                stats = _Stats()
                stats.calculate(vals.data, s.whiskermode)
                self.plotBox(painter, axes, plotpos, widgetposn, width,
                             clip, stats)
        else:
            # manually given boxes
            vals = [d.data for d in datasets] + [plotposns]
            lens = [len(d) for d in vals]
            for i in xrange(min(lens)):
                stats = _Stats()
                stats.topwhisker = vals[0][i]
                stats.botwhisker = vals[1][i]
                stats.botquart = vals[2][i]
                stats.topquart = vals[3][i]
                stats.mean = vals[4][i]
                stats.median = vals[5][i]
                stats.outliers = N.array([])
                self.plotBox(painter, axes, vals[6][i], widgetposn,
                             width, clip, stats)
Exemplo n.º 5
0
    def draw(self, parentposn, phelper, outerbounds=None):
        """Plot the data on a plotter."""

        posn = GenericPlotter.draw(self, parentposn, phelper, outerbounds=outerbounds)
        x1, y1, x2, y2 = posn

        s = self.settings

        # exit if hidden
        if s.hide:
            return

        # get data
        doc = self.document
        xv = s.get("xData").getData(doc)
        yv = s.get("yData").getData(doc)
        text = s.get("labels").getData(doc, checknull=True)
        scalepoints = s.get("scalePoints").getData(doc)

        if not xv or not yv:
            return

        # if text entered, then multiply up to get same number of values
        # as datapoints
        if text:
            length = min(len(xv.data), len(yv.data))
            text = text * (length / len(text)) + text[: length % len(text)]

        # get axes widgets
        axes = self._fetchAxes()
        if not axes:
            return

        # clip data within bounds of plotter
        cliprect = self.clipAxesBounds(axes, posn)
        painter = phelper.painter(self, posn, clip=cliprect)

        # loop over chopped up values
        for xvals, yvals, tvals, ptvals in document.generateValidDatasetParts(xv, yv, text, scalepoints):

            # print "Calculating coordinates"
            # calc plotter coords of x and y points
            xplotter = axes[0].dataToPlotterCoords(posn, xvals.data)
            yplotter = axes[1].dataToPlotterCoords(posn, yvals.data)

            # print "Painting error bars"
            # plot errors bars
            self._plotErrors(posn, painter, xplotter, yplotter, axes, xvals, yvals, cliprect)

            # print "Painting plot line"
            # plot data line (and/or filling above or below)
            if not s.PlotLine.hide or not s.FillAbove.hide or not s.FillBelow.hide:
                if s.PlotLine.bezierJoin and hasqtloops:
                    self._drawBezierLine(painter, xplotter, yplotter, posn, xvals, yvals)
                else:
                    self._drawPlotLine(painter, xplotter, yplotter, posn, xvals, yvals, cliprect)

            # plot the points (we do this last so they are on top)
            markersize = s.get("markerSize").convert(painter)
            if not s.MarkerLine.hide or not s.MarkerFill.hide:

                # print "Painting marker fill"
                if not s.MarkerFill.hide:
                    # filling for markers
                    painter.setBrush(s.MarkerFill.makeQBrush())
                else:
                    # no-filling brush
                    painter.setBrush(qt4.QBrush())

                # print "Painting marker lines"
                if not s.MarkerLine.hide:
                    # edges of markers
                    painter.setPen(s.MarkerLine.makeQPen(painter))
                else:
                    # invisible pen
                    painter.setPen(qt4.QPen(qt4.Qt.NoPen))

                # thin datapoints as required
                if s.thinfactor <= 1:
                    xplt, yplt = xplotter, yplotter
                else:
                    xplt, yplt = (xplotter[:: s.thinfactor], yplotter[:: s.thinfactor])

                # whether to scale markers
                scaling = None
                if ptvals:
                    scaling = ptvals.data

                # actually plot datapoints
                utils.plotMarkers(painter, xplt, yplt, s.marker, markersize, scaling=scaling, clip=cliprect)

            # finally plot any labels
            if tvals and not s.Label.hide:
                self.drawLabels(painter, xplotter, yplotter, tvals, markersize)
Exemplo n.º 6
0
    def draw(self, parentposn, phelper, outerbounds=None):
        """Plot the data on a plotter."""

        posn = GenericPlotter.draw(self,
                                   parentposn,
                                   phelper,
                                   outerbounds=outerbounds)
        x1, y1, x2, y2 = posn

        s = self.settings

        # exit if hidden
        if s.hide:
            return

        # get data
        doc = self.document
        xv = s.get('xData').getData(doc)
        yv = s.get('yData').getData(doc)
        text = s.get('labels').getData(doc, checknull=True)
        scalepoints = s.get('scalePoints').getData(doc)
        colorpoints = s.Color.get('points').getData(doc)

        # if a missing dataset, make a fake dataset for the second one
        # based on a row number
        if xv and not yv and s.get('yData').isEmpty():
            # use index for y data
            length = xv.data.shape[0]
            yv = document.DatasetRange(length, (1, length))
        elif yv and not xv and s.get('xData').isEmpty():
            # use index for x data
            length = yv.data.shape[0]
            xv = document.DatasetRange(length, (1, length))
        if not xv or not yv:
            # no valid dataset, so exit
            return

        # if text entered, then multiply up to get same number of values
        # as datapoints
        if text:
            length = min(len(xv.data), len(yv.data))
            text = text * (length / len(text)) + text[:length % len(text)]

        # get axes widgets
        axes = self._fetchAxes()
        if not axes:
            # no valid axes, so exit
            return

        # clip data within bounds of plotter
        cliprect = self.clipAxesBounds(axes, posn)
        painter = phelper.painter(self, posn, clip=cliprect)

        # loop over chopped up values
        for xvals, yvals, tvals, ptvals, cvals in (
                document.generateValidDatasetParts(xv, yv, text, scalepoints,
                                                   colorpoints)):

            #print "Calculating coordinates"
            # calc plotter coords of x and y points
            xplotter = axes[0].dataToPlotterCoords(posn, xvals.data)
            yplotter = axes[1].dataToPlotterCoords(posn, yvals.data)

            #print "Painting plot line"
            # plot data line (and/or filling above or below)
            if not s.PlotLine.hide or not s.FillAbove.hide or not s.FillBelow.hide:
                if s.PlotLine.bezierJoin and hasqtloops:
                    self._drawBezierLine(painter, xplotter, yplotter, posn,
                                         xvals, yvals)
                else:
                    self._drawPlotLine(painter, xplotter, yplotter, posn,
                                       xvals, yvals, cliprect)

            # shift points if in certain step modes
            if s.PlotLine.steps != 'off':
                steps = s.PlotLine.steps
                if s.PlotLine.steps == 'right-shift-points':
                    xplotter[1:] = 0.5 * (xplotter[:-1] + xplotter[1:])
                elif s.PlotLine.steps == 'left-shift-points':
                    xplotter[:-1] = 0.5 * (xplotter[:-1] + xplotter[1:])

            #print "Painting error bars"
            # plot errors bars
            self._plotErrors(posn, painter, xplotter, yplotter, axes, xvals,
                             yvals, cliprect)

            # plot the points (we do this last so they are on top)
            markersize = s.get('markerSize').convert(painter)
            if not s.MarkerLine.hide or not s.MarkerFill.hide:

                #print "Painting marker fill"
                if not s.MarkerFill.hide:
                    # filling for markers
                    painter.setBrush(s.MarkerFill.makeQBrush())
                else:
                    # no-filling brush
                    painter.setBrush(qt4.QBrush())

                #print "Painting marker lines"
                if not s.MarkerLine.hide:
                    # edges of markers
                    painter.setPen(s.MarkerLine.makeQPen(painter))
                else:
                    # invisible pen
                    painter.setPen(qt4.QPen(qt4.Qt.NoPen))

                # thin datapoints as required
                if s.thinfactor <= 1:
                    xplt, yplt = xplotter, yplotter
                else:
                    xplt, yplt = (xplotter[::s.thinfactor],
                                  yplotter[::s.thinfactor])

                # whether to scale markers
                scaling = colorvals = cmap = None
                if ptvals:
                    scaling = ptvals.data
                    if s.thinfactor > 1:
                        scaling = scaling[::s.thinfactor]

                # color point individually
                if cvals:
                    colorvals = utils.applyScaling(cvals.data, s.Color.scaling,
                                                   s.Color.min, s.Color.max)
                    if s.thinfactor > 1:
                        colorvals = colorvals[::s.thinfactor]
                    cmap = self.document.getColormap(
                        s.MarkerFill.colorMap, s.MarkerFill.colorMapInvert)

                # actually plot datapoints
                utils.plotMarkers(painter,
                                  xplt,
                                  yplt,
                                  s.marker,
                                  markersize,
                                  scaling=scaling,
                                  clip=cliprect,
                                  cmap=cmap,
                                  colorvals=colorvals)

            # finally plot any labels
            if tvals and not s.Label.hide:
                self.drawLabels(painter, xplotter, yplotter, tvals, markersize)
Exemplo n.º 7
0
    def draw(self, parentposn, phelper, outerbounds=None):
        """Plot the data on a plotter."""

        posn = GenericPlotter.draw(self, parentposn, phelper,
                                   outerbounds=outerbounds)
        x1, y1, x2, y2 = posn

        s = self.settings

        # exit if hidden
        if s.hide:
            return

        # get data
        doc = self.document
        xv = s.get('xData').getData(doc)
        yv = s.get('yData').getData(doc)
        text = s.get('labels').getData(doc, checknull=True)
        scalepoints = s.get('scalePoints').getData(doc)
        colorpoints = s.Color.get('points').getData(doc)

        # if a missing dataset, make a fake dataset for the second one
        # based on a row number
        if xv and not yv and s.get('yData').isEmpty():
            # use index for y data
            length = xv.data.shape[0]
            yv = document.DatasetRange(length, (1,length))
        elif yv and not xv and s.get('xData').isEmpty():
            # use index for x data
            length = yv.data.shape[0]
            xv = document.DatasetRange(length, (1,length))
        if not xv or not yv:
            # no valid dataset, so exit
            return

        # if text entered, then multiply up to get same number of values
        # as datapoints
        if text:
            length = min( len(xv.data), len(yv.data) )
            text = text*(length / len(text)) + text[:length % len(text)]

        # get axes widgets
        axes = self._fetchAxes()
        if not axes:
            # no valid axes, so exit
            return

        # clip data within bounds of plotter
        cliprect = self.clipAxesBounds(axes, posn)
        painter = phelper.painter(self, posn, clip=cliprect)

        # loop over chopped up values
        for xvals, yvals, tvals, ptvals, cvals in (
            document.generateValidDatasetParts(
                xv, yv, text, scalepoints, colorpoints)):

            #print "Calculating coordinates"
            # calc plotter coords of x and y points
            xplotter = axes[0].dataToPlotterCoords(posn, xvals.data)
            yplotter = axes[1].dataToPlotterCoords(posn, yvals.data)

            #print "Painting error bars"
            # plot errors bars
            self._plotErrors(posn, painter, xplotter, yplotter,
                             axes, xvals, yvals, cliprect)

            #print "Painting plot line"
            # plot data line (and/or filling above or below)
            if not s.PlotLine.hide or not s.FillAbove.hide or not s.FillBelow.hide:
                if s.PlotLine.bezierJoin and hasqtloops:
                    self._drawBezierLine( painter, xplotter, yplotter, posn,
                                          xvals, yvals )
                else:
                    self._drawPlotLine( painter, xplotter, yplotter, posn,
                                        xvals, yvals, cliprect )

            # plot the points (we do this last so they are on top)
            markersize = s.get('markerSize').convert(painter)
            if not s.MarkerLine.hide or not s.MarkerFill.hide:

                #print "Painting marker fill"
                if not s.MarkerFill.hide:
                    # filling for markers
                    painter.setBrush( s.MarkerFill.makeQBrush() )
                else:
                    # no-filling brush
                    painter.setBrush( qt4.QBrush() )

                #print "Painting marker lines"
                if not s.MarkerLine.hide:
                    # edges of markers
                    painter.setPen( s.MarkerLine.makeQPen(painter) )
                else:
                    # invisible pen
                    painter.setPen( qt4.QPen(qt4.Qt.NoPen) )

                # thin datapoints as required
                if s.thinfactor <= 1:
                    xplt, yplt = xplotter, yplotter
                else:
                    xplt, yplt = (xplotter[::s.thinfactor],
                                  yplotter[::s.thinfactor])

                # whether to scale markers
                scaling = colorvals = cmap = None
                if ptvals:
                    scaling = ptvals.data
                # color point individually
                if cvals:
                    colorvals = utils.applyScaling(
                        cvals.data, s.Color.scaling,
                        s.Color.min, s.Color.max)
                    cmap = self.document.getColormap(
                        s.MarkerFill.colorMap, s.MarkerFill.colorMapInvert)

                # actually plot datapoints
                utils.plotMarkers(painter, xplt, yplt, s.marker, markersize,
                                  scaling=scaling, clip=cliprect,
                                  cmap=cmap, colorvals=colorvals)

            # finally plot any labels
            if tvals and not s.Label.hide:
                self.drawLabels(painter, xplotter, yplotter,
                                tvals, markersize)
Exemplo n.º 8
0
    def draw(self, parentposn, phelper, outerbounds=None):
        """Plot the data on a plotter."""

        widgetposn = GenericPlotter.draw(self,
                                         parentposn,
                                         phelper,
                                         outerbounds=outerbounds)
        s = self.settings

        # exit if hidden
        if s.hide:
            return

        # get data
        doc = self.document
        positions = s.get('posn').getData(doc)
        lengths = s.get('lengths').getData(doc)
        if not lengths:
            return

        # get axes widgets
        axes = self.parent.getAxes((s.xAxis, s.yAxis))

        # return if there are no proper axes
        if (None in axes or axes[0].settings.direction != 'horizontal'
                or axes[1].settings.direction != 'vertical'):
            return

        # where the bars are to be placed horizontally
        barposns, maxwidth = self.findBarPositions(lengths, positions, axes,
                                                   widgetposn)

        # only use finite positions
        origposnlen = len(barposns)
        validposn = N.isfinite(barposns)
        barposns = barposns[validposn]

        # this is a bit rubbish - we take the datasets and
        # make sure they have the same lengths as posns and remove NaNs
        # Datasets are stored as dicts
        dsvals = []
        for dataset in lengths:
            vals = {}
            for key in ('data', 'serr', 'nerr', 'perr'):
                v = getattr(dataset, key)
                if v is not None:
                    vals[key] = extend1DArray(N.nan_to_num(v),
                                              origposnlen)[validposn]
            dsvals.append(vals)

        # clip data within bounds of plotter
        clip = self.clipAxesBounds(axes, widgetposn)
        painter = phelper.painter(self, widgetposn, clip=clip)

        # actually do the drawing
        fn = {
            'stacked': self.barDrawStacked,
            'stacked-area': self.areaDrawStacked,
            'grouped': self.barDrawGroup
        }[s.mode]
        fn(painter, barposns, maxwidth, dsvals, axes, widgetposn, clip)
Exemplo n.º 9
0
    def draw(self, parentposn, phelper, outerbounds=None):
        """Plot the data on a plotter."""

        widgetposn = GenericPlotter.draw(self,
                                         parentposn,
                                         phelper,
                                         outerbounds=outerbounds)
        s = self.settings

        # exit if hidden
        if s.hide:
            return

        # get data
        doc = self.document
        positions = self.getPosns()
        if s.calculate:
            # calculate from data
            values = s.get('values').getData(doc)
            if values is None:
                return
        else:
            # use manual datasets
            datasets = [
                s.get(x).getData(doc)
                for x in ('whiskermin', 'whiskermax', 'boxmin', 'boxmax',
                          'mean', 'median')
            ]
            if None in datasets:
                return

        # get axes widgets
        axes = self.parent.getAxes((s.xAxis, s.yAxis))

        # return if there are no proper axes
        if (None in axes or axes[0].settings.direction != 'horizontal'
                or axes[1].settings.direction != 'vertical'):
            return

        clip = self.clipAxesBounds(axes, widgetposn)
        painter = phelper.painter(self, widgetposn, clip=clip)

        # get boxes visible along direction of boxes to work out width
        horz = (s.direction == 'horizontal')
        plotposns = axes[horz].dataToPlotterCoords(widgetposn, positions)

        if horz:
            inplot = (plotposns > widgetposn[1]) & (plotposns < widgetposn[3])
        else:
            inplot = (plotposns > widgetposn[0]) & (plotposns < widgetposn[2])
        inplotposn = plotposns[inplot]
        if inplotposn.shape[0] < 2:
            if horz:
                width = (widgetposn[3] - widgetposn[1]) * 0.5
            else:
                width = (widgetposn[2] - widgetposn[0]) * 0.5
        else:
            # use minimum different between points to get width
            inplotposn.sort()
            width = N.nanmin(inplotposn[1:] - inplotposn[:-1])

        # adjust width
        width = width * s.fillfraction

        if s.calculate:
            # calculated boxes
            for vals, plotpos in izip(values, plotposns):
                stats = _Stats()
                stats.calculate(vals.data, s.whiskermode)
                self.plotBox(painter, axes, plotpos, widgetposn, width, clip,
                             stats)
        else:
            # manually given boxes
            vals = [d.data for d in datasets] + [plotposns]
            lens = [len(d) for d in vals]
            for i in xrange(min(lens)):
                stats = _Stats()
                stats.topwhisker = vals[0][i]
                stats.botwhisker = vals[1][i]
                stats.botquart = vals[2][i]
                stats.topquart = vals[3][i]
                stats.mean = vals[4][i]
                stats.median = vals[5][i]
                stats.outliers = N.array([])
                self.plotBox(painter, axes, vals[6][i], widgetposn, width,
                             clip, stats)