matplotlib-map-utils 4.1.0__tar.gz → 4.1.1__tar.gz
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-4.1.0/matplotlib_map_utils.egg-info → matplotlib_map_utils-4.1.1}/PKG-INFO +2 -2
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/README.md +1 -1
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/__init__.py +16 -2
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/core/inset_map.py +11 -11
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/core/north_arrow.py +12 -12
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/core/scale_bar.py +30 -24
- matplotlib_map_utils-4.1.1/matplotlib_map_utils/py.typed +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/validation/inset_map.py +21 -7
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/validation/north_arrow.py +85 -16
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/validation/scale_bar.py +115 -23
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/validation/shared.py +36 -1
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1/matplotlib_map_utils.egg-info}/PKG-INFO +2 -2
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils.egg-info/SOURCES.txt +1 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/pyproject.toml +3 -1
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/LICENSE +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/docs/assets/index/generator_logo.py +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/docs/assets/index/generator_map.py +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/docs/assets/inset_maps/generator.py +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/docs/assets/north_arrows/generator.py +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/docs/assets/quick/generator.py +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/docs/assets/scale_bars/generator.py +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/config.py +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/core/__init__.py +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/defaults/__init__.py +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/defaults/inset_map.py +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/defaults/north_arrow.py +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/defaults/scale_bar.py +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/scratch/map_utils.py +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/scratch/north_arrow_old_classes.py +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/utils/__init__.py +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/utils/usa.json +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/utils/usa.py +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/validation/__init__.py +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils.egg-info/dependency_links.txt +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils.egg-info/requires.txt +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils.egg-info/top_level.txt +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/setup.cfg +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/site/assets/index/generator_logo.py +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/site/assets/index/generator_map.py +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/site/assets/inset_maps/generator.py +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/site/assets/north_arrows/generator.py +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/site/assets/quick/generator.py +0 -0
- {matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/site/assets/scale_bars/generator.py +0 -0
{matplotlib_map_utils-4.1.0/matplotlib_map_utils.egg-info → matplotlib_map_utils-4.1.1}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: matplotlib-map-utils
|
|
3
|
-
Version: 4.1.
|
|
3
|
+
Version: 4.1.1
|
|
4
4
|
Summary: A suite of tools for creating maps in matplotlib
|
|
5
5
|
Author-email: David Moss <davidmoss1221@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/moss-xyz/matplotlib-map-utils/
|
|
@@ -28,7 +28,7 @@ Dynamic: license-file
|
|
|
28
28
|
|
|
29
29
|
**Feedback:** I welcome any and all feedback! See the *Development Notes* below for more details.
|
|
30
30
|
|
|
31
|
-
**Current Version:** `v4.1.
|
|
31
|
+
**Current Version:** `v4.1.1`, which fixed a a few bugs (see [here](https://moss-xyz.github.io/matplotlib-map-utils/package/#release-notes) for details!)
|
|
32
32
|
|
|
33
33
|
---
|
|
34
34
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
**Feedback:** I welcome any and all feedback! See the *Development Notes* below for more details.
|
|
10
10
|
|
|
11
|
-
**Current Version:** `v4.1.
|
|
11
|
+
**Current Version:** `v4.1.1`, which fixed a a few bugs (see [here](https://moss-xyz.github.io/matplotlib-map-utils/package/#release-notes) for details!)
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
@@ -4,11 +4,25 @@ from .core.scale_bar import ScaleBar, scale_bar, dual_bars
|
|
|
4
4
|
from .core.inset_map import InsetMap, inset_map, ExtentIndicator, indicate_extent, DetailIndicator, indicate_detail, inset_usa
|
|
5
5
|
from typing import Literal
|
|
6
6
|
|
|
7
|
+
# TypedDicts describing the config dictionaries accepted by the objects/functions above.
|
|
8
|
+
# These power editor intellisense (key + value autocomplete) and can be used by callers
|
|
9
|
+
# to annotate their own config variables; runtime validation is still handled by pydantic.
|
|
10
|
+
from .validation.scale_bar import (ScaleBarBarDict, ScaleBarLabelsDict, ScaleBarUnitsDict,
|
|
11
|
+
ScaleBarTextDict, ScaleBarAobDict)
|
|
12
|
+
from .validation.north_arrow import (NorthArrowBaseDict, NorthArrowFancyDict, NorthArrowLabelDict,
|
|
13
|
+
NorthArrowShadowDict, NorthArrowPackDict, NorthArrowAobDict,
|
|
14
|
+
NorthArrowRotationDict)
|
|
15
|
+
from .validation.inset_map import InsetMapPlotDict
|
|
16
|
+
|
|
7
17
|
# This defines what wildcard imports should import
|
|
8
|
-
__all__ = ["NorthArrow", "north_arrow",
|
|
18
|
+
__all__ = ["NorthArrow", "north_arrow",
|
|
9
19
|
"ScaleBar", "scale_bar", "dual_bars",
|
|
10
20
|
"InsetMap","inset_map", "ExtentIndicator","indicate_extent", "DetailIndicator","indicate_detail", "inset_usa",
|
|
11
|
-
"set_size"
|
|
21
|
+
"set_size",
|
|
22
|
+
"ScaleBarBarDict", "ScaleBarLabelsDict", "ScaleBarUnitsDict", "ScaleBarTextDict", "ScaleBarAobDict",
|
|
23
|
+
"NorthArrowBaseDict", "NorthArrowFancyDict", "NorthArrowLabelDict", "NorthArrowShadowDict",
|
|
24
|
+
"NorthArrowPackDict", "NorthArrowAobDict", "NorthArrowRotationDict",
|
|
25
|
+
"InsetMapPlotDict"]
|
|
12
26
|
|
|
13
27
|
from . import config
|
|
14
28
|
|
{matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/core/inset_map.py
RENAMED
|
@@ -35,12 +35,12 @@ class InsetMap(matplotlib.artist.Artist):
|
|
|
35
35
|
## INITIALIZATION ##
|
|
36
36
|
def __init__(self,
|
|
37
37
|
size: str=None,
|
|
38
|
-
location:
|
|
38
|
+
location: imt.Location="lower left",
|
|
39
39
|
imsize: Any=None,
|
|
40
40
|
pad: Any=None,
|
|
41
41
|
coords: Any=None,
|
|
42
42
|
transform=None,
|
|
43
|
-
to_plot=None,
|
|
43
|
+
to_plot: None | list[imt.InsetMapPlotDict]=None,
|
|
44
44
|
zorder: int=99,
|
|
45
45
|
**kwargs):
|
|
46
46
|
# Starting up the object with the base properties of a matplotlib Artist
|
|
@@ -199,7 +199,7 @@ class ExtentIndicator(matplotlib.artist.Artist):
|
|
|
199
199
|
|
|
200
200
|
## INITIALIZATION ##
|
|
201
201
|
def __init__(self,
|
|
202
|
-
to_return:
|
|
202
|
+
to_return: None | imt.ExtentReturn=None,
|
|
203
203
|
straighten: bool=True,
|
|
204
204
|
pad: Any=0.05,
|
|
205
205
|
plot: bool=True,
|
|
@@ -358,7 +358,7 @@ class DetailIndicator(matplotlib.artist.Artist):
|
|
|
358
358
|
|
|
359
359
|
## INITIALIZATION ##
|
|
360
360
|
def __init__(self,
|
|
361
|
-
to_return:
|
|
361
|
+
to_return: None | imt.DetailReturn=None,
|
|
362
362
|
straighten: bool=True,
|
|
363
363
|
pad: Any=0.05,
|
|
364
364
|
plot: bool=True,
|
|
@@ -544,9 +544,9 @@ class DetailIndicator(matplotlib.artist.Artist):
|
|
|
544
544
|
|
|
545
545
|
# Function for creating an inset map, independent of the InsetMap object model
|
|
546
546
|
# It is intended to be an easier-to-use API than the default inset_axes
|
|
547
|
-
def inset_map(ax,
|
|
547
|
+
def inset_map(ax,
|
|
548
548
|
size: str=None,
|
|
549
|
-
location:
|
|
549
|
+
location: imt.Location="upper right",
|
|
550
550
|
imsize: Any=None,
|
|
551
551
|
pad: Any=None,
|
|
552
552
|
coords: Any=None,
|
|
@@ -670,7 +670,7 @@ def indicate_extent(pax: matplotlib.axes.Axes,
|
|
|
670
670
|
bax: matplotlib.axes.Axes,
|
|
671
671
|
pcrs: Any,
|
|
672
672
|
bcrs: Any,
|
|
673
|
-
to_return:
|
|
673
|
+
to_return: None | imt.ExtentReturn=None,
|
|
674
674
|
straighten: bool=True,
|
|
675
675
|
pad: Any=0.05,
|
|
676
676
|
plot: bool=True,
|
|
@@ -755,11 +755,11 @@ def indicate_extent(pax: matplotlib.axes.Axes,
|
|
|
755
755
|
# This will also, call extent_indicator too, as the two are linked
|
|
756
756
|
# here, PAX means "parent axis" (where the indicator is plotted)
|
|
757
757
|
# and IAX means "inset axis" (which contains the detail/zoomed-in section)
|
|
758
|
-
def indicate_detail(pax: matplotlib.axes.Axes,
|
|
759
|
-
iax: matplotlib.axes.Axes,
|
|
760
|
-
pcrs: Any,
|
|
758
|
+
def indicate_detail(pax: matplotlib.axes.Axes,
|
|
759
|
+
iax: matplotlib.axes.Axes,
|
|
760
|
+
pcrs: Any,
|
|
761
761
|
icrs: Any,
|
|
762
|
-
to_return:
|
|
762
|
+
to_return: None | imt.DetailReturn=None,
|
|
763
763
|
straighten: bool=True,
|
|
764
764
|
pad: Any=0.05,
|
|
765
765
|
plot: bool=True,
|
{matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/core/north_arrow.py
RENAMED
|
@@ -34,11 +34,11 @@ from ..validation.shared import _del_keys
|
|
|
34
34
|
class NorthArrow(matplotlib.artist.Artist):
|
|
35
35
|
|
|
36
36
|
## INITIALIZATION ##
|
|
37
|
-
def __init__(self, size: str=None, location:
|
|
37
|
+
def __init__(self, size: str=None, location: nat.Location="upper right",
|
|
38
38
|
scale: None | float | int=None,
|
|
39
|
-
base: None | bool |
|
|
40
|
-
label: None | bool |
|
|
41
|
-
pack: None |
|
|
39
|
+
base: None | bool | nat.NorthArrowBaseDict = None, fancy: None | bool | nat.NorthArrowFancyDict = None,
|
|
40
|
+
label: None | bool | nat.NorthArrowLabelDict = None, shadow: None | bool | nat.NorthArrowShadowDict = None,
|
|
41
|
+
pack: None | nat.NorthArrowPackDict = None, aob: None | nat.NorthArrowAobDict = None, rotation: None | nat.NorthArrowRotationDict = None,
|
|
42
42
|
zorder: int=99,):
|
|
43
43
|
# Starting up the object with the base properties of a matplotlib Artist
|
|
44
44
|
matplotlib.artist.Artist.__init__(self)
|
|
@@ -231,15 +231,15 @@ class NorthArrow(matplotlib.artist.Artist):
|
|
|
231
231
|
|
|
232
232
|
# This function presents a way to draw the north arrow independent of the NorthArrow object model
|
|
233
233
|
# and is actually used by the object model when draw() is called anyways
|
|
234
|
-
def north_arrow(ax, draw=True, size: str=None, location:
|
|
234
|
+
def north_arrow(ax, draw=True, size: str=None, location: nat.Location="upper right",
|
|
235
235
|
scale: None | float | int=None,
|
|
236
|
-
base: None | bool |
|
|
237
|
-
fancy: None | bool |
|
|
238
|
-
label: None | bool |
|
|
239
|
-
shadow: None | bool |
|
|
240
|
-
pack: None |
|
|
241
|
-
aob: None |
|
|
242
|
-
rotation: None |
|
|
236
|
+
base: None | bool | nat.NorthArrowBaseDict=None,
|
|
237
|
+
fancy: None | bool | nat.NorthArrowFancyDict=None,
|
|
238
|
+
label: None | bool | nat.NorthArrowLabelDict=None,
|
|
239
|
+
shadow: None | bool | nat.NorthArrowShadowDict=None,
|
|
240
|
+
pack: None | nat.NorthArrowPackDict=None,
|
|
241
|
+
aob: None | nat.NorthArrowAobDict=None,
|
|
242
|
+
rotation: None | nat.NorthArrowRotationDict=None,
|
|
243
243
|
zorder: int=99,):
|
|
244
244
|
|
|
245
245
|
if draw==True:
|
{matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/core/scale_bar.py
RENAMED
|
@@ -35,13 +35,13 @@ from ..validation.shared import _del_keys
|
|
|
35
35
|
class ScaleBar(matplotlib.artist.Artist):
|
|
36
36
|
|
|
37
37
|
## INITIALIZATION ##
|
|
38
|
-
def __init__(self, size: str=None, style:
|
|
39
|
-
location:
|
|
40
|
-
bar: None | bool |
|
|
41
|
-
units: None | bool |
|
|
42
|
-
labels: None | bool |
|
|
43
|
-
text: None | bool |
|
|
44
|
-
aob: None | bool |
|
|
38
|
+
def __init__(self, size: str=None, style: sbt.ScaleBarStyle="boxes",
|
|
39
|
+
location: sbt.Location="upper right",
|
|
40
|
+
bar: None | bool | sbt.ScaleBarBarDict=None,
|
|
41
|
+
units: None | bool | sbt.ScaleBarUnitsDict=None,
|
|
42
|
+
labels: None | bool | sbt.ScaleBarLabelsDict=None,
|
|
43
|
+
text: None | bool | sbt.ScaleBarTextDict=None,
|
|
44
|
+
aob: None | bool | sbt.ScaleBarAobDict=None,
|
|
45
45
|
zorder: int=99,
|
|
46
46
|
):
|
|
47
47
|
# Starting up the object with the base properties of a matplotlib Artist
|
|
@@ -220,13 +220,13 @@ class ScaleBar(matplotlib.artist.Artist):
|
|
|
220
220
|
|
|
221
221
|
### DRAWING FUNCTIONS ###
|
|
222
222
|
|
|
223
|
-
def scale_bar(ax, draw=True, size: str=None, style:
|
|
224
|
-
location:
|
|
225
|
-
bar: None | bool |
|
|
226
|
-
units: None | bool |
|
|
227
|
-
labels: None | bool |
|
|
228
|
-
text: None | bool |
|
|
229
|
-
aob: None | bool |
|
|
223
|
+
def scale_bar(ax, draw=True, size: str=None, style: sbt.ScaleBarStyle="boxes",
|
|
224
|
+
location: sbt.Location="upper right",
|
|
225
|
+
bar: None | bool | sbt.ScaleBarBarDict=None,
|
|
226
|
+
units: None | bool | sbt.ScaleBarUnitsDict=None,
|
|
227
|
+
labels: None | bool | sbt.ScaleBarLabelsDict=None,
|
|
228
|
+
text: None | bool | sbt.ScaleBarTextDict=None,
|
|
229
|
+
aob: None | bool | sbt.ScaleBarAobDict=None,
|
|
230
230
|
zorder: int=99,
|
|
231
231
|
return_aob: bool=True,):
|
|
232
232
|
# For the default function mode, dispatch to the Artist class so final
|
|
@@ -301,7 +301,7 @@ def scale_bar(ax, draw=True, size: str=None, style: Literal["ticks","boxes"]="bo
|
|
|
301
301
|
segments = _config_seg(bar_max, bar_length/major_div, major_div, minor_div,
|
|
302
302
|
_bar["minor_type"], _labels["style"],
|
|
303
303
|
_labels["labels"], _labels["format"], _labels["format_int"])
|
|
304
|
-
|
|
304
|
+
|
|
305
305
|
# Also setting the segment gap to be either the edgewidth or the tickwidth
|
|
306
306
|
gap_width = _bar.get("edgewidth", _bar.get("edgewidth", 0))
|
|
307
307
|
|
|
@@ -320,7 +320,7 @@ def scale_bar(ax, draw=True, size: str=None, style: Literal["ticks","boxes"]="bo
|
|
|
320
320
|
major_height = _bar["height"]*72
|
|
321
321
|
|
|
322
322
|
# Initializing the bar with an invisible spacer, to align it with the text later
|
|
323
|
-
# if all of these conditions are met, we do not need a
|
|
323
|
+
# if all of these conditions are met, we do not need a spacer
|
|
324
324
|
if _labels["style"] == "last_only" and major_div==1 and (minor_div==1 or minor_div==0):
|
|
325
325
|
bar_artists = []
|
|
326
326
|
# If we have minor divs, it will be equal to half the minor width
|
|
@@ -516,14 +516,14 @@ def scale_bar(ax, draw=True, size: str=None, style: Literal["ticks","boxes"]="bo
|
|
|
516
516
|
# This is a convenience function for creating two scale bars, with different units, aligned with each other
|
|
517
517
|
# The bars should be identical except for the units and the divisions
|
|
518
518
|
# NOTE: still under development, will tidy up if there is usage of it
|
|
519
|
-
def dual_bars(ax, draw=True, size: str=None, style:
|
|
520
|
-
location:
|
|
519
|
+
def dual_bars(ax, draw=True, size: str=None, style: sbt.ScaleBarStyle="boxes",
|
|
520
|
+
location: sbt.Location="upper right",
|
|
521
521
|
units_dual=["mi","km"], bar_maxes=[None,None], bar_lengths=[None,None], major_divs=[None, None], minor_divs=[None, None],
|
|
522
|
-
bar: None | bool |
|
|
523
|
-
units: None | bool |
|
|
524
|
-
labels: None | bool |
|
|
525
|
-
text: None | bool |
|
|
526
|
-
aob: None | bool |
|
|
522
|
+
bar: None | bool | sbt.ScaleBarBarDict=None,
|
|
523
|
+
units: None | bool | sbt.ScaleBarUnitsDict=None,
|
|
524
|
+
labels: None | bool | sbt.ScaleBarLabelsDict=None,
|
|
525
|
+
text: None | bool | sbt.ScaleBarTextDict=None,
|
|
526
|
+
aob: None | bool | sbt.ScaleBarAobDict=None,
|
|
527
527
|
zorder: int=99,
|
|
528
528
|
pad=0, sep=0,
|
|
529
529
|
return_aob: bool=True
|
|
@@ -643,7 +643,13 @@ def _config_bar(ax, bar):
|
|
|
643
643
|
# We've done most of the work here - just need to see if we want a minor div or not
|
|
644
644
|
# If one is provided, override what we calculated above
|
|
645
645
|
if bar["minor_div"] is not None:
|
|
646
|
-
|
|
646
|
+
if bar["minor_div"] <= 1:
|
|
647
|
+
bar_minor_div = 1
|
|
648
|
+
else:
|
|
649
|
+
bar_minor_div = bar["minor_div"]
|
|
650
|
+
# Alternatively, if minor_type is "none", then we need to set to 1
|
|
651
|
+
if bar["minor_type"] == "none":
|
|
652
|
+
bar_minor_div = 1
|
|
647
653
|
|
|
648
654
|
# Returning everything
|
|
649
655
|
return bar_max, bar_length, units_label, bar_major_div, bar_minor_div
|
|
File without changes
|
|
@@ -8,17 +8,18 @@
|
|
|
8
8
|
# Geo packages
|
|
9
9
|
import matplotlib.axes
|
|
10
10
|
# Pydantic type validation
|
|
11
|
-
from typing import Annotated, Union, Tuple, List, Optional, Literal, Any, Dict
|
|
11
|
+
from typing import Annotated, Union, Tuple, List, Optional, Literal, Any, Dict, TypedDict
|
|
12
12
|
from pydantic import ConfigDict, BaseModel, Field, model_validator
|
|
13
|
-
from .shared import MatplotlibColor, CRSInput, _get_size_key
|
|
13
|
+
from .shared import MatplotlibColor, CRSInput, _get_size_key, Location, ExtentReturn, DetailReturn
|
|
14
14
|
from .. import config
|
|
15
15
|
from ..defaults import inset_map as imd
|
|
16
16
|
|
|
17
17
|
### ALL ###
|
|
18
18
|
# This code tells other packages what to import if not explicitly stated
|
|
19
19
|
__all__ = [
|
|
20
|
-
"InsetMapPlotModel", "InsetMapInsetModel",
|
|
20
|
+
"InsetMapPlotModel", "InsetMapInsetModel",
|
|
21
21
|
"InsetMapExtentModel", "InsetMapDetailModel",
|
|
22
|
+
"InsetMapPlotDict",
|
|
22
23
|
]
|
|
23
24
|
|
|
24
25
|
### COMPONENT MODELS ###
|
|
@@ -30,7 +31,7 @@ class InsetMapPlotModel(BaseModel):
|
|
|
30
31
|
|
|
31
32
|
class InsetMapInsetModel(BaseModel):
|
|
32
33
|
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
33
|
-
location:
|
|
34
|
+
location: Location
|
|
34
35
|
imsize: Optional[Union[Annotated[Union[float, int], Field(ge=0)], Tuple[Annotated[Union[float, int], Field(ge=0)], Annotated[Union[float, int], Field(ge=0)]]]] = None
|
|
35
36
|
pad: Optional[Union[Annotated[Union[float, int], Field(ge=0)], Tuple[Annotated[Union[float, int], Field(ge=0)], Annotated[Union[float, int], Field(ge=0)]]]] = None
|
|
36
37
|
coords: Optional[Tuple[Union[float, int], Union[float, int]]] = None
|
|
@@ -64,11 +65,24 @@ class InsetMapExtentModel(BaseModel):
|
|
|
64
65
|
alpha: Annotated[Union[float, int], Field(ge=0)]
|
|
65
66
|
linewidth: Annotated[Union[float, int], Field(ge=0)]
|
|
66
67
|
zorder: int
|
|
67
|
-
to_return: Optional[
|
|
68
|
+
to_return: Optional[ExtentReturn] = None
|
|
68
69
|
|
|
69
70
|
class InsetMapDetailModel(BaseModel):
|
|
70
71
|
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
71
|
-
to_return: Optional[
|
|
72
|
+
to_return: Optional[DetailReturn] = None
|
|
72
73
|
connector_color: MatplotlibColor
|
|
73
74
|
connector_width: Annotated[Union[float, int], Field(ge=0)]
|
|
74
|
-
zorder: int
|
|
75
|
+
zorder: int
|
|
76
|
+
|
|
77
|
+
### TYPED DICTS ###
|
|
78
|
+
# Inset-map objects take their settings as individual keyword arguments rather
|
|
79
|
+
# than nested config dicts, so (unlike ScaleBar/NorthArrow) there is no dict
|
|
80
|
+
# literal to complete - the enumerated kwargs are typed with the shared Literal
|
|
81
|
+
# aliases directly in core/inset_map.py. The one place a dict literal IS passed
|
|
82
|
+
# is each element of `to_plot`, so we expose a TypedDict for that shape. It is
|
|
83
|
+
# never validated at runtime (InsetMapPlotModel does that); it exists only so
|
|
84
|
+
# `to_plot=[{"data": ..., "kwargs": ...}]` autocompletes its keys.
|
|
85
|
+
|
|
86
|
+
class InsetMapPlotDict(TypedDict, total=False):
|
|
87
|
+
data: Any
|
|
88
|
+
kwargs: dict
|
|
@@ -8,24 +8,28 @@
|
|
|
8
8
|
# Default packages
|
|
9
9
|
import warnings
|
|
10
10
|
# The types we use in this script
|
|
11
|
-
from typing import Annotated, Union, Tuple, Optional, Literal, Any
|
|
11
|
+
from typing import Annotated, Union, Tuple, Optional, Literal, Any, TypedDict
|
|
12
12
|
# Pydantic type validation
|
|
13
13
|
from pydantic import ConfigDict, BaseModel, Field, BeforeValidator, model_validator
|
|
14
|
-
from .shared import MatplotlibColor, Numpy2DArray, MatplotlibFontsize, CRSInput, _get_size_key
|
|
14
|
+
from .shared import (MatplotlibColor, Numpy2DArray, MatplotlibFontsize, CRSInput, _get_size_key,
|
|
15
|
+
Location, LabelPosition, HAlign, VAlign, FontFamily, FontStyle, FontWeight,
|
|
16
|
+
PackAlign, PackMode, RotationReference)
|
|
15
17
|
from .. import config
|
|
16
18
|
from ..defaults import north_arrow as nad
|
|
17
19
|
|
|
18
20
|
### ALL ###
|
|
19
21
|
# This code tells other packages what to import if not explicitly stated
|
|
20
22
|
__all__ = [
|
|
21
|
-
"NorthArrowPrimaryModel", "NorthArrowBaseModel", "NorthArrowFancyModel",
|
|
22
|
-
"NorthArrowLabelModel", "NorthArrowShadowModel", "NorthArrowPackModel",
|
|
23
|
-
"NorthArrowAobModel", "NorthArrowRotationModel"
|
|
23
|
+
"NorthArrowPrimaryModel", "NorthArrowBaseModel", "NorthArrowFancyModel",
|
|
24
|
+
"NorthArrowLabelModel", "NorthArrowShadowModel", "NorthArrowPackModel",
|
|
25
|
+
"NorthArrowAobModel", "NorthArrowRotationModel",
|
|
26
|
+
"NorthArrowBaseDict", "NorthArrowFancyDict", "NorthArrowLabelDict", "NorthArrowShadowDict",
|
|
27
|
+
"NorthArrowPackDict", "NorthArrowAobDict", "NorthArrowRotationDict"
|
|
24
28
|
]
|
|
25
29
|
|
|
26
30
|
### COMPONENT MODELS ###
|
|
27
31
|
class NorthArrowPrimaryModel(BaseModel):
|
|
28
|
-
location:
|
|
32
|
+
location: Location
|
|
29
33
|
scale: Annotated[Optional[Union[float, int]], Field(ge=0)] = None
|
|
30
34
|
zorder: int
|
|
31
35
|
|
|
@@ -74,14 +78,14 @@ class NorthArrowFancyModel(BaseModel):
|
|
|
74
78
|
class NorthArrowLabelModel(BaseModel):
|
|
75
79
|
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
76
80
|
text: str
|
|
77
|
-
position:
|
|
78
|
-
ha:
|
|
79
|
-
va:
|
|
81
|
+
position: LabelPosition
|
|
82
|
+
ha: HAlign
|
|
83
|
+
va: VAlign
|
|
80
84
|
fontsize: MatplotlibFontsize
|
|
81
|
-
fontfamily:
|
|
82
|
-
fontstyle:
|
|
85
|
+
fontfamily: FontFamily
|
|
86
|
+
fontstyle: FontStyle
|
|
83
87
|
color: MatplotlibColor
|
|
84
|
-
fontweight:
|
|
88
|
+
fontweight: FontWeight
|
|
85
89
|
stroke_width: Annotated[Union[float, int], Field(ge=0)]
|
|
86
90
|
stroke_color: MatplotlibColor
|
|
87
91
|
rotation: Annotated[Union[float, int], Field(ge=-360, le=360)]
|
|
@@ -112,11 +116,11 @@ class NorthArrowShadowModel(BaseModel):
|
|
|
112
116
|
|
|
113
117
|
class NorthArrowPackModel(BaseModel):
|
|
114
118
|
sep: Annotated[Union[float, int], Field(ge=0)]
|
|
115
|
-
align:
|
|
119
|
+
align: PackAlign
|
|
116
120
|
pad: Annotated[Union[float, int], Field(ge=0)]
|
|
117
121
|
width: Annotated[Optional[Union[float, int]], Field(ge=0)] = None
|
|
118
122
|
height: Annotated[Optional[Union[float, int]], Field(ge=0)] = None
|
|
119
|
-
mode:
|
|
123
|
+
mode: PackMode
|
|
120
124
|
|
|
121
125
|
@model_validator(mode='before')
|
|
122
126
|
@classmethod
|
|
@@ -151,7 +155,7 @@ class NorthArrowRotationModel(BaseModel):
|
|
|
151
155
|
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
152
156
|
degrees: Annotated[Optional[Union[float, int]], Field(ge=-360, le=360)] = None
|
|
153
157
|
crs: Optional[CRSInput] = None
|
|
154
|
-
reference: Optional[
|
|
158
|
+
reference: Optional[RotationReference] = None
|
|
155
159
|
coords: Optional[Tuple[Union[float, int], Union[float, int]]] = None
|
|
156
160
|
|
|
157
161
|
@model_validator(mode='before')
|
|
@@ -174,4 +178,69 @@ class NorthArrowRotationModel(BaseModel):
|
|
|
174
178
|
raise ValueError("If degrees is None, crs, reference, and coords cannot be None: please provide a valid input for each of these variables instead")
|
|
175
179
|
elif isinstance(self.degrees, (int, float)) and (self.crs is not None or self.reference is not None or self.coords is not None):
|
|
176
180
|
warnings.warn("A value for degrees was supplied; values for crs, reference, and coords will be ignored")
|
|
177
|
-
return self
|
|
181
|
+
return self
|
|
182
|
+
|
|
183
|
+
### TYPED DICTS ###
|
|
184
|
+
# These mirror the user-facing fields of the models above, purely for editor
|
|
185
|
+
# intellisense (key + value autocomplete inside dict literals). They are never
|
|
186
|
+
# instantiated or validated at runtime - the plain dicts users pass still flow
|
|
187
|
+
# through the pydantic models above. total=False marks every key optional, since
|
|
188
|
+
# users supply partial configs. Literal-typed fields reuse the shared aliases so
|
|
189
|
+
# their allowed values stay in lockstep with the models.
|
|
190
|
+
|
|
191
|
+
class NorthArrowBaseDict(TypedDict, total=False):
|
|
192
|
+
coords: Any
|
|
193
|
+
facecolor: Any
|
|
194
|
+
edgecolor: Any
|
|
195
|
+
linewidth: float | int
|
|
196
|
+
zorder: int
|
|
197
|
+
|
|
198
|
+
class NorthArrowFancyDict(TypedDict, total=False):
|
|
199
|
+
coords: Any
|
|
200
|
+
facecolor: Any
|
|
201
|
+
zorder: int
|
|
202
|
+
|
|
203
|
+
class NorthArrowLabelDict(TypedDict, total=False):
|
|
204
|
+
text: str
|
|
205
|
+
position: LabelPosition
|
|
206
|
+
ha: HAlign
|
|
207
|
+
va: VAlign
|
|
208
|
+
fontsize: float | int | str
|
|
209
|
+
fontfamily: FontFamily
|
|
210
|
+
fontstyle: FontStyle
|
|
211
|
+
color: Any
|
|
212
|
+
fontweight: FontWeight
|
|
213
|
+
stroke_width: float | int
|
|
214
|
+
stroke_color: Any
|
|
215
|
+
rotation: float | int
|
|
216
|
+
zorder: int
|
|
217
|
+
|
|
218
|
+
class NorthArrowShadowDict(TypedDict, total=False):
|
|
219
|
+
offset: tuple
|
|
220
|
+
alpha: float | int
|
|
221
|
+
shadow_rgbFace: Any
|
|
222
|
+
|
|
223
|
+
class NorthArrowPackDict(TypedDict, total=False):
|
|
224
|
+
sep: float | int
|
|
225
|
+
align: PackAlign
|
|
226
|
+
pad: float | int
|
|
227
|
+
width: float | int
|
|
228
|
+
height: float | int
|
|
229
|
+
mode: PackMode
|
|
230
|
+
|
|
231
|
+
class NorthArrowAobDict(TypedDict, total=False):
|
|
232
|
+
facecolor: Any
|
|
233
|
+
edgecolor: Any
|
|
234
|
+
alpha: float | int
|
|
235
|
+
pad: float | int
|
|
236
|
+
borderpad: float | int
|
|
237
|
+
prop: float | int | str
|
|
238
|
+
frameon: bool
|
|
239
|
+
bbox_to_anchor: Any
|
|
240
|
+
bbox_transform: Any
|
|
241
|
+
|
|
242
|
+
class NorthArrowRotationDict(TypedDict, total=False):
|
|
243
|
+
degrees: float | int
|
|
244
|
+
crs: Any
|
|
245
|
+
reference: RotationReference
|
|
246
|
+
coords: Any
|
|
@@ -6,9 +6,11 @@
|
|
|
6
6
|
### IMPORTING PACKAGES ###
|
|
7
7
|
|
|
8
8
|
# Pydantic type validation
|
|
9
|
-
from typing import Annotated, Union, Tuple, List, Optional, Literal, Any
|
|
9
|
+
from typing import Annotated, Union, Tuple, List, Optional, Literal, Any, TypedDict
|
|
10
10
|
from pydantic import ConfigDict, BaseModel, Field, BeforeValidator, model_validator
|
|
11
|
-
from .shared import MatplotlibColor, MatplotlibFontsize, CRSInput, _validate_crs_input, _get_size_key
|
|
11
|
+
from .shared import (MatplotlibColor, MatplotlibFontsize, CRSInput, _validate_crs_input, _get_size_key,
|
|
12
|
+
ScaleBarStyle, Location, BarUnit, MinorType, TickLoc, LabelStyle, LabelsLoc, UnitsLoc,
|
|
13
|
+
FontFamily, FontStyle, FontWeight, RotationMode)
|
|
12
14
|
from .. import config
|
|
13
15
|
from ..defaults import scale_bar as sbd
|
|
14
16
|
|
|
@@ -16,7 +18,8 @@ from ..defaults import scale_bar as sbd
|
|
|
16
18
|
# This code tells other packages what to import if not explicitly stated
|
|
17
19
|
__all__ = [
|
|
18
20
|
"preferred_divs", "convert_dict", "units_standard",
|
|
19
|
-
"ScaleBarPrimaryModel", "ScaleBarBarModel", "ScaleBarLabelsModel", "ScaleBarUnitsModel", "ScaleBarTextModel", "ScaleBarAobModel"
|
|
21
|
+
"ScaleBarPrimaryModel", "ScaleBarBarModel", "ScaleBarLabelsModel", "ScaleBarUnitsModel", "ScaleBarTextModel", "ScaleBarAobModel",
|
|
22
|
+
"ScaleBarBarDict", "ScaleBarLabelsDict", "ScaleBarUnitsDict", "ScaleBarTextDict", "ScaleBarAobDict"
|
|
20
23
|
]
|
|
21
24
|
|
|
22
25
|
### CONSTANTS ###
|
|
@@ -73,8 +76,8 @@ units_standard = {
|
|
|
73
76
|
### COMPONENT MODELS ###
|
|
74
77
|
|
|
75
78
|
class ScaleBarPrimaryModel(BaseModel):
|
|
76
|
-
style:
|
|
77
|
-
location:
|
|
79
|
+
style: ScaleBarStyle
|
|
80
|
+
location: Location
|
|
78
81
|
zorder: int
|
|
79
82
|
|
|
80
83
|
def _validate_scalebar_projection(v):
|
|
@@ -87,7 +90,7 @@ ScaleBarProjection = Annotated[Any, BeforeValidator(_validate_scalebar_projectio
|
|
|
87
90
|
class ScaleBarBarModel(BaseModel):
|
|
88
91
|
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
89
92
|
projection: ScaleBarProjection
|
|
90
|
-
unit: Optional[
|
|
93
|
+
unit: Optional[BarUnit] = None
|
|
91
94
|
rotation: Annotated[Optional[Union[float, int]], Field(ge=-360, le=360)] = None
|
|
92
95
|
max: Annotated[Optional[Union[float, int]], Field(ge=0)] = None
|
|
93
96
|
length: Annotated[Optional[Union[float, int]], Field(ge=0)] = None
|
|
@@ -96,12 +99,12 @@ class ScaleBarBarModel(BaseModel):
|
|
|
96
99
|
major_div: Annotated[Optional[int], Field(ge=1)] = None
|
|
97
100
|
minor_div: Annotated[Optional[int], Field(ge=0)] = None
|
|
98
101
|
minor_frac: Annotated[Optional[Union[float, int]], Field(ge=0, le=1)] = None
|
|
99
|
-
minor_type: Optional[
|
|
102
|
+
minor_type: Optional[MinorType] = None
|
|
100
103
|
major_mult: Annotated[Optional[Union[float, int]], Field(ge=0)] = None
|
|
101
104
|
facecolors: Optional[Union[MatplotlibColor, List[MatplotlibColor], Tuple[MatplotlibColor, ...]]] = None
|
|
102
105
|
edgecolors: Optional[Union[MatplotlibColor, List[MatplotlibColor], Tuple[MatplotlibColor, ...]]] = None
|
|
103
106
|
edgewidth: Annotated[Optional[Union[float, int]], Field(ge=0)] = None
|
|
104
|
-
tick_loc: Optional[
|
|
107
|
+
tick_loc: Optional[TickLoc] = None
|
|
105
108
|
basecolors: Optional[Union[MatplotlibColor, List[MatplotlibColor], Tuple[MatplotlibColor, ...]]] = None
|
|
106
109
|
tickcolors: Optional[Union[MatplotlibColor, List[MatplotlibColor], Tuple[MatplotlibColor, ...]]] = None
|
|
107
110
|
tickwidth: Annotated[Optional[Union[float, int]], Field(ge=0)] = None
|
|
@@ -125,17 +128,17 @@ class ScaleBarLabelsModel(BaseModel):
|
|
|
125
128
|
labels: Optional[Union[List[Any], Tuple[Any, ...]]] = None
|
|
126
129
|
format: str
|
|
127
130
|
format_int: bool
|
|
128
|
-
style:
|
|
129
|
-
loc: Optional[
|
|
131
|
+
style: LabelStyle
|
|
132
|
+
loc: Optional[LabelsLoc] = None
|
|
130
133
|
fontsize: Optional[MatplotlibFontsize] = None
|
|
131
134
|
textcolors: Optional[Union[MatplotlibColor, List[MatplotlibColor], Tuple[MatplotlibColor, ...]]] = None
|
|
132
|
-
fontfamily: Optional[
|
|
133
|
-
fontstyle: Optional[
|
|
134
|
-
fontweight: Optional[
|
|
135
|
+
fontfamily: Optional[FontFamily] = None
|
|
136
|
+
fontstyle: Optional[FontStyle] = None
|
|
137
|
+
fontweight: Optional[FontWeight] = None
|
|
135
138
|
stroke_width: Annotated[Optional[Union[float, int]], Field(ge=0)] = None
|
|
136
139
|
stroke_color: Optional[MatplotlibColor] = None
|
|
137
140
|
rotation: Annotated[Optional[Union[float, int]], Field(ge=-360, le=360)] = None
|
|
138
|
-
rotation_mode: Optional[
|
|
141
|
+
rotation_mode: Optional[RotationMode] = None
|
|
139
142
|
sep: Annotated[Union[float, int], Field(ge=0)]
|
|
140
143
|
pad: Annotated[Union[float, int], Field(ge=0)]
|
|
141
144
|
|
|
@@ -163,16 +166,16 @@ class ScaleBarLabelsModel(BaseModel):
|
|
|
163
166
|
class ScaleBarUnitsModel(BaseModel):
|
|
164
167
|
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
165
168
|
label: Optional[str] = None
|
|
166
|
-
loc: Optional[
|
|
169
|
+
loc: Optional[UnitsLoc] = None
|
|
167
170
|
fontsize: Optional[MatplotlibFontsize] = None
|
|
168
171
|
textcolor: Optional[MatplotlibColor] = None
|
|
169
|
-
fontfamily: Optional[
|
|
170
|
-
fontstyle: Optional[
|
|
171
|
-
fontweight: Optional[
|
|
172
|
+
fontfamily: Optional[FontFamily] = None
|
|
173
|
+
fontstyle: Optional[FontStyle] = None
|
|
174
|
+
fontweight: Optional[FontWeight] = None
|
|
172
175
|
stroke_width: Annotated[Optional[Union[float, int]], Field(ge=0)] = None
|
|
173
176
|
stroke_color: Optional[MatplotlibColor] = None
|
|
174
177
|
rotation: Annotated[Optional[Union[float, int]], Field(ge=-360, le=360)] = None
|
|
175
|
-
rotation_mode: Optional[
|
|
178
|
+
rotation_mode: Optional[RotationMode] = None
|
|
176
179
|
sep: Annotated[Union[float, int], Field(ge=0)]
|
|
177
180
|
pad: Annotated[Union[float, int], Field(ge=0)]
|
|
178
181
|
|
|
@@ -198,13 +201,13 @@ class ScaleBarTextModel(BaseModel):
|
|
|
198
201
|
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
199
202
|
fontsize: MatplotlibFontsize
|
|
200
203
|
textcolor: Union[MatplotlibColor, List[MatplotlibColor], Tuple[MatplotlibColor, ...]]
|
|
201
|
-
fontfamily:
|
|
202
|
-
fontstyle:
|
|
203
|
-
fontweight:
|
|
204
|
+
fontfamily: FontFamily
|
|
205
|
+
fontstyle: FontStyle
|
|
206
|
+
fontweight: FontWeight
|
|
204
207
|
stroke_width: Annotated[Union[float, int], Field(ge=0)]
|
|
205
208
|
stroke_color: MatplotlibColor
|
|
206
209
|
rotation: Annotated[Optional[Union[float, int]], Field(ge=-360, le=360)] = None
|
|
207
|
-
rotation_mode: Optional[
|
|
210
|
+
rotation_mode: Optional[RotationMode] = None
|
|
208
211
|
|
|
209
212
|
@model_validator(mode='before')
|
|
210
213
|
@classmethod
|
|
@@ -235,3 +238,92 @@ class ScaleBarAobModel(BaseModel):
|
|
|
235
238
|
size = data.pop('size', config.DEFAULT_SIZE)
|
|
236
239
|
defaults = sbd._DEFAULTS_SB[_get_size_key(size)][4]
|
|
237
240
|
return defaults | data
|
|
241
|
+
|
|
242
|
+
### TYPED DICTS ###
|
|
243
|
+
# These mirror the user-facing fields of the models above, purely for editor
|
|
244
|
+
# intellisense (key + value autocomplete inside dict literals). They are never
|
|
245
|
+
# instantiated or validated at runtime - the plain dicts users pass still flow
|
|
246
|
+
# through the pydantic models above. total=False marks every key optional, since
|
|
247
|
+
# users supply partial configs. Literal-typed fields reuse the shared aliases so
|
|
248
|
+
# their allowed values stay in lockstep with the models.
|
|
249
|
+
|
|
250
|
+
class ScaleBarBarDict(TypedDict, total=False):
|
|
251
|
+
projection: Any
|
|
252
|
+
unit: BarUnit
|
|
253
|
+
rotation: float | int
|
|
254
|
+
max: float | int
|
|
255
|
+
length: float | int
|
|
256
|
+
height: float | int
|
|
257
|
+
reverse: bool
|
|
258
|
+
major_div: int
|
|
259
|
+
minor_div: int
|
|
260
|
+
minor_frac: float | int
|
|
261
|
+
minor_type: MinorType
|
|
262
|
+
major_mult: float | int
|
|
263
|
+
facecolors: Any
|
|
264
|
+
edgecolors: Any
|
|
265
|
+
edgewidth: float | int
|
|
266
|
+
tick_loc: TickLoc
|
|
267
|
+
basecolors: Any
|
|
268
|
+
tickcolors: Any
|
|
269
|
+
tickwidth: float | int
|
|
270
|
+
interpolation: str
|
|
271
|
+
dpi_cor: bool
|
|
272
|
+
resample: bool
|
|
273
|
+
raster_dpi: float | int
|
|
274
|
+
raster_dpi_scale: float | int
|
|
275
|
+
|
|
276
|
+
class ScaleBarLabelsDict(TypedDict, total=False):
|
|
277
|
+
labels: list | tuple
|
|
278
|
+
format: str
|
|
279
|
+
format_int: bool
|
|
280
|
+
style: LabelStyle
|
|
281
|
+
loc: LabelsLoc
|
|
282
|
+
fontsize: float | int | str
|
|
283
|
+
textcolors: Any
|
|
284
|
+
fontfamily: FontFamily
|
|
285
|
+
fontstyle: FontStyle
|
|
286
|
+
fontweight: FontWeight
|
|
287
|
+
stroke_width: float | int
|
|
288
|
+
stroke_color: Any
|
|
289
|
+
rotation: float | int
|
|
290
|
+
rotation_mode: RotationMode
|
|
291
|
+
sep: float | int
|
|
292
|
+
pad: float | int
|
|
293
|
+
|
|
294
|
+
class ScaleBarUnitsDict(TypedDict, total=False):
|
|
295
|
+
label: str
|
|
296
|
+
loc: UnitsLoc
|
|
297
|
+
fontsize: float | int | str
|
|
298
|
+
textcolor: Any
|
|
299
|
+
fontfamily: FontFamily
|
|
300
|
+
fontstyle: FontStyle
|
|
301
|
+
fontweight: FontWeight
|
|
302
|
+
stroke_width: float | int
|
|
303
|
+
stroke_color: Any
|
|
304
|
+
rotation: float | int
|
|
305
|
+
rotation_mode: RotationMode
|
|
306
|
+
sep: float | int
|
|
307
|
+
pad: float | int
|
|
308
|
+
|
|
309
|
+
class ScaleBarTextDict(TypedDict, total=False):
|
|
310
|
+
fontsize: float | int | str
|
|
311
|
+
textcolor: Any
|
|
312
|
+
fontfamily: FontFamily
|
|
313
|
+
fontstyle: FontStyle
|
|
314
|
+
fontweight: FontWeight
|
|
315
|
+
stroke_width: float | int
|
|
316
|
+
stroke_color: Any
|
|
317
|
+
rotation: float | int
|
|
318
|
+
rotation_mode: RotationMode
|
|
319
|
+
|
|
320
|
+
class ScaleBarAobDict(TypedDict, total=False):
|
|
321
|
+
facecolor: Any
|
|
322
|
+
edgecolor: Any
|
|
323
|
+
alpha: float | int
|
|
324
|
+
pad: float | int
|
|
325
|
+
borderpad: float | int
|
|
326
|
+
prop: float | int | str
|
|
327
|
+
frameon: bool
|
|
328
|
+
bbox_to_anchor: Any
|
|
329
|
+
bbox_transform: Any
|
{matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/validation/shared.py
RENAMED
|
@@ -6,9 +6,44 @@
|
|
|
6
6
|
import numpy
|
|
7
7
|
import pyproj
|
|
8
8
|
import matplotlib.rcsetup
|
|
9
|
-
from typing import Annotated, Any
|
|
9
|
+
from typing import Annotated, Any, Literal
|
|
10
10
|
from pydantic import BeforeValidator
|
|
11
11
|
|
|
12
|
+
### SHARED LITERAL ALIASES ###
|
|
13
|
+
# These name the enumerated value-sets used across the validation models.
|
|
14
|
+
# They are referenced by BOTH the pydantic models (for runtime validation) and
|
|
15
|
+
# the TypedDicts (for editor intellisense), so the allowed values can never drift
|
|
16
|
+
# between the two representations.
|
|
17
|
+
|
|
18
|
+
# Shared across components
|
|
19
|
+
Location = Literal["upper right", "upper left", "lower left", "lower right",
|
|
20
|
+
"center left", "center right", "lower center", "upper center", "center"]
|
|
21
|
+
FontFamily = Literal["serif", "sans-serif", "cursive", "fantasy", "monospace"]
|
|
22
|
+
FontStyle = Literal["normal", "italic", "oblique"]
|
|
23
|
+
FontWeight = Literal["normal", "bold", "heavy", "light", "ultrabold", "ultralight"]
|
|
24
|
+
RotationMode = Literal["anchor", "default"]
|
|
25
|
+
|
|
26
|
+
# scale_bar-specific
|
|
27
|
+
ScaleBarStyle = Literal["ticks", "boxes"]
|
|
28
|
+
BarUnit = Literal["m", "km", "ft", "yd", "mi", "nmi"]
|
|
29
|
+
MinorType = Literal["all", "first", "none"]
|
|
30
|
+
TickLoc = Literal["above", "below", "middle"]
|
|
31
|
+
LabelStyle = Literal["major", "first_last", "last_only", "minor_all", "minor_first"]
|
|
32
|
+
LabelsLoc = Literal["above", "below"]
|
|
33
|
+
UnitsLoc = Literal["bar", "text", "opposite"]
|
|
34
|
+
|
|
35
|
+
# north_arrow-specific
|
|
36
|
+
LabelPosition = Literal["top", "bottom", "left", "right"]
|
|
37
|
+
HAlign = Literal["left", "center", "right"]
|
|
38
|
+
VAlign = Literal["baseline", "bottom", "center", "center_baseline", "top"]
|
|
39
|
+
PackAlign = Literal["top", "bottom", "left", "right", "center", "baseline"]
|
|
40
|
+
PackMode = Literal["fixed", "expand", "equal"]
|
|
41
|
+
RotationReference = Literal["axis", "data", "center"]
|
|
42
|
+
|
|
43
|
+
# inset_map-specific
|
|
44
|
+
ExtentReturn = Literal["shape", "patch", "fig", "ax"]
|
|
45
|
+
DetailReturn = Literal["connectors", "lines"]
|
|
46
|
+
|
|
12
47
|
def _validate_color(v):
|
|
13
48
|
if v is None:
|
|
14
49
|
return v
|
{matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1/matplotlib_map_utils.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: matplotlib-map-utils
|
|
3
|
-
Version: 4.1.
|
|
3
|
+
Version: 4.1.1
|
|
4
4
|
Summary: A suite of tools for creating maps in matplotlib
|
|
5
5
|
Author-email: David Moss <davidmoss1221@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/moss-xyz/matplotlib-map-utils/
|
|
@@ -28,7 +28,7 @@ Dynamic: license-file
|
|
|
28
28
|
|
|
29
29
|
**Feedback:** I welcome any and all feedback! See the *Development Notes* below for more details.
|
|
30
30
|
|
|
31
|
-
**Current Version:** `v4.1.
|
|
31
|
+
**Current Version:** `v4.1.1`, which fixed a a few bugs (see [here](https://moss-xyz.github.io/matplotlib-map-utils/package/#release-notes) for details!)
|
|
32
32
|
|
|
33
33
|
---
|
|
34
34
|
|
{matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils.egg-info/SOURCES.txt
RENAMED
|
@@ -9,6 +9,7 @@ docs/assets/quick/generator.py
|
|
|
9
9
|
docs/assets/scale_bars/generator.py
|
|
10
10
|
matplotlib_map_utils/__init__.py
|
|
11
11
|
matplotlib_map_utils/config.py
|
|
12
|
+
matplotlib_map_utils/py.typed
|
|
12
13
|
matplotlib_map_utils.egg-info/PKG-INFO
|
|
13
14
|
matplotlib_map_utils.egg-info/SOURCES.txt
|
|
14
15
|
matplotlib_map_utils.egg-info/dependency_links.txt
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "matplotlib-map-utils"
|
|
7
|
-
version = "4.1.
|
|
7
|
+
version = "4.1.1"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name="David Moss", email="davidmoss1221@gmail.com" },
|
|
10
10
|
]
|
|
@@ -29,6 +29,7 @@ exclude = ["matplotlib_map_utils.scratch*", "site*", "docs*"]
|
|
|
29
29
|
|
|
30
30
|
[tool.setuptools.package-data]
|
|
31
31
|
"matplotlib_map_utils.utils" = ["*.json"]
|
|
32
|
+
"matplotlib_map_utils" = ["py.typed"]
|
|
32
33
|
|
|
33
34
|
[dependency-groups]
|
|
34
35
|
dev = [
|
|
@@ -37,6 +38,7 @@ dev = [
|
|
|
37
38
|
"ipykernel>=6.30.1",
|
|
38
39
|
"jupyter>=1.1.1",
|
|
39
40
|
"mapclassify>=2.8.1",
|
|
41
|
+
"marimo>=0.23.10",
|
|
40
42
|
"matplotlib>=3.10.7",
|
|
41
43
|
"notebook>=7.4.7",
|
|
42
44
|
"pip>=25.2",
|
|
File without changes
|
{matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/docs/assets/index/generator_logo.py
RENAMED
|
File without changes
|
{matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/docs/assets/index/generator_map.py
RENAMED
|
File without changes
|
{matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/docs/assets/inset_maps/generator.py
RENAMED
|
File without changes
|
{matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/docs/assets/north_arrows/generator.py
RENAMED
|
File without changes
|
|
File without changes
|
{matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/docs/assets/scale_bars/generator.py
RENAMED
|
File without changes
|
|
File without changes
|
{matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/core/__init__.py
RENAMED
|
File without changes
|
{matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/defaults/__init__.py
RENAMED
|
File without changes
|
{matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/defaults/inset_map.py
RENAMED
|
File without changes
|
|
File without changes
|
{matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/defaults/scale_bar.py
RENAMED
|
File without changes
|
{matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/scratch/map_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
{matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/utils/__init__.py
RENAMED
|
File without changes
|
{matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils/utils/usa.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/matplotlib_map_utils.egg-info/requires.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/site/assets/index/generator_logo.py
RENAMED
|
File without changes
|
{matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/site/assets/index/generator_map.py
RENAMED
|
File without changes
|
{matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/site/assets/inset_maps/generator.py
RENAMED
|
File without changes
|
{matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/site/assets/north_arrows/generator.py
RENAMED
|
File without changes
|
|
File without changes
|
{matplotlib_map_utils-4.1.0 → matplotlib_map_utils-4.1.1}/site/assets/scale_bars/generator.py
RENAMED
|
File without changes
|