Passed
Push — main ( 60119b...e5c7f7 )
by Douglas
02:02
created

_bound_ticks   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 74
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 39
dl 0
loc 74
rs 10
c 0
b 0
f 0
wmc 6

3 Methods

Rating   Name   Duplication   Size   Complexity  
A TickBounder.adjust() 0 5 1
A TickBounder._adjust() 0 9 4
A TickBounder.adjusted() 0 6 1
1
from dataclasses import dataclass
2
from typing import Union
3
4
from matplotlib.axes import Axes
5
from matplotlib.axis import Axis
6
7
8
@dataclass(frozen=True, repr=True, order=True)
9
class Coords:
10
    x0: float
11
    x1: float
12
    y0: float
13
    y1: float
14
15
16
@dataclass(frozen=True, repr=True, order=True)
17
class TickBounder:
18
    """
19
    Forces Axes limits to start and/or end at major or minor ticks.
20
21
    Each argument in the constructor can be:
22
    - ``True`` -- set the bound according to the ticks
23
    - ``False`` -- do not change the bound
24
    - a ``float`` - set to this
25
26
    Args:
27
        x0: left bound (``.getxlim()[0]``)
28
        y0: bottom bound (``.getylim()[0]``)
29
        x1: right bound (``.getxlim()[1]``)
30
        y1: top bound (``.getylim()[1]``)
31
        major: Use major tick marks rather than minor
32
33
    Example:
34
        This example will bound maximum width and height of the Axes
35
        to the smallest tick that fits the data,
36
        and will set the minimum width and height to 0::
37
38
            ticker = TickBounder(x=0, y0=0, x1=True, y1=True)
39
            ticker.adjust(ax)
40
    """
41
42
    x0: Union[bool, float] = True
43
    y0: Union[bool, float] = True
44
    x1: Union[bool, float] = True
45
    y1: Union[bool, float] = True
46
    major: bool = True
47
48
    def adjust(self, ax: Axes) -> Axes:
49
        coords = self.adjusted(ax)
50
        ax.set_xlim(coords.x0, coords.x1)
51
        ax.set_ylim(coords.y0, coords.y1)
52
        return ax
53
54
    def adjusted(self, ax: Axes) -> Coords:
55
        return Coords(
56
            x0=self._adjust(ax.xaxis, self.x0, ax.get_xlim()[0], 0),
57
            x1=self._adjust(ax.xaxis, self.x0, ax.get_xlim()[1], 1),
58
            y0=self._adjust(ax.yaxis, self.y0, ax.get_ylim()[0], 0),
59
            y1=self._adjust(ax.yaxis, self.y0, ax.get_ylim()[1], 1),
60
        )
61
62
    def _adjust(self, ax: Axis, to: Union[bool, float], default: float, side: int) -> float:
63
        if to is False:
64
            return default
65
        try:
66
            return float(to)
67
        except ValueError:
68
            pass
69
        vals = ax.get_majorticklocs() if self.major else ax.get_minorticklocs()
70
        return vals[side]
71
72
73
__all__ = ["TickBounder", "Coords"]
74