matplotlib-map-utils 2.0.0__tar.gz → 2.0.2__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.
Files changed (23) hide show
  1. {matplotlib_map_utils-2.0.0 → matplotlib_map_utils-2.0.2}/PKG-INFO +12 -6
  2. {matplotlib_map_utils-2.0.0 → matplotlib_map_utils-2.0.2}/README.md +9 -3
  3. {matplotlib_map_utils-2.0.0 → matplotlib_map_utils-2.0.2}/matplotlib_map_utils/core/scale_bar.py +50 -30
  4. {matplotlib_map_utils-2.0.0 → matplotlib_map_utils-2.0.2}/matplotlib_map_utils.egg-info/PKG-INFO +12 -6
  5. {matplotlib_map_utils-2.0.0 → matplotlib_map_utils-2.0.2}/pyproject.toml +2 -2
  6. {matplotlib_map_utils-2.0.0 → matplotlib_map_utils-2.0.2}/LICENSE +0 -0
  7. {matplotlib_map_utils-2.0.0 → matplotlib_map_utils-2.0.2}/matplotlib_map_utils/__init__.py +0 -0
  8. {matplotlib_map_utils-2.0.0 → matplotlib_map_utils-2.0.2}/matplotlib_map_utils/core/__init__.py +0 -0
  9. {matplotlib_map_utils-2.0.0 → matplotlib_map_utils-2.0.2}/matplotlib_map_utils/core/north_arrow.py +0 -0
  10. {matplotlib_map_utils-2.0.0 → matplotlib_map_utils-2.0.2}/matplotlib_map_utils/defaults/__init__.py +0 -0
  11. {matplotlib_map_utils-2.0.0 → matplotlib_map_utils-2.0.2}/matplotlib_map_utils/defaults/north_arrow.py +0 -0
  12. {matplotlib_map_utils-2.0.0 → matplotlib_map_utils-2.0.2}/matplotlib_map_utils/defaults/scale_bar.py +0 -0
  13. {matplotlib_map_utils-2.0.0 → matplotlib_map_utils-2.0.2}/matplotlib_map_utils/scratch/map_utils.py +0 -0
  14. {matplotlib_map_utils-2.0.0 → matplotlib_map_utils-2.0.2}/matplotlib_map_utils/scratch/north_arrow_old_classes.py +0 -0
  15. {matplotlib_map_utils-2.0.0 → matplotlib_map_utils-2.0.2}/matplotlib_map_utils/validation/__init__.py +0 -0
  16. {matplotlib_map_utils-2.0.0 → matplotlib_map_utils-2.0.2}/matplotlib_map_utils/validation/functions.py +0 -0
  17. {matplotlib_map_utils-2.0.0 → matplotlib_map_utils-2.0.2}/matplotlib_map_utils/validation/north_arrow.py +0 -0
  18. {matplotlib_map_utils-2.0.0 → matplotlib_map_utils-2.0.2}/matplotlib_map_utils/validation/scale_bar.py +0 -0
  19. {matplotlib_map_utils-2.0.0 → matplotlib_map_utils-2.0.2}/matplotlib_map_utils.egg-info/SOURCES.txt +0 -0
  20. {matplotlib_map_utils-2.0.0 → matplotlib_map_utils-2.0.2}/matplotlib_map_utils.egg-info/dependency_links.txt +0 -0
  21. {matplotlib_map_utils-2.0.0 → matplotlib_map_utils-2.0.2}/matplotlib_map_utils.egg-info/requires.txt +0 -0
  22. {matplotlib_map_utils-2.0.0 → matplotlib_map_utils-2.0.2}/matplotlib_map_utils.egg-info/top_level.txt +0 -0
  23. {matplotlib_map_utils-2.0.0 → matplotlib_map_utils-2.0.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: matplotlib-map-utils
3
- Version: 2.0.0
3
+ Version: 2.0.2
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/
@@ -8,7 +8,7 @@ Project-URL: Bug Tracker, https://github.com/moss-xyz/matplotlib-map-utils/issue
8
8
  Classifier: Programming Language :: Python :: 3
9
9
  Classifier: License :: OSI Approved :: GNU General Public License (GPL)
10
10
  Classifier: Operating System :: OS Independent
11
- Requires-Python: >=3.9
11
+ Requires-Python: >=3.10
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
14
  Requires-Dist: matplotlib>=3.9.0
@@ -49,11 +49,11 @@ pip install matplotlib-map-utils
49
49
 
50
50
  The requirements for this package are:
51
51
 
52
- * `python >= 3.9.0` (due to the dictionary-concatenation method utilized)
52
+ * `python >= 3.10` (due to the use of the pipe operator to concatenate dictionaries and types)
53
53
 
54
- * `matplotlib >= 3.9.0` (might work with lower versions but not guaranteed)
54
+ * `matplotlib >= 3.9` (might work with lower versions but not guaranteed)
55
55
 
56
- * `cartopy >= 0.23.0` (due to earlier bug with calling `copy()` on `CRS` objects)
56
+ * `cartopy >= 0.23` (due to earlier bug with calling `copy()` on `CRS` objects)
57
57
 
58
58
  ---
59
59
 
@@ -242,6 +242,12 @@ Two more projects assisted with the creation of this script:
242
242
 
243
243
  * [`Cartopy`](https://github.com/SciTools/cartopy/issues/2361) fixed an issue inherent to calling `.copy()` on `CRS` objects.
244
244
 
245
+ #### Releases
246
+
247
+ - `v2.0.1`: Fixed a bug in the `dual_bars()` function that prevented empty dictionaries to be passed. Also added a warning when auto-calculated bar widths appear to be exceeding the dimension of the axis (usually occurs when the axis is <2 kilometeres or miles long, depending on the units selected).
248
+
249
+ - `v2.0.2`: Changed f-string formatting to alternate double and single quotes, so as to maintain compatibility with versions of Python before 3.12 (see [here](https://github.com/moss-xyz/matplotlib-map-utils/issues/3)). However, this did reveal that another aspect of the code, namely concatenating `type` in function arguments, requires 3.10, and so the minimum python version was incremented.
250
+
245
251
  #### Future Roadmap
246
252
 
247
253
  With the release of `v2.x`, and the addition of **Scale Bar** tools, this project has achieved the two main objectives that I set out to.
@@ -32,11 +32,11 @@ pip install matplotlib-map-utils
32
32
 
33
33
  The requirements for this package are:
34
34
 
35
- * `python >= 3.9.0` (due to the dictionary-concatenation method utilized)
35
+ * `python >= 3.10` (due to the use of the pipe operator to concatenate dictionaries and types)
36
36
 
37
- * `matplotlib >= 3.9.0` (might work with lower versions but not guaranteed)
37
+ * `matplotlib >= 3.9` (might work with lower versions but not guaranteed)
38
38
 
39
- * `cartopy >= 0.23.0` (due to earlier bug with calling `copy()` on `CRS` objects)
39
+ * `cartopy >= 0.23` (due to earlier bug with calling `copy()` on `CRS` objects)
40
40
 
41
41
  ---
42
42
 
@@ -225,6 +225,12 @@ Two more projects assisted with the creation of this script:
225
225
 
226
226
  * [`Cartopy`](https://github.com/SciTools/cartopy/issues/2361) fixed an issue inherent to calling `.copy()` on `CRS` objects.
227
227
 
228
+ #### Releases
229
+
230
+ - `v2.0.1`: Fixed a bug in the `dual_bars()` function that prevented empty dictionaries to be passed. Also added a warning when auto-calculated bar widths appear to be exceeding the dimension of the axis (usually occurs when the axis is <2 kilometeres or miles long, depending on the units selected).
231
+
232
+ - `v2.0.2`: Changed f-string formatting to alternate double and single quotes, so as to maintain compatibility with versions of Python before 3.12 (see [here](https://github.com/moss-xyz/matplotlib-map-utils/issues/3)). However, this did reveal that another aspect of the code, namely concatenating `type` in function arguments, requires 3.10, and so the minimum python version was incremented.
233
+
228
234
  #### Future Roadmap
229
235
 
230
236
  With the release of `v2.x`, and the addition of **Scale Bar** tools, this project has achieved the two main objectives that I set out to.
@@ -511,42 +511,57 @@ def dual_bars(ax, draw=True, style: Literal["ticks","boxes"]="boxes",
511
511
  return_aob: bool=True
512
512
  ):
513
513
 
514
+ _style = sbf._validate(sbt._VALIDATE_PRIMARY, "style", style)
515
+ _location = sbf._validate(sbt._VALIDATE_PRIMARY, "location", location)
516
+
517
+ ##### CONCATENATION #####
518
+ # NOTE: Probably a better way to do this, will investigate
519
+ # Validation is done within each call of the scale_bar function, so don't need to do as much here
520
+ if _style == "boxes":
521
+ _bar = (_del_keys(_DEFAULT_BAR, ["rotation", "unit", "max", "length", "major_div", "minor_div",
522
+ "minor_frac","tick_loc","basecolors","tickcolors","tickwidth"]) | bar)
523
+ else:
524
+ _bar = (_del_keys(_DEFAULT_BAR, ["rotation", "unit", "max", "length", "major_div", "minor_div",
525
+ "facecolors","edgecolors","edgewidth"]) | bar)
526
+ _units = _DEFAULT_UNITS | units if units is not None else _DEFAULT_UNITS
527
+ _labels = _DEFAULT_LABELS | labels if labels is not None else _DEFAULT_LABELS
528
+ _text = _DEFAULT_TEXT | text if text is not None else _DEFAULT_TEXT
529
+ _aob = _DEFAULT_AOB | aob if aob is not None else _DEFAULT_AOB
530
+
514
531
  ##### VALIDATION #####
515
- if type(units_dual) not in [list, tuple] or len(units_dual) != 2:
532
+ if not isinstance(units_dual, (list, tuple)) or len(units_dual) != 2:
516
533
  raise ValueError("units_dual must be a list or tuple of length 2")
517
- if type(bar_maxes) not in [list, tuple] or len(bar_maxes) != 2:
534
+ if not isinstance(bar_maxes, (list, tuple)) or len(bar_maxes) != 2:
518
535
  raise ValueError("bar_maxes must be a list or tuple of length 2")
519
- if type(bar_lengths) not in [list, tuple] or len(bar_lengths) != 2:
536
+ if not isinstance(bar_lengths, (list, tuple)) or len(bar_lengths) != 2:
520
537
  raise ValueError("bar_lengths must be a list or tuple of length 2")
521
- if type(major_divs) not in [list, tuple] or len(major_divs) != 2:
538
+ if not isinstance(major_divs, (list, tuple)) or len(major_divs) != 2:
522
539
  raise ValueError("major_divs must be a list or tuple of length 2")
523
- if type(minor_divs) not in [list, tuple] or len(minor_divs) != 2:
540
+ if not isinstance(minor_divs, (list, tuple)) or len(minor_divs) != 2:
524
541
  raise ValueError("minor_divs must be a list or tuple of length 2")
525
542
 
526
- if units.get("loc", None) == "opposite":
543
+ if _units.get("loc", None) == "opposite":
527
544
  raise ValueError("units['loc'] for units cannot be opposite for dual_bars, as it will not align correctly with the second scale bar")
528
545
 
529
- if bar.get("rotation", None) is not None and bar.get("rotation", 0) != 0:
530
- warnings.warn("bar['rotation'] is not fully support. It is recommended instead that you set rotation to zero and return the image by setting draw=False and return_aob=False, to return the OffsetImage of the dual scale bars instead.")
531
- if bar.get("unit", None) is not None:
546
+ if _bar.get("rotation", None) is not None and bar.get("rotation", 0) != 0:
547
+ warnings.warn("bar['rotation'] is not fully supported. It is recommended instead that you set rotation to zero and return the image by setting draw=False and return_aob=False, to return the OffsetImage of the dual scale bars instead.")
548
+ if _bar.get("unit", None) is not None:
532
549
  warnings.warn("bar['unit'] is ignored for dual_bars, as it is set by units_dual")
533
- _ = bar.pop("unit")
534
- if bar.get("max", None) is not None:
550
+ _ = _bar.pop("unit")
551
+ if _bar.get("max", None) is not None:
535
552
  warnings.warn("bar['max'] is ignored for dual_bars, as it is (optionally) set by bar_maxes")
536
- _ = bar.pop("max")
537
- if bar.get("length", None) is not None:
553
+ _ = _bar.pop("max")
554
+ if _bar.get("length", None) is not None:
538
555
  warnings.warn("bar['length'] is ignored for dual_bars, as it is (optionally) set by bar_lengths")
539
- _ = bar.pop("length")
540
- if bar.get("major_div", None) is not None:
556
+ _ = _bar.pop("length")
557
+ if _bar.get("major_div", None) is not None:
541
558
  warnings.warn("bar['major_div'] is ignored for dual_bars, as it is (optionally) set by major_divs")
542
- _ = bar.pop("major_div")
543
- if bar.get("minor_div", None) is not None:
559
+ _ = _bar.pop("major_div")
560
+ if _bar.get("minor_div", None) is not None:
544
561
  warnings.warn("bar['minor_div'] is ignored for dual_bars, as it is (optionally) set by minor_divs")
545
- _ = bar.pop("minor_div")
562
+ _ = _bar.pop("minor_div")
546
563
 
547
- _style = sbf._validate(sbt._VALIDATE_PRIMARY, "style", style)
548
- _location = sbf._validate(sbt._VALIDATE_PRIMARY, "location", location)
549
- _aob = sbf._validate_dict(aob, _DEFAULT_AOB, sbt._VALIDATE_AOB, return_clean=True)
564
+ _aob = sbf._validate_dict(_aob, _DEFAULT_AOB, sbt._VALIDATE_AOB, return_clean=True)
550
565
 
551
566
  ##### CREATION #####
552
567
  # Setting up the order of some other settings (label location, tick location)
@@ -563,15 +578,16 @@ def dual_bars(ax, draw=True, style: Literal["ticks","boxes"]="boxes",
563
578
  # Creating a bar
564
579
  # Because draw is False and return_aob is false, an OffsetImage will be returned
565
580
  bars.append(scale_bar(ax, draw=False, style=_style, location=location,
566
- bar=((bar | bar_settings) if bar is not None else bar_settings),
567
- units=units,
568
- labels=(labels | label_settings if labels is not None else label_settings),
569
- text=text,
581
+ bar=(_bar | bar_settings),
582
+ units=_units,
583
+ labels=(_labels | label_settings),
584
+ text=_text,
585
+ aob=None,
570
586
  return_aob=False))
571
587
 
572
588
  ##### PACKING #####
573
589
  # First need to know if we pack vertically or horizontally
574
- bar_vertical = _calc_vert(bar["rotation"])
590
+ bar_vertical = _calc_vert(_bar["rotation"])
575
591
  packer = matplotlib.offsetbox.VPacker if bar_vertical == False else matplotlib.offsetbox.HPacker
576
592
  if bar["reverse"] == True:
577
593
  align = "right" if bar_vertical == False else "top"
@@ -586,7 +602,7 @@ def dual_bars(ax, draw=True, style: Literal["ticks","boxes"]="boxes",
586
602
  # Placing the packer in the AOB first off
587
603
  aob_pack = matplotlib.offsetbox.AnchoredOffsetbox(loc=_location, child=pack, **_del_keys(_aob, ["facecolor","edgecolor","alpha"]))
588
604
  # Finding if and how much we need to nudge either image
589
- aob_pack = _align_dual(ax, aob_pack, bar_vertical, bar["reverse"])
605
+ aob_pack = _align_dual(ax, aob_pack, bar_vertical, _bar["reverse"])
590
606
 
591
607
  ##### FINAL RENDER #####
592
608
  # If desired, we can just return the final packer
@@ -663,7 +679,7 @@ def _config_bar(ax, bar):
663
679
  # If the provided units are in degrees, we will convert to meters first
664
680
  # This will recalculate the ax_range
665
681
  if units_proj=="degree":
666
- warnings.warn(f"Provided CRS {bar["projection"]} uses degrees. An attempt will be made at conversion, but there will be accuracy issues: it is recommended that you use a projected CRS instead.")
682
+ warnings.warn(f"Provided CRS {bar['projection']} uses degrees. An attempt will be made at conversion, but there will be accuracy issues: it is recommended that you use a projected CRS instead.")
667
683
  ylim = ax.get_ylim()
668
684
  xlim = ax.get_xlim()
669
685
  # Using https://github.com/seangrogan/great_circle_calculator/blob/master/great_circle_calculator/great_circle_calculator.py
@@ -690,7 +706,7 @@ def _config_bar(ax, bar):
690
706
  try:
691
707
  units_user = sbt.units_standard.get(bar["unit"])
692
708
  except:
693
- warnings.warn(f"Desired output units selected by user ({bar["unit"]}) are considered invalid; please use one of the units specified in the units_standard dictionary in defaults.py")
709
+ warnings.warn(f"Desired output units selected by user ({bar['unit']}) are considered invalid; please use one of the units specified in the units_standard dictionary in defaults.py")
694
710
  units_user = None
695
711
 
696
712
  # Converting
@@ -733,7 +749,7 @@ def _config_bar(ax, bar):
733
749
  if bar["length"] < ax_dim:
734
750
  bar_max = (bar["length"] / ax_dim) * ax_range
735
751
  else:
736
- warnings.warn(f"Provided bar length ({bar["length"]}) is greater than the axis length ({ax_dim}); setting bar length to default (20% of axis length).")
752
+ warnings.warn(f"Provided bar length ({bar['length']}) is greater than the axis length ({ax_dim}); setting bar length to default (25% of axis length).")
737
753
  bar_max = 0.25 * ax_range
738
754
  # If bar["max"] is provided, don't need to go through all of this effort
739
755
  else:
@@ -791,6 +807,10 @@ def _config_bar(ax, bar):
791
807
  minor_div = 1
792
808
  else:
793
809
  minor_div = sbt.preferred_divs[bar_max_best][1]
810
+
811
+ # Doing a quick check of the calculated value, to see if it is "too long"
812
+ if (bar_length / ax_dim > 0.9) or (bar_max > ax_range * 0.9):
813
+ warnings.warn(f"The auto-calculated dimensions of the bar are too large for the axis. This usually happens when the height or width of your map is ~1 to 2 miles or kilometres (depending on your selected unit). This will result in a bar close to or longer than your axis, extending beyond your frame. Consider either manually specifying a 'max' and 'major_div' value less than 2, or switching your units to feet/metres as necessary.")
794
814
 
795
815
  return bar_max, bar_length, units_label, major_div, minor_div
796
816
 
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: matplotlib-map-utils
3
- Version: 2.0.0
3
+ Version: 2.0.2
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/
@@ -8,7 +8,7 @@ Project-URL: Bug Tracker, https://github.com/moss-xyz/matplotlib-map-utils/issue
8
8
  Classifier: Programming Language :: Python :: 3
9
9
  Classifier: License :: OSI Approved :: GNU General Public License (GPL)
10
10
  Classifier: Operating System :: OS Independent
11
- Requires-Python: >=3.9
11
+ Requires-Python: >=3.10
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
14
  Requires-Dist: matplotlib>=3.9.0
@@ -49,11 +49,11 @@ pip install matplotlib-map-utils
49
49
 
50
50
  The requirements for this package are:
51
51
 
52
- * `python >= 3.9.0` (due to the dictionary-concatenation method utilized)
52
+ * `python >= 3.10` (due to the use of the pipe operator to concatenate dictionaries and types)
53
53
 
54
- * `matplotlib >= 3.9.0` (might work with lower versions but not guaranteed)
54
+ * `matplotlib >= 3.9` (might work with lower versions but not guaranteed)
55
55
 
56
- * `cartopy >= 0.23.0` (due to earlier bug with calling `copy()` on `CRS` objects)
56
+ * `cartopy >= 0.23` (due to earlier bug with calling `copy()` on `CRS` objects)
57
57
 
58
58
  ---
59
59
 
@@ -242,6 +242,12 @@ Two more projects assisted with the creation of this script:
242
242
 
243
243
  * [`Cartopy`](https://github.com/SciTools/cartopy/issues/2361) fixed an issue inherent to calling `.copy()` on `CRS` objects.
244
244
 
245
+ #### Releases
246
+
247
+ - `v2.0.1`: Fixed a bug in the `dual_bars()` function that prevented empty dictionaries to be passed. Also added a warning when auto-calculated bar widths appear to be exceeding the dimension of the axis (usually occurs when the axis is <2 kilometeres or miles long, depending on the units selected).
248
+
249
+ - `v2.0.2`: Changed f-string formatting to alternate double and single quotes, so as to maintain compatibility with versions of Python before 3.12 (see [here](https://github.com/moss-xyz/matplotlib-map-utils/issues/3)). However, this did reveal that another aspect of the code, namely concatenating `type` in function arguments, requires 3.10, and so the minimum python version was incremented.
250
+
245
251
  #### Future Roadmap
246
252
 
247
253
  With the release of `v2.x`, and the addition of **Scale Bar** tools, this project has achieved the two main objectives that I set out to.
@@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "matplotlib-map-utils"
7
- version = "2.0.0"
7
+ version = "2.0.2"
8
8
  authors = [
9
9
  { name="David Moss", email="davidmoss1221@gmail.com" },
10
10
  ]
11
11
  description = "A suite of tools for creating maps in matplotlib"
12
12
  readme = "README.md"
13
- requires-python = ">=3.9"
13
+ requires-python = ">=3.10"
14
14
  classifiers = [
15
15
  "Programming Language :: Python :: 3",
16
16
  "License :: OSI Approved :: GNU General Public License (GPL)",