matplotlib-map-utils 1.0.2__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- matplotlib_map_utils/__init__.py +5 -1
- matplotlib_map_utils/core/__init__.py +4 -0
- matplotlib_map_utils/{north_arrow.py → core/north_arrow.py} +56 -55
- matplotlib_map_utils/core/scale_bar.py +1200 -0
- matplotlib_map_utils/defaults/__init__.py +4 -0
- matplotlib_map_utils/{defaults.py → defaults/north_arrow.py} +4 -4
- matplotlib_map_utils/defaults/scale_bar.py +377 -0
- matplotlib_map_utils/validation/__init__.py +2 -0
- matplotlib_map_utils/validation/functions.py +231 -0
- matplotlib_map_utils/validation/north_arrow.py +175 -0
- matplotlib_map_utils/validation/scale_bar.py +274 -0
- matplotlib_map_utils-2.0.0.dist-info/METADATA +281 -0
- matplotlib_map_utils-2.0.0.dist-info/RECORD +18 -0
- {matplotlib_map_utils-1.0.2.dist-info → matplotlib_map_utils-2.0.0.dist-info}/WHEEL +1 -1
- matplotlib_map_utils/validation.py +0 -332
- matplotlib_map_utils-1.0.2.dist-info/METADATA +0 -131
- matplotlib_map_utils-1.0.2.dist-info/RECORD +0 -11
- {matplotlib_map_utils-1.0.2.dist-info → matplotlib_map_utils-2.0.0.dist-info}/LICENSE +0 -0
- {matplotlib_map_utils-1.0.2.dist-info → matplotlib_map_utils-2.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,175 @@
|
|
1
|
+
############################################################
|
2
|
+
# validation/north_arrow.py contains all the main objects
|
3
|
+
# for checking inputs passed to class definitions
|
4
|
+
############################################################
|
5
|
+
|
6
|
+
### IMPORTING PACKAGES ###
|
7
|
+
|
8
|
+
# Default packages
|
9
|
+
import warnings
|
10
|
+
# Math packages
|
11
|
+
import numpy
|
12
|
+
# Geo packages
|
13
|
+
import pyproj
|
14
|
+
# Graphical packages
|
15
|
+
import matplotlib
|
16
|
+
# matplotlib's useful validation functions
|
17
|
+
import matplotlib.rcsetup
|
18
|
+
# The types we use in this script
|
19
|
+
from typing import Tuple, TypedDict, Literal, get_args
|
20
|
+
# Finally, the validation functions
|
21
|
+
from . import functions as vf
|
22
|
+
|
23
|
+
### ALL ###
|
24
|
+
# This code tells other packages what to import if not explicitly stated
|
25
|
+
__all__ = [
|
26
|
+
"_TYPE_BASE", "_TYPE_FANCY", "_TYPE_LABEL", "_TYPE_SHADOW",
|
27
|
+
"_TYPE_PACK", "_TYPE_AOB", "_TYPE_ROTATION"
|
28
|
+
]
|
29
|
+
|
30
|
+
### TYPE HINTS ###
|
31
|
+
# This section of the code is for defining structured dictionaries and lists
|
32
|
+
# for the inputs necessary for object creation we've created (such as the style dictionaries)
|
33
|
+
# so that intellisense can help with autocompletion
|
34
|
+
|
35
|
+
class _TYPE_BASE(TypedDict, total=False):
|
36
|
+
coords: numpy.array # must be 2D numpy array
|
37
|
+
facecolor: str # any color value for matplotlib
|
38
|
+
edgecolor: str # any color value for matplotlib
|
39
|
+
linewidth: float | int # between 0 and inf
|
40
|
+
zorder: int # any integer
|
41
|
+
|
42
|
+
class _TYPE_FANCY(TypedDict, total=False):
|
43
|
+
coords: numpy.array # must be 2D numpy array
|
44
|
+
facecolor: str # any color value for matplotlib
|
45
|
+
zorder: int # any integer
|
46
|
+
|
47
|
+
class _TYPE_LABEL(TypedDict, total=False):
|
48
|
+
text: str # any string that you want to display ("N" or "North" being the most common)
|
49
|
+
position: Literal["top", "bottom", "left", "right"] # from matplotlib documentation
|
50
|
+
ha: Literal["left", "center", "right"] # from matplotlib documentation
|
51
|
+
va: Literal["baseline", "bottom", "center", "center_baseline", "top"] # from matplotlib documentation
|
52
|
+
fontsize: str | float | int # any fontsize value for matplotlib
|
53
|
+
fontfamily: Literal["serif", "sans-serif", "cursive", "fantasy", "monospace"] # from matplotlib documentation
|
54
|
+
fontstyle: Literal["normal", "italic", "oblique"] # from matplotlib documentation
|
55
|
+
color: str # any color value for matplotlib
|
56
|
+
fontweight: Literal["normal", "bold", "heavy", "light", "ultrabold", "ultralight"] # from matplotlib documentation
|
57
|
+
stroke_width: float | int # between 0 and infinity
|
58
|
+
stroke_color: str # any color value for matplotlib
|
59
|
+
rotation: float | int # between -360 and 360
|
60
|
+
zorder: int # any integer
|
61
|
+
|
62
|
+
class _TYPE_SHADOW(TypedDict, total=False):
|
63
|
+
offset: Tuple[float | int, float | int] # two-length tuple or list of x,y values in points
|
64
|
+
alpha: float | int # between 0 and 1
|
65
|
+
shadow_rgbFace: str # any color vlaue for matplotlib
|
66
|
+
|
67
|
+
class _TYPE_PACK(TypedDict, total=False):
|
68
|
+
sep: float | int # between 0 and inf
|
69
|
+
align: Literal["top", "bottom", "left", "right", "center", "baseline"] # from matplotlib documentation
|
70
|
+
pad: float | int # between 0 and inf
|
71
|
+
width: float | int # between 0 and inf
|
72
|
+
height: float | int # between 0 and inf
|
73
|
+
mode: Literal["fixed", "expand", "equal"] # from matplotlib documentation
|
74
|
+
|
75
|
+
class _TYPE_AOB(TypedDict, total=False):
|
76
|
+
facecolor: str # NON-STANDARD: used to set the facecolor of the offset box (i.e. to white), any color vlaue for matplotlib
|
77
|
+
edgecolor: str # NON-STANDARD: used to set the edge of the offset box (i.e. to black), any color vlaue for matplotlib
|
78
|
+
alpha: float | int # NON-STANDARD: used to set the transparency of the face color of the offset box^, between 0 and 1
|
79
|
+
pad: float | int # between 0 and inf
|
80
|
+
borderpad: float | int # between 0 and inf
|
81
|
+
prop: str | float | int # any fontsize value for matplotlib
|
82
|
+
frameon: bool # any bool
|
83
|
+
# bbox_to_anchor: None # NOTE: currently unvalidated, use at your own risk!
|
84
|
+
# bbox_transform: None # NOTE: currently unvalidated, use at your own risk!
|
85
|
+
|
86
|
+
class _TYPE_ROTATION(TypedDict, total=False):
|
87
|
+
degrees: float | int # anything between -360 and 360, or None for "auto"
|
88
|
+
crs: str | int | pyproj.CRS # only required if degrees is None: should be a valid cartopy or pyproj crs, or a string that can be converted to that
|
89
|
+
reference: Literal["axis", "data", "center"] # only required if degrees is None: should be either "axis" or "data" or "center"
|
90
|
+
coords: Tuple[float | int, float | int] # only required if degrees is None: should be a tuple of coordinates in the relevant reference window
|
91
|
+
|
92
|
+
### VALIDITY DICTS ###
|
93
|
+
# These compile the functions above^, as well as matplotlib's built-in validity functions
|
94
|
+
# into dictionaries that can be used to validate all the inputs to a dictionary at once
|
95
|
+
|
96
|
+
_VALIDATE_PRIMARY = {
|
97
|
+
"location":{"func":vf._validate_list, "kwargs":{"list":["upper right", "upper left", "lower left", "lower right", "center left", "center right", "lower center", "upper center", "center"]}},
|
98
|
+
"scale":{"func":vf._validate_range, "kwargs":{"min":0, "max":None, "none_ok":True}}, # between 0 and inf
|
99
|
+
}
|
100
|
+
|
101
|
+
_VALIDATE_BASE = {
|
102
|
+
"coords":{"func":vf._validate_coords, "kwargs":{"numpy_type":numpy.ndarray, "dims":2}}, # must be 2D numpy array
|
103
|
+
"facecolor":{"func":matplotlib.rcsetup.validate_color}, # any color value for matplotlib
|
104
|
+
"edgecolor":{"func":matplotlib.rcsetup.validate_color}, # any color value for matplotlib
|
105
|
+
"linewidth":{"func":vf._validate_range, "kwargs":{"min":0, "max":None}}, # between 0 and inf
|
106
|
+
"zorder":{"func":vf._validate_type, "kwargs":{"match":int}} # any integer
|
107
|
+
}
|
108
|
+
|
109
|
+
_VALIDATE_FANCY = {
|
110
|
+
"coords":{"func":vf._validate_coords, "kwargs":{"numpy_type":numpy.ndarray, "dims":2}}, # must be 2D numpy array
|
111
|
+
"facecolor":{"func":matplotlib.rcsetup.validate_color}, # any color value for matplotlib
|
112
|
+
"zorder":{"func":vf._validate_type, "kwargs":{"match":int}} # any integer
|
113
|
+
}
|
114
|
+
|
115
|
+
_VALID_LABEL_POSITION = get_args(_TYPE_LABEL.__annotations__["position"])
|
116
|
+
_VALID_LABEL_HA = get_args(_TYPE_LABEL.__annotations__["ha"])
|
117
|
+
_VALID_LABEL_VA = get_args(_TYPE_LABEL.__annotations__["va"])
|
118
|
+
_VALID_LABEL_FONTFAMILY = get_args(_TYPE_LABEL.__annotations__["fontfamily"])
|
119
|
+
_VALID_LABEL_FONTSTYLE = get_args(_TYPE_LABEL.__annotations__["fontstyle"])
|
120
|
+
_VALID_LABEL_FONTWEIGHT = get_args(_TYPE_LABEL.__annotations__["fontweight"])
|
121
|
+
|
122
|
+
_VALIDATE_LABEL = {
|
123
|
+
"text":{"func":vf._validate_type, "kwargs":{"match":str}}, # any string
|
124
|
+
"position":{"func":vf._validate_list, "kwargs":{"list":_VALID_LABEL_POSITION}},
|
125
|
+
"ha":{"func":vf._validate_list, "kwargs":{"list":_VALID_LABEL_HA}},
|
126
|
+
"va":{"func":vf._validate_list, "kwargs":{"list":_VALID_LABEL_VA}},
|
127
|
+
"fontsize":{"func":matplotlib.rcsetup.validate_fontsize}, # any fontsize value for matplotlib
|
128
|
+
"fontfamily":{"func":vf._validate_list, "kwargs":{"list":_VALID_LABEL_FONTFAMILY}},
|
129
|
+
"fontstyle":{"func":vf._validate_list, "kwargs":{"list":_VALID_LABEL_FONTSTYLE}},
|
130
|
+
"color":{"func":matplotlib.rcsetup.validate_color}, # any color value for matplotlib
|
131
|
+
"fontweight":{"func":matplotlib.rcsetup.validate_fontweight}, # any fontweight value for matplotlib
|
132
|
+
"stroke_width":{"func":vf._validate_range, "kwargs":{"min":0, "max":None}}, # between 0 and inf
|
133
|
+
"stroke_color":{"func":matplotlib.rcsetup.validate_color}, # any color value for matplotlib
|
134
|
+
"rotation":{"func":vf._validate_range, "kwargs":{"min":-360, "max":360, "none_ok":True}}, # anything between -360 and 360, or None for "auto"
|
135
|
+
"zorder":{"func":vf._validate_type, "kwargs":{"match":int}} # any integer
|
136
|
+
}
|
137
|
+
|
138
|
+
_VALIDATE_SHADOW = {
|
139
|
+
"offset":{"func":vf._validate_tuple, "kwargs":{"length":2, "types":[float, int]}},
|
140
|
+
"alpha":{"func":vf._validate_range, "kwargs":{"min":0, "max":1, "none_ok":True}}, # any value between 0 and 1
|
141
|
+
"shadow_rgbFace":{"func":matplotlib.rcsetup.validate_color}, # any color value for matplotlib
|
142
|
+
}
|
143
|
+
|
144
|
+
_VALID_PACK_ALIGN = get_args(_TYPE_PACK.__annotations__["align"])
|
145
|
+
_VALID_PACK_MODE = get_args(_TYPE_PACK.__annotations__["mode"])
|
146
|
+
|
147
|
+
_VALIDATE_PACK = {
|
148
|
+
"sep":{"func":vf._validate_range, "kwargs":{"min":0, "max":None}}, # between 0 and inf
|
149
|
+
"align":{"func":vf._validate_list, "kwargs":{"list":_VALID_PACK_ALIGN}},
|
150
|
+
"pad":{"func":vf._validate_range, "kwargs":{"min":0, "max":None}}, # between 0 and inf
|
151
|
+
"width":{"func":vf._validate_range, "kwargs":{"min":0, "max":None, "none_ok":True}}, # between 0 and inf
|
152
|
+
"height":{"func":vf._validate_range, "kwargs":{"min":0, "max":None, "none_ok":True}}, # between 0 and inf
|
153
|
+
"mode":{"func":vf._validate_list, "kwargs":{"list":_VALID_PACK_MODE}}
|
154
|
+
}
|
155
|
+
|
156
|
+
_VALIDATE_AOB = {
|
157
|
+
"facecolor":{"func":vf._validate_color_or_none, "kwargs":{"none_ok":True}}, # any color value for matplotlib OR NONE
|
158
|
+
"edgecolor":{"func":vf._validate_color_or_none, "kwargs":{"none_ok":True}}, # any color value for matplotlib OR NONE
|
159
|
+
"alpha":{"func":vf._validate_range, "kwargs":{"min":0, "max":1, "none_ok":True}}, # any value between 0 and 1
|
160
|
+
"pad":{"func":vf._validate_range, "kwargs":{"min":0, "max":None}}, # between 0 and inf
|
161
|
+
"borderpad":{"func":vf._validate_range, "kwargs":{"min":0, "max":None}}, # between 0 and inf
|
162
|
+
"prop":{"func":matplotlib.rcsetup.validate_fontsize}, # any fontsize value for matplotlib
|
163
|
+
"frameon":{"func":vf._validate_type, "kwargs":{"match":bool}}, # any bool
|
164
|
+
"bbox_to_anchor":{"func":vf._skip_validation}, # NOTE: currently unvalidated, use at your own risk!
|
165
|
+
"bbox_transform":{"func":vf._skip_validation} # NOTE: currently unvalidated, use at your own risk!
|
166
|
+
}
|
167
|
+
|
168
|
+
_VALID_ROTATION_REFERENCE = get_args(_TYPE_ROTATION.__annotations__["reference"])
|
169
|
+
|
170
|
+
_VALIDATE_ROTATION = {
|
171
|
+
"degrees":{"func":vf._validate_range, "kwargs":{"min":-360, "max":360, "none_ok":True}}, # anything between -360 and 360, or None for "auto"
|
172
|
+
"crs":{"func":vf._validate_crs, "kwargs":{"none_ok":True}}, # see _validate_crs for details on what is accepted
|
173
|
+
"reference":{"func":vf._validate_list, "kwargs":{"list":_VALID_ROTATION_REFERENCE, "none_ok":True}}, # see _VALID_ROTATION_REFERENCE for accepted values
|
174
|
+
"coords":{"func":vf._validate_tuple, "kwargs":{"length":2, "types":[float, int], "none_ok":True}} # only required if degrees is None: should be a tuple of coordinates in the relevant reference window
|
175
|
+
}
|
@@ -0,0 +1,274 @@
|
|
1
|
+
############################################################
|
2
|
+
# validation/scale_bar.py contains all the main objects
|
3
|
+
# for checking inputs passed to class definitions
|
4
|
+
############################################################
|
5
|
+
|
6
|
+
### IMPORTING PACKAGES ###
|
7
|
+
|
8
|
+
# Geo packages
|
9
|
+
import pyproj
|
10
|
+
# Graphical packages
|
11
|
+
import matplotlib
|
12
|
+
# matplotlib's useful validation functions
|
13
|
+
import matplotlib.rcsetup
|
14
|
+
# The types we use in this script
|
15
|
+
from typing import Tuple, TypedDict, Literal, get_args
|
16
|
+
# Finally, the validation functions
|
17
|
+
from . import functions as vf
|
18
|
+
|
19
|
+
### ALL ###
|
20
|
+
# This code tells other packages what to import if not explicitly stated
|
21
|
+
__all__ = [
|
22
|
+
"preferred_divs", "convert_dict", "units_standard",
|
23
|
+
"_TYPE_BAR", "_TYPE_LABELS", "_TYPE_UNITS", "_TYPE_TEXT", "_TYPE_AOB"
|
24
|
+
]
|
25
|
+
|
26
|
+
### CONSTANTS ###
|
27
|
+
# These are constants that we use elsewhere in the script
|
28
|
+
# when setting up a scale bar
|
29
|
+
|
30
|
+
# A list of preferred "highest" numbers
|
31
|
+
# And the corresponding major and min divs
|
32
|
+
preferred_divs = {
|
33
|
+
2:[4,2],
|
34
|
+
2.5:[5,1],
|
35
|
+
3:[3,3],
|
36
|
+
4:[4,2],
|
37
|
+
5:[5,1],
|
38
|
+
6:[3,2],
|
39
|
+
7:[2,1],
|
40
|
+
8:[4,2],
|
41
|
+
9:[3,3],
|
42
|
+
10:[5,2],
|
43
|
+
}
|
44
|
+
|
45
|
+
# For converting between units
|
46
|
+
# Everything is relative to the meter
|
47
|
+
convert_dict = {
|
48
|
+
"m":1,
|
49
|
+
"ft":0.3048,
|
50
|
+
"yd":0.9144,
|
51
|
+
"mi":1609.34,
|
52
|
+
"nmi":1852,
|
53
|
+
"km":1000,
|
54
|
+
}
|
55
|
+
|
56
|
+
# Standardizing the text of the units
|
57
|
+
units_standard = {
|
58
|
+
# degrees
|
59
|
+
# note these are not valid units to convert INTO
|
60
|
+
# "deg":"deg", "deg":"degree",
|
61
|
+
# feet
|
62
|
+
# the last one at the end is how many projections report it
|
63
|
+
"ft":"ft", "ftUS":"ft", "foot":"ft", "feet":"ft", "US survey foot":"ft",
|
64
|
+
# yards
|
65
|
+
"yd":"yd", "yard":"yd", "yards":"yd",
|
66
|
+
# miles
|
67
|
+
"mi":"mi", "mile":"mi", "miles":"mi",
|
68
|
+
# nautical miles
|
69
|
+
# note that nm is NOT accepted - that is nanometers!
|
70
|
+
"nmi":"nmi", "nautical":"nmi", "nautical mile":"nmi", "nautical miles":"nmi",
|
71
|
+
# meters
|
72
|
+
"m":"m", "meter":"m", "metre":"m", "meters":"m", "metres":"m",
|
73
|
+
# kilometers
|
74
|
+
"km":"km", "kilometer":"km", "kilometers":"km", "kilometre":"km", "kilometres":"km",
|
75
|
+
}
|
76
|
+
|
77
|
+
### TYPE HINTS ###
|
78
|
+
# This section of the code is for defining structured dictionaries and lists
|
79
|
+
# for the inputs necessary for object creation we've created (such as the style dictionaries)
|
80
|
+
# so that intellisense can help with autocompletion
|
81
|
+
|
82
|
+
class _TYPE_BAR(TypedDict, total=False):
|
83
|
+
projection: str | int | pyproj.CRS # should be a valid cartopy or pyproj crs, or a string or int that can be converted to that
|
84
|
+
unit: Literal["m","km","ft","yd","mi","nmi"] # the units you want to convert the bar to, if different than the projection units
|
85
|
+
rotation: float | int # between -360 and 360
|
86
|
+
max: float | int # the max bar value, in desired units (as specified by units dict)
|
87
|
+
length: float | int # the length of the bar in inches (if > 1) or as a % of the axis (if between 0 and 1)
|
88
|
+
height: float | int # the height of the bar in inches
|
89
|
+
reverse: bool # flag if the order of the elements should be reversed
|
90
|
+
major_div: int # the number of major divisions on the bar
|
91
|
+
minor_div: int # the number of minor divisions on the bar
|
92
|
+
minor_frac: float # the fraction of the major division that the minor division should be (e.g. 0.5 = half the size of the major division)
|
93
|
+
minor_type: Literal["all","first","none"] # whether the minor divisions should be drawn on all major divisions or just the first one
|
94
|
+
# Boxes only
|
95
|
+
facecolors: list | tuple | str # a color or list of colors to use for the faces of the boxes
|
96
|
+
edgecolors: list | tuple | str # a color or list of colors to use for the edges of the boxes
|
97
|
+
edgewidth: float | int # the line thickness of the edges of the boxes
|
98
|
+
# Ticks only
|
99
|
+
tick_loc: Literal["above","below","middle"] # the location of the ticks relative to the bar
|
100
|
+
basecolors: list | tuple | str # a color or list of colors to use for the bottom bar
|
101
|
+
tickcolors: list | tuple | str # a color or list of colors to use for the ticks
|
102
|
+
tickwidth: float | int # the line thickness of the bottom bar and ticks
|
103
|
+
|
104
|
+
|
105
|
+
class _TYPE_LABELS(TypedDict, total=False):
|
106
|
+
labels: list | tuple # a list of text labels to replace the default labels of the major elements
|
107
|
+
format: str # a format string to apply to the default labels of the major elements
|
108
|
+
format_int: bool # if True, float divisions that end in zero wil be converted to ints (e.g. 1.0 -> 1)
|
109
|
+
style: Literal["major","first_last","last_only","minor_all","minor_first"] # each selection in the list creates a different set of labels
|
110
|
+
loc: Literal["above","below"] # whether the major text elements should appear above or below the bar
|
111
|
+
fontsize: str | float | int # any fontsize value for matplotlib
|
112
|
+
textcolors: list | str # a color or list of colors to use for the major text elements
|
113
|
+
fontfamily: Literal["serif", "sans-serif", "cursive", "fantasy", "monospace"] # from matplotlib documentation
|
114
|
+
fontstyle: Literal["normal", "italic", "oblique"] # from matplotlib documentation
|
115
|
+
fontweight: Literal["normal", "bold", "heavy", "light", "ultrabold", "ultralight"] # from matplotlib documentation
|
116
|
+
stroke_width: float | int # between 0 and infinity
|
117
|
+
stroke_color: str # optional: any color value for matplotlib
|
118
|
+
rotation: float | int # a value between -360 and 360 to rotate the text elements by
|
119
|
+
rotation_mode: Literal["anchor","default"] # from matplotlib documentation
|
120
|
+
sep: float | int # between 0 and inf, used to add separation between the labels and the bar
|
121
|
+
pad: float | int # between 0 and inf, used to add separation between the labels and the bar
|
122
|
+
|
123
|
+
|
124
|
+
class _TYPE_UNITS(TypedDict, total=False):
|
125
|
+
label: str # an override for the units label
|
126
|
+
loc: Literal["bar","text","opposite"] # where the units text should appear (in line with the bar, or the major div text, or opposite the major div text)
|
127
|
+
fontsize: str | float | int # any fontsize value for matplotlib
|
128
|
+
textcolor: str # any color value for matplotlib
|
129
|
+
fontfamily: Literal["serif", "sans-serif", "cursive", "fantasy", "monospace"] # from matplotlib documentation
|
130
|
+
fontstyle: Literal["normal", "italic", "oblique"] # from matplotlib documentation
|
131
|
+
fontweight: Literal["normal", "bold", "heavy", "light", "ultrabold", "ultralight"] # from matplotlib documentation
|
132
|
+
stroke_width: float | int # between 0 and infinity
|
133
|
+
stroke_color: str # any color value for matplotlib
|
134
|
+
rotation: float | int # between -360 and 360
|
135
|
+
rotation_mode: Literal["anchor","default"] # from matplotlib documentation
|
136
|
+
sep: float | int # between 0 and inf, used to add separation between the units text and the bar ("opposite" only)
|
137
|
+
pad: float | int # between 0 and inf, used to add separation between the units text and the bar ("opposite" only)
|
138
|
+
|
139
|
+
|
140
|
+
class _TYPE_TEXT(TypedDict, total=False):
|
141
|
+
fontsize: str | float | int # any fontsize value for matplotlib
|
142
|
+
textcolor: list | str # a color or list of colors to use for all the text elements
|
143
|
+
fontfamily: Literal["serif", "sans-serif", "cursive", "fantasy", "monospace"] # from matplotlib documentation
|
144
|
+
fontstyle: Literal["normal", "italic", "oblique"] # from matplotlib documentation
|
145
|
+
fontweight: Literal["normal", "bold", "heavy", "light", "ultrabold", "ultralight"] # from matplotlib documentation
|
146
|
+
stroke_width: float | int # between 0 and infinity
|
147
|
+
stroke_color: str # optional: any color value for matplotlib
|
148
|
+
rotation: float | int # a value between -360 and 360 to rotate the text elements by
|
149
|
+
rotation_mode: Literal["anchor","default"] # from matplotlib documentation
|
150
|
+
|
151
|
+
|
152
|
+
class _TYPE_AOB(TypedDict, total=False):
|
153
|
+
facecolor: str # NON-STANDARD: used to set the facecolor of the offset box (i.e. to white), any color vlaue for matplotlib
|
154
|
+
edgecolor: str # NON-STANDARD: used to set the edge of the offset box (i.e. to black), any color vlaue for matplotlib
|
155
|
+
alpha: float | int # NON-STANDARD: used to set the transparency of the face color of the offset box^, between 0 and 1
|
156
|
+
pad: float | int # between 0 and inf
|
157
|
+
borderpad: float | int # between 0 and inf
|
158
|
+
prop: str | float | int # any fontsize value for matplotlib
|
159
|
+
frameon: bool # any bool
|
160
|
+
# bbox_to_anchor: None # NOTE: currently unvalidated, use at your own risk!
|
161
|
+
# bbox_transform: None # NOTE: currently unvalidated, use at your own risk!
|
162
|
+
|
163
|
+
### VALIDITY DICTS ###
|
164
|
+
# These compile the functions above^, as well as matplotlib's built-in validity functions
|
165
|
+
# into dictionaries that can be used to validate all the inputs to a dictionary at once
|
166
|
+
|
167
|
+
_VALIDATE_PRIMARY = {
|
168
|
+
"style":{"func":vf._validate_list, "kwargs":{"list":["ticks","boxes"]}},
|
169
|
+
"location":{"func":vf._validate_list, "kwargs":{"list":["upper right", "upper left", "lower left", "lower right", "center left", "center right", "lower center", "upper center", "center"]}},
|
170
|
+
}
|
171
|
+
|
172
|
+
_VALID_BAR_TICK_LOC = get_args(_TYPE_BAR.__annotations__["tick_loc"])
|
173
|
+
_VALID_BAR_MINOR_TYPE = get_args(_TYPE_BAR.__annotations__["minor_type"])
|
174
|
+
|
175
|
+
_VALIDATE_BAR = {
|
176
|
+
"projection":{"func":vf._validate_projection}, # must be a valid CRS
|
177
|
+
"unit":{"func":vf._validate_list, "kwargs":{"list":list(units_standard.keys()), "none_ok":True}}, # any of the listed unit values are accepted
|
178
|
+
"rotation":{"func":vf._validate_range, "kwargs":{"min":-360, "max":360, "none_ok":True}}, # between -360 and 360 degrees
|
179
|
+
"max":{"func":vf._validate_range, "kwargs":{"min":0, "max":None, "none_ok":True}}, # between 0 and inf
|
180
|
+
"length":{"func":vf._validate_range, "kwargs":{"min":0, "max":None, "none_ok":True}}, # between 0 and inf
|
181
|
+
"height":{"func":vf._validate_range, "kwargs":{"min":0, "max":None, "none_ok":True}}, # between 0 and inf
|
182
|
+
"reverse":{"func":vf._validate_type, "kwargs":{"match":bool}}, # any bool
|
183
|
+
|
184
|
+
"major_div":{"func":vf._validate_range, "kwargs":{"min":1, "max":None, "none_ok":True}}, # between 0 and inf
|
185
|
+
"minor_div":{"func":vf._validate_range, "kwargs":{"min":0, "max":None, "none_ok":True}}, # between 0 and inf
|
186
|
+
"minor_frac":{"func":vf._validate_range, "kwargs":{"min":0, "max":1, "none_ok":True}}, # ticks only: between 0 and 1
|
187
|
+
"minor_type":{"func":vf._validate_list, "kwargs":{"list":_VALID_BAR_MINOR_TYPE, "none_ok":True}}, # any item in the list, or None (for no minor)
|
188
|
+
|
189
|
+
"facecolors":{"func":vf._validate_iterable, "kwargs":{"func":matplotlib.rcsetup.validate_color}}, # boxes only: any color value for matplotlib
|
190
|
+
"edgecolors":{"func":vf._validate_iterable, "kwargs":{"func":matplotlib.rcsetup.validate_color}}, # boxes only: any color value for matplotlib
|
191
|
+
"edgewidth":{"func":vf._validate_range, "kwargs":{"min":0, "max":None, "none_ok":True}}, # boxes only: between 0 and inf
|
192
|
+
|
193
|
+
"tick_loc":{"func":vf._validate_list, "kwargs":{"list":_VALID_BAR_TICK_LOC}}, # ticks only: any item in the list
|
194
|
+
"basecolors":{"func":vf._validate_iterable, "kwargs":{"func":matplotlib.rcsetup.validate_color}}, # ticks only: any color value for matplotlib
|
195
|
+
"tickcolors":{"func":vf._validate_iterable, "kwargs":{"func":matplotlib.rcsetup.validate_color}}, # ticks only: any color value for matplotlib
|
196
|
+
"tickwidth":{"func":vf._validate_range, "kwargs":{"min":0, "max":None, "none_ok":True}}, # ticks only: between 0 and inf
|
197
|
+
}
|
198
|
+
|
199
|
+
_VALID_LABELS_STYLE = get_args(_TYPE_LABELS.__annotations__["style"])
|
200
|
+
_VALID_LABELS_LOC = get_args(_TYPE_LABELS.__annotations__["loc"])
|
201
|
+
_VALID_LABELS_FONTFAMILY = get_args(_TYPE_LABELS.__annotations__["fontfamily"])
|
202
|
+
_VALID_LABELS_FONTSTYLE = get_args(_TYPE_LABELS.__annotations__["fontstyle"])
|
203
|
+
_VALID_LABELS_FONTWEIGHT = get_args(_TYPE_LABELS.__annotations__["fontweight"])
|
204
|
+
_VALID_LABELS_ROTATION_MODE = get_args(_TYPE_LABELS.__annotations__["rotation_mode"])
|
205
|
+
|
206
|
+
_VALIDATE_LABELS = {
|
207
|
+
"labels":{"func":vf._validate_iterable, "kwargs":{"func":vf._validate_types,"kwargs":{"matches":[str,bool], "none_ok":True}}}, # any list of strings
|
208
|
+
"format":{"func":vf._validate_type, "kwargs":{"match":str}}, # only check that it is a string, not that it is a valid format string
|
209
|
+
"format_int":{"func":vf._validate_type, "kwargs":{"match":bool}}, # any bool
|
210
|
+
"style":{"func":vf._validate_list, "kwargs":{"list":_VALID_LABELS_STYLE}}, # any item in the list
|
211
|
+
"loc":{"func":vf._validate_list, "kwargs":{"list":_VALID_LABELS_LOC, "none_ok":True}}, # any string in the list we allow
|
212
|
+
"fontsize":{"func":matplotlib.rcsetup.validate_fontsize}, # any fontsize for matplotlib
|
213
|
+
"textcolors":{"func":vf._validate_iterable, "kwargs":{"func":matplotlib.rcsetup.validate_color}}, # any color value for matplotlib
|
214
|
+
"fontfamily":{"func":vf._validate_list, "kwargs":{"list":_VALID_LABELS_FONTFAMILY}},
|
215
|
+
"fontstyle":{"func":vf._validate_list, "kwargs":{"list":_VALID_LABELS_FONTSTYLE}},
|
216
|
+
"fontweight":{"func":matplotlib.rcsetup.validate_fontweight}, # any fontweight value for matplotlib
|
217
|
+
"stroke_width":{"func":vf._validate_range, "kwargs":{"min":0, "max":None}}, # between 0 and inf
|
218
|
+
"stroke_color":{"func":matplotlib.rcsetup.validate_color}, # any color value for matplotlib
|
219
|
+
"rotation":{"func":vf._validate_range, "kwargs":{"min":-360, "max":360, "none_ok":True}}, # between -360 and 360 degrees
|
220
|
+
"rotation_mode":{"func":vf._validate_list, "kwargs":{"list":_VALID_LABELS_ROTATION_MODE, "none_ok":True}}, # any string in the list we allow
|
221
|
+
"sep":{"func":vf._validate_range, "kwargs":{"min":0, "max":None}}, # between 0 and inf
|
222
|
+
"pad":{"func":vf._validate_range, "kwargs":{"min":0, "max":None}}, # between 0 and inf
|
223
|
+
}
|
224
|
+
|
225
|
+
_VALID_UNITS_LOC = get_args(_TYPE_UNITS.__annotations__["loc"])
|
226
|
+
_VALID_UNITS_FONTFAMILY = get_args(_TYPE_UNITS.__annotations__["fontfamily"])
|
227
|
+
_VALID_UNITS_FONTSTYLE = get_args(_TYPE_UNITS.__annotations__["fontstyle"])
|
228
|
+
_VALID_UNITS_FONTWEIGHT = get_args(_TYPE_UNITS.__annotations__["fontweight"])
|
229
|
+
_VALID_UNITS_ROTATION_MODE = get_args(_TYPE_UNITS.__annotations__["rotation_mode"])
|
230
|
+
|
231
|
+
_VALIDATE_UNITS = {
|
232
|
+
"label":{"func":vf._validate_type, "kwargs":{"match":str, "none_ok":True}}, # any string
|
233
|
+
"loc":{"func":vf._validate_list, "kwargs":{"list":_VALID_UNITS_LOC, "none_ok":True}}, # any string in the list we allow
|
234
|
+
"fontsize":{"func":matplotlib.rcsetup.validate_fontsize}, # any fontsize for matplotlib
|
235
|
+
"textcolor":{"func":matplotlib.rcsetup.validate_color}, # any color value for matplotlib
|
236
|
+
"fontfamily":{"func":vf._validate_list, "kwargs":{"list":_VALID_UNITS_FONTFAMILY}},
|
237
|
+
"fontstyle":{"func":vf._validate_list, "kwargs":{"list":_VALID_UNITS_FONTSTYLE}},
|
238
|
+
"fontweight":{"func":matplotlib.rcsetup.validate_fontweight}, # any fontweight value for matplotlib
|
239
|
+
"stroke_width":{"func":vf._validate_range, "kwargs":{"min":0, "max":None}}, # between 0 and inf
|
240
|
+
"stroke_color":{"func":matplotlib.rcsetup.validate_color}, # any color value for matplotlib
|
241
|
+
"rotation":{"func":vf._validate_range, "kwargs":{"min":-360, "max":360, "none_ok":True}}, # between -360 and 360 degrees
|
242
|
+
"rotation_mode":{"func":vf._validate_list, "kwargs":{"list":_VALID_UNITS_ROTATION_MODE, "none_ok":True}}, # any string in the list we allow
|
243
|
+
"sep":{"func":vf._validate_range, "kwargs":{"min":0, "max":None}}, # between 0 and inf
|
244
|
+
"pad":{"func":vf._validate_range, "kwargs":{"min":0, "max":None}}, # between 0 and inf
|
245
|
+
}
|
246
|
+
|
247
|
+
_VALID_TEXT_FONTFAMILY = get_args(_TYPE_TEXT.__annotations__["fontfamily"])
|
248
|
+
_VALID_TEXT_FONTSTYLE = get_args(_TYPE_TEXT.__annotations__["fontstyle"])
|
249
|
+
_VALID_TEXT_FONTWEIGHT = get_args(_TYPE_TEXT.__annotations__["fontweight"])
|
250
|
+
_VALID_TEXT_ROTATION_MODE = get_args(_TYPE_TEXT.__annotations__["rotation_mode"])
|
251
|
+
|
252
|
+
_VALIDATE_TEXT = {
|
253
|
+
"fontsize":{"func":matplotlib.rcsetup.validate_fontsize}, # any fontsize for matplotlib
|
254
|
+
"textcolor":{"func":matplotlib.rcsetup.validate_color}, # any color value for matplotlib
|
255
|
+
"fontfamily":{"func":vf._validate_list, "kwargs":{"list":_VALID_TEXT_FONTFAMILY}},
|
256
|
+
"fontstyle":{"func":vf._validate_list, "kwargs":{"list":_VALID_TEXT_FONTSTYLE}},
|
257
|
+
"fontweight":{"func":matplotlib.rcsetup.validate_fontweight}, # any fontweight value for matplotlib
|
258
|
+
"stroke_width":{"func":vf._validate_range, "kwargs":{"min":0, "max":None}}, # between 0 and inf
|
259
|
+
"stroke_color":{"func":matplotlib.rcsetup.validate_color}, # any color value for matplotlib
|
260
|
+
"rotation":{"func":vf._validate_range, "kwargs":{"min":-360, "max":360, "none_ok":True}}, # between -360 and 360 degrees
|
261
|
+
"rotation_mode":{"func":vf._validate_list, "kwargs":{"list":_VALID_TEXT_ROTATION_MODE, "none_ok":True}}, # any string in the list we allow
|
262
|
+
}
|
263
|
+
|
264
|
+
_VALIDATE_AOB = {
|
265
|
+
"facecolor":{"func":vf._validate_color_or_none, "kwargs":{"none_ok":True}}, # any color value for matplotlib OR NONE
|
266
|
+
"edgecolor":{"func":vf._validate_color_or_none, "kwargs":{"none_ok":True}}, # any color value for matplotlib OR NONE
|
267
|
+
"alpha":{"func":vf._validate_range, "kwargs":{"min":0, "max":1, "none_ok":True}}, # any value between 0 and 1
|
268
|
+
"pad":{"func":vf._validate_range, "kwargs":{"min":0, "max":None}}, # between 0 and inf
|
269
|
+
"borderpad":{"func":vf._validate_range, "kwargs":{"min":0, "max":None}}, # between 0 and inf
|
270
|
+
"prop":{"func":matplotlib.rcsetup.validate_fontsize}, # any fontsize value for matplotlib
|
271
|
+
"frameon":{"func":vf._validate_type, "kwargs":{"match":bool}}, # any bool
|
272
|
+
"bbox_to_anchor":{"func":vf._skip_validation}, # NOTE: currently unvalidated, use at your own risk!
|
273
|
+
"bbox_transform":{"func":vf._skip_validation}, # NOTE: currently unvalidated, use at your own risk!
|
274
|
+
}
|