Exemple #1
0
    def partfunction(self, data):
        if data.first:
            data.first = 0
            min = data.min
            max = data.max
            if self.extendtick is not None and len(
                    self.ticklist) > self.extendtick:
                min, max = self.extendminmax(min, max,
                                             self.ticklist[self.extendtick],
                                             data.extendmin, data.extendmax)
            if self.extendlabel is not None and len(
                    self.labellist) > self.extendlabel:
                min, max = self.extendminmax(min, max,
                                             self.labellist[self.extendlabel],
                                             data.extendmin, data.extendmax)

            ticks = []
            for i in range(len(self.ticklist)):
                ticks = tick.mergeticklists(
                    ticks,
                    self.getticks(min, max, self.ticklist[i], ticklevel=i))
            for i in range(len(self.labellist)):
                ticks = tick.mergeticklists(
                    ticks,
                    self.getticks(min, max, self.labellist[i], labellevel=i))

            return ticks

        return None
Exemple #2
0
    def partfunction(self, data):
        if data.first:
            data.first = 0
            min = data.min
            max = data.max
            if self.extendtick is not None and len(self.ticklist) > self.extendtick:
                min, max = self.extendminmax(min, max, self.ticklist[self.extendtick], data.extendmin, data.extendmax)
            if self.extendlabel is not None and len(self.labellist) > self.extendlabel:
                min, max = self.extendminmax(min, max, self.labellist[self.extendlabel], data.extendmin, data.extendmax)

            ticks = []
            for i in range(len(self.ticklist)):
                ticks = tick.mergeticklists(ticks, self.getticks(min, max, self.ticklist[i], ticklevel=i))
            for i in range(len(self.labellist)):
                ticks = tick.mergeticklists(ticks, self.getticks(min, max, self.labellist[i], labellevel=i))

            return ticks

        return None
Exemple #3
0
 def getticks(self, min, max, preexp, ticklevel=None, labellevel=None):
     ticks = []
     minimin = 0
     maximax = 0
     for f in preexp.pres:
         thisticks = []
         imin = int(math.ceil(math.log(min / float(f)) /
                              math.log(preexp.exp) - 0.5 * self.epsilon))
         imax = int(math.floor(math.log(max / float(f)) /
                               math.log(preexp.exp) + 0.5 * self.epsilon))
         for i in range(imin, imax + 1):
             pos = f * tick.rational((preexp.exp, 1), power=i)
             thisticks.append(tick.tick((pos.num, pos.denom), ticklevel = ticklevel, labellevel = labellevel))
         ticks = tick.mergeticklists(ticks, thisticks)
     return ticks
Exemple #4
0
    def _create(self, data, positioner, graphtexrunner, parter, rater, errorname):
        errorname = " for axis %s" % errorname
        if data.min is None or data.max is None:
            raise RuntimeError("incomplete axis range%s" % errorname)
        if data.max == data.min:
            if self.fallbackrange is not None:
                try:
                    data.min, data.max = data.min - 0.5*self.fallbackrange, data.min + 0.5*self.fallbackrange
                except TypeError:
                    data.min, data.max = self.fallbackrange[0], self.fallbackrange[1]
            else:
                raise RuntimeError("zero axis range%s" % errorname)

        def layout(data):
            self.adjustaxis(data, data.ticks, graphtexrunner, errorname)
            self.texter.labels(data.ticks)
            if self.divisor:
                for t in data.ticks:
                    t *= tick.rational(self.divisor)
            canvas = painter.axiscanvas(self.painter, graphtexrunner)
            if self.painter is not None:
                self.painter.paint(canvas, data, self, positioner)
            return canvas

        if parter is None:
            data.ticks = self.manualticks
            return layout(data)

        # a variant is a data copy with local modifications to test several partitions
        class variant:
            def __init__(self, data, **kwargs):
                self.data = data
                for key, value in kwargs.items():
                    setattr(self, key, value)

            def __getattr__(self, key):
                return getattr(data, key)

            def __cmp__(self, other):
                # we can also sort variants by their rate
                return cmp(self.rate, other.rate)

        # build a list of variants
        bestrate = None
        if self.divisor is not None:
            if data.min is not None:
                data_min_divided = data.min/self.divisor
            else:
                data_min_divided = None
            if data.max is not None:
                data_max_divided = data.max/self.divisor
            else:
                data_max_divided = None
            partfunctions = parter.partfunctions(data_min_divided, data_max_divided,
                                                 self.min is None, self.max is None)
        else:
            partfunctions = parter.partfunctions(data.min, data.max,
                                                 self.min is None, self.max is None)
        variants = []
        for partfunction in partfunctions:
            worse = 0
            while worse < self.maxworse:
                worse += 1
                ticks = partfunction()
                if ticks is None:
                    break
                ticks = [t for t in tick.mergeticklists(self.manualticks, ticks, mergeequal=0)
                         if t.ticklevel is not None or t.labellevel is not None]
                if ticks:
                    rate = rater.rateticks(self, ticks, self.density)
                    if self.reverse:
                        rate += rater.raterange(self.convert(data, ticks[0]) -
                                                self.convert(data, ticks[-1]), 1)
                    else:
                        rate += rater.raterange(self.convert(data, ticks[-1]) -
                                                self.convert(data, ticks[0]), 1)
                    if bestrate is None or rate < bestrate:
                        bestrate = rate
                        worse = 0
                    variants.append(variant(data, rate=rate, ticks=ticks))

        if not variants:
            raise RuntimeError("no axis partitioning found%s" % errorname)

        if len(variants) == 1 or self.painter is None:
            # When the painter is None, we could sort the variants here by their rating.
            # However, we didn't did this so far and there is no real reason to change that.
            data.ticks = variants[0].ticks
            return layout(data)

        # build the layout for best variants
        for variant in variants:
            variant.storedcanvas = None
        variants.sort()
        while not variants[0].storedcanvas:
            variants[0].storedcanvas = layout(variants[0])
            ratelayout = rater.ratelayout(variants[0].storedcanvas, self.density)
            if ratelayout is None:
                del variants[0]
                if not variants:
                    raise NoValidPartitionError("no valid axis partitioning found%s" % errorname)
            else:
                variants[0].rate += ratelayout
            variants.sort()
        self.adjustaxis(data, variants[0].ticks, graphtexrunner, errorname)
        data.ticks = variants[0].ticks
        return variants[0].storedcanvas
Exemple #5
0
    def _create(self, data, positioner, graphtextengine, parter, rater,
                errorname):
        errorname = " for axis %s" % errorname
        if data.min is None or data.max is None:
            raise RuntimeError("incomplete axis range%s" % errorname)
        if data.max == data.min:
            if self.fallbackrange is not None:
                try:
                    data.min, data.max = data.min - 0.5 * self.fallbackrange, data.min + 0.5 * self.fallbackrange
                except TypeError:
                    data.min, data.max = self.fallbackrange[
                        0], self.fallbackrange[1]
            else:
                raise RuntimeError("zero axis range%s" % errorname)

        if self.divisor is not None:
            rational_divisor = tick.rational(self.divisor)
            convert_tick = lambda x: float(x) * self.divisor
        else:
            convert_tick = lambda x: x

        def layout(data):
            if data.ticks:
                self.adjustaxis(data, [
                    convert_tick(data.ticks[0]),
                    convert_tick(data.ticks[-1])
                ], graphtextengine, errorname)
            self.texter.labels(data.ticks)
            if self.divisor:
                for t in data.ticks:
                    t *= rational_divisor
            canvas = painter.axiscanvas(self.painter, graphtextengine)
            if self.painter is not None:
                self.painter.paint(canvas, data, self, positioner)
            return canvas

        if parter is None:
            data.ticks = self.manualticks
            return layout(data)

        # a variant is a data copy with local modifications to test several partitions
        @functools.total_ordering
        class variant:
            def __init__(self, data, **kwargs):
                self.data = data
                for key, value in list(kwargs.items()):
                    setattr(self, key, value)

            def __getattr__(self, key):
                return getattr(data, key)

            def __lt__(self, other):
                # we can also sort variants by their rate
                return self.rate < other.rate

            def __eq__(self, other):
                # we can also sort variants by their rate
                return self.rate == other.rate

        # build a list of variants
        bestrate = None
        if self.divisor is not None:
            if data.min is not None:
                data_min_divided = data.min / self.divisor
            else:
                data_min_divided = None
            if data.max is not None:
                data_max_divided = data.max / self.divisor
            else:
                data_max_divided = None
            partfunctions = parter.partfunctions(data_min_divided,
                                                 data_max_divided,
                                                 self.min is None,
                                                 self.max is None)
        else:
            partfunctions = parter.partfunctions(data.min, data.max,
                                                 self.min is None,
                                                 self.max is None)
        variants = []
        for partfunction in partfunctions:
            worse = 0
            while worse < self.maxworse:
                worse += 1
                ticks = partfunction()
                if ticks is None:
                    break
                ticks = tick.mergeticklists(self.manualticks,
                                            ticks,
                                            mergeequal=0)
                if ticks:
                    rate = rater.rateticks(self, ticks, self.density)
                    if rate is not None:
                        if self.reverse:
                            rate += rater.raterange(
                                self.convert(data, convert_tick(ticks[0])) -
                                self.convert(data, convert_tick(ticks[-1])), 1)
                        else:
                            rate += rater.raterange(
                                self.convert(data, convert_tick(ticks[-1])) -
                                self.convert(data, convert_tick(ticks[0])), 1)
                        if bestrate is None or rate < bestrate:
                            bestrate = rate
                            worse = 0
                        variants.append(variant(data, rate=rate, ticks=ticks))

        if not variants:
            raise RuntimeError("no axis partitioning found%s" % errorname)

        if len(variants) == 1 or self.painter is None:
            # When the painter is None, we could sort the variants here by their rating.
            # However, we didn't did this so far and there is no real reason to change that.
            data.ticks = variants[0].ticks
            return layout(data)

        # build the layout for best variants
        for variant in variants:
            variant.storedcanvas = None
        variants.sort()
        while not variants[0].storedcanvas:
            variants[0].storedcanvas = layout(variants[0])
            ratelayout = rater.ratelayout(variants[0].storedcanvas,
                                          self.density)
            if ratelayout is None:
                del variants[0]
                if not variants:
                    raise NoValidPartitionError(
                        "no valid axis partitioning found%s" % errorname)
            else:
                variants[0].rate += ratelayout
            variants.sort()
        self.adjustaxis(data, variants[0].ticks, graphtextengine, errorname)
        data.ticks = variants[0].ticks
        return variants[0].storedcanvas
Exemple #6
0
    def _create(self, data, positioner, graphtexrunner, parter, rater,
                errorname):
        errorname = " for axis %s" % errorname
        if data.min is None or data.max is None:
            raise RuntimeError("incomplete axis range%s" % errorname)

        def layout(data):
            self.adjustaxis(data, data.ticks, graphtexrunner, errorname)
            self.texter.labels(data.ticks)
            if self.divisor:
                for t in data.ticks:
                    t *= tick.rational(self.divisor)
            canvas = painter.axiscanvas(self.painter, graphtexrunner)
            if self.painter is not None:
                self.painter.paint(canvas, data, self, positioner)
            return canvas

        if parter is None:
            data.ticks = self.manualticks
            return layout(data)

        # a variant is a data copy with local modifications to test several partitions
        class variant:
            def __init__(self, data, **kwargs):
                self.data = data
                for key, value in kwargs.items():
                    setattr(self, key, value)

            def __getattr__(self, key):
                return getattr(data, key)

            def __cmp__(self, other):
                # we can also sort variants by their rate
                return cmp(self.rate, other.rate)

        # build a list of variants
        bestrate = None
        if self.divisor is not None:
            partfunctions = parter.partfunctions(data.min / self.divisor,
                                                 data.max / self.divisor,
                                                 self.min is None,
                                                 self.max is None)
        else:
            partfunctions = parter.partfunctions(data.min, data.max,
                                                 self.min is None,
                                                 self.max is None)
        variants = []
        for partfunction in partfunctions:
            worse = 0
            while worse < self.maxworse:
                worse += 1
                ticks = partfunction()
                if ticks is None:
                    break
                ticks = tick.mergeticklists(self.manualticks,
                                            ticks,
                                            mergeequal=0)
                if ticks:
                    rate = rater.rateticks(self, ticks, self.density)
                    if self.reverse:
                        rate += rater.raterange(
                            self.convert(data, ticks[0]) -
                            self.convert(data, ticks[-1]), 1)
                    else:
                        rate += rater.raterange(
                            self.convert(data, ticks[-1]) -
                            self.convert(data, ticks[0]), 1)
                    if bestrate is None or rate < bestrate:
                        bestrate = rate
                        worse = 0
                    variants.append(variant(data, rate=rate, ticks=ticks))

        if not variants:
            raise RuntimeError("no axis partitioning found%s" % errorname)

        if len(variants) == 1 or self.painter is None:
            # When the painter is None, we could sort the variants here by their rating.
            # However, we didn't did this so far and there is no real reason to change that.
            data.ticks = variants[0].ticks
            return layout(data)

        # build the layout for best variants
        for variant in variants:
            variant.storedcanvas = None
        variants.sort()
        while not variants[0].storedcanvas:
            variants[0].storedcanvas = layout(variants[0])
            ratelayout = rater.ratelayout(variants[0].storedcanvas,
                                          self.density)
            if ratelayout is None:
                del variants[0]
                if not variants:
                    raise NoValidPartitionError(
                        "no valid axis partitioning found%s" % errorname)
            else:
                variants[0].rate += ratelayout
            variants.sort()
        self.adjustaxis(data, variants[0].ticks, graphtexrunner, errorname)
        data.ticks = variants[0].ticks
        return variants[0].storedcanvas