File: linear.py

package info (click to toggle)
python-leather 0.4.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 652 kB
  • sloc: python: 2,385; makefile: 117; sh: 5
file content (59 lines) | stat: -rw-r--r-- 1,849 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
from decimal import Decimal

from leather.scales.base import Scale
from leather.ticks.score import ScoreTicker


class Linear(Scale):
    """
    A scale that linearly maps values from a domain to a range.

    :param domain_min:
        The minimum value of the input domain.
    :param domain_max:
        The maximum value of the input domain.
    """
    def __init__(self, domain_min, domain_max):
        if domain_min > domain_max:
            raise ValueError('Inverted domains are not currently supported.')
        elif domain_min == domain_max:
            # Default to unit scale
            self._data_min = Decimal(0)
            self._data_max = Decimal(1)
        else:
            self._data_min = Decimal(domain_min)
            self._data_max = Decimal(domain_max)

        self._ticker = ScoreTicker(self._data_min, self._data_max)

    def contains(self, v):
        """
        Return :code:`True` if a given value is contained within this scale's
        domain.
        """
        return self._data_min <= v <= self._data_max

    def project(self, value, range_min, range_max):
        """
        Project a value in this scale's domain to a target range.
        """
        value = Decimal(value)
        range_min = Decimal(range_min)
        range_max = Decimal(range_max)

        pos = (value - self._ticker.min) / (self._ticker.max - self._ticker.min)

        return ((range_max - range_min) * pos) + range_min

    def project_interval(self, value, range_min, range_max):
        """
        Project a value in this scale's domain to an interval in the target
        range. This is used for places :class:`.Bars` and :class:`.Columns`.
        """
        raise NotImplementedError

    def ticks(self):
        """
        Generate a series of ticks for this scale.
        """
        return self._ticker.ticks