matplotlib-map-utils 1.0.3__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.
@@ -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
+ }