matplotlib-map-utils 3.0.1__tar.gz → 3.1.0__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-3.0.1 → matplotlib_map_utils-3.1.0}/PKG-INFO +53 -8
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/README.md +52 -7
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/matplotlib_map_utils/core/inset_map.py +64 -40
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/matplotlib_map_utils/core/north_arrow.py +24 -9
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/matplotlib_map_utils/core/scale_bar.py +261 -197
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/matplotlib_map_utils/defaults/scale_bar.py +5 -0
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/matplotlib_map_utils/validation/functions.py +3 -6
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/matplotlib_map_utils/validation/inset_map.py +3 -0
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/matplotlib_map_utils/validation/north_arrow.py +1 -0
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/matplotlib_map_utils/validation/scale_bar.py +7 -4
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/matplotlib_map_utils.egg-info/PKG-INFO +53 -8
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/matplotlib_map_utils.egg-info/top_level.txt +0 -1
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/pyproject.toml +1 -1
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/LICENSE +0 -0
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/matplotlib_map_utils/__init__.py +0 -0
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/matplotlib_map_utils/core/__init__.py +0 -0
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/matplotlib_map_utils/defaults/__init__.py +0 -0
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/matplotlib_map_utils/defaults/inset_map.py +0 -0
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/matplotlib_map_utils/defaults/north_arrow.py +0 -0
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/matplotlib_map_utils/scratch/map_utils.py +0 -0
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/matplotlib_map_utils/scratch/north_arrow_old_classes.py +0 -0
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/matplotlib_map_utils/utils/__init__.py +0 -0
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/matplotlib_map_utils/utils/usa.json +0 -0
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/matplotlib_map_utils/utils/usa.py +0 -0
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/matplotlib_map_utils/validation/__init__.py +0 -0
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/matplotlib_map_utils.egg-info/SOURCES.txt +0 -0
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/matplotlib_map_utils.egg-info/dependency_links.txt +0 -0
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/matplotlib_map_utils.egg-info/requires.txt +0 -0
- {matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: matplotlib-map-utils
|
3
|
-
Version: 3.0
|
3
|
+
Version: 3.1.0
|
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/
|
@@ -29,7 +29,7 @@ Dynamic: license-file
|
|
29
29
|
|
30
30
|
---
|
31
31
|
|
32
|
-
### Introduction
|
32
|
+
### 👋 Introduction
|
33
33
|
|
34
34
|
`matplotlib_map_utils` is intended to be a package that provides various functions and objects that assist with the the creation of maps using [`matplotlib`](https://matplotlib.org/stable/).
|
35
35
|
|
@@ -53,7 +53,7 @@ Together, these allow for the easy creation of a map such as the following:
|
|
53
53
|
|
54
54
|
---
|
55
55
|
|
56
|
-
### Installation
|
56
|
+
### 💾 Installation
|
57
57
|
|
58
58
|
This package is available on PyPi, and can be installed like so:
|
59
59
|
|
@@ -71,7 +71,7 @@ The requirements for this package are:
|
|
71
71
|
|
72
72
|
---
|
73
73
|
|
74
|
-
### Package Structure
|
74
|
+
### 📦 Package Structure
|
75
75
|
|
76
76
|
<details>
|
77
77
|
<summary><i>The package is arrayed in the following way:</i></summary>
|
@@ -260,6 +260,38 @@ This will create an output like the following:
|
|
260
260
|
|
261
261
|
Refer to `docs\howto_scale_bar` for details on how to customize each facet of the scale bar.
|
262
262
|
|
263
|
+
#### Specifying Length
|
264
|
+
|
265
|
+
There are three main ways of specifying the length of a scale bar:
|
266
|
+
|
267
|
+
- `length` is used to set the total length of the bar, either in _inches_ (for values >= 1) or as a _fraction of the axis_ (for values < 1).
|
268
|
+
- The default value of the scale bar utilizes this method, with a `length` value of `0.25` (meaning 25% of the axis).
|
269
|
+
- It will automatically orient itself against the horizontal or vertical axis when calculating its fraction, based on the value supplied for `rotation`.
|
270
|
+
- Note that any values here will be rounded to a "nice" whole integer, so the length will *always be approximate*; ex., if two inches is 9,128 units, your scale bar will end up being 9,000 units, and therefore a little less than two inches.
|
271
|
+
- Values `major_div` and `minor_div` are ignored, while a value for `max` will _override_ `length`.
|
272
|
+
|
273
|
+
- `max` is used to define the total length of the bar, _in the same units as your map_, as determined by the value of `projection` and `unit`.
|
274
|
+
- Ex: If you are using a projection in feet, and give a `max` of `1000`, your scale bar will be representative of 1,000 feet.
|
275
|
+
- Ex: If you are using a projection in feet, but provide a value of `meter` to `unit`, and give a `max` of `1000`, your scale bar will be representative of 1,000 meters.
|
276
|
+
- Will _override_ any value provided for `length`, and give a warning that it is doing so!
|
277
|
+
- Values can be optionally be provided for `major_div` and `minor_div`, to subdivide the bar into major or minor segments as you desire; if left blank, values for these will be calculated automatically (see `preferred_divs` in `validation/scale_bar.py` for the values used).
|
278
|
+
|
279
|
+
- `major_mult` can be used alongside `major_div` to _derive_ the total length: `major_mult` is the _length of a **single** major division_, in the _same units as your map_ (as determined by the value of `projection` and `unit`), which is then multiplied out by `major_div` to arrive at the desired length of the bar.
|
280
|
+
- Ex: If you set `major_mult` to 1,000, and `major_div` to 3, your bar will be 3,000 units long, divided into three 1,000 segments.
|
281
|
+
- This is the _only_ use case for `major_mult` - using it anywhere else will result in warnings and/or errors!
|
282
|
+
- Specifying either `max` or `length` will override this method!
|
283
|
+
- `minor_div` can still be _optionally_ provided.
|
284
|
+
|
285
|
+
All of the above cases expect a valid CRS to be supplied to the `projection` parameter, to correctly calculate the relative size of the bar with respect to the map's underlying units. However, three _additional_ values may be passed to `projection`, to override this behavior entirely:
|
286
|
+
|
287
|
+
- If `projection` is set to `px`, `pixel`, or `pixels`, then values for `max` and `major_mult` are interpreted as being in _pixels_ (so a `max` of 1,000 will result in a bar 1,000 pixels long)
|
288
|
+
|
289
|
+
- If `projection` is set to `pt`, `point`, or `points`, then values for `max` and `major_mult` are interpreted as being in _points_ (so a `max` of 1,000 will result in a bar 1,000 points long (a point is 1/72 of an inch))
|
290
|
+
|
291
|
+
- If `projection` is set to `dx`, `custom`, or `axis`, then values for `max` and `major_mult` are interpreted as being in _the units of the x or y axis_ (so a `max` of 1,000 will result in a bar equal to 1,000 units of the x-axis (if orientated horizontally))
|
292
|
+
|
293
|
+
The intent of these additional methods is to provide an alternative interface for defining the bar, in the case of non-standard projections, or for non-cartographic use cases (in particular, this is inspired by the `dx` implementation of `matplotlib-scalebar`). However, this puts the onus on the user to know how big their bar should be - you also cannot pass a value to `unit` to convert! Note you can provide custom label text to the bar via the `labels` and `units` arguments (ex. if you need to label "inches" or something).
|
294
|
+
|
263
295
|
</details>
|
264
296
|
|
265
297
|
---
|
@@ -347,7 +379,7 @@ usa = USA()
|
|
347
379
|
# Getting a list FIPS codes for US States
|
348
380
|
usa.filter(states=True, to_return="fips")
|
349
381
|
# Getting a list of State Names for states in the South and Midwest regions
|
350
|
-
usa.filter(region=["South","
|
382
|
+
usa.filter(region=["South","Midwest"], to_return="name")
|
351
383
|
```
|
352
384
|
|
353
385
|
Refer to `docs\howto_utils` for details on how to use this class, including with `pandas.apply()`.
|
@@ -356,7 +388,7 @@ Refer to `docs\howto_utils` for details on how to use this class, including with
|
|
356
388
|
|
357
389
|
---
|
358
390
|
|
359
|
-
### Development Notes
|
391
|
+
### 📝 Development Notes
|
360
392
|
|
361
393
|
#### Inspiration and Thanks
|
362
394
|
|
@@ -370,6 +402,9 @@ Two more projects assisted with the creation of this script:
|
|
370
402
|
|
371
403
|
#### Releases
|
372
404
|
|
405
|
+
<details>
|
406
|
+
<summary><i>See prior release notes</i></summary>
|
407
|
+
|
373
408
|
- `v1.0.x`: Initial releases featuring the North Arrow element, along with some minor bug fixes.
|
374
409
|
|
375
410
|
- `v2.0.0`: Initial release of the Scale Bar element.
|
@@ -380,15 +415,21 @@ Two more projects assisted with the creation of this script:
|
|
380
415
|
|
381
416
|
- `v2.1.0`: Added a utility class, `USA`, for filtering subsets of US states and territories based on FIPS code, name, abbreviation, region, division, and more. This is considered a beta release, and might be subject to change later on.
|
382
417
|
|
418
|
+
</details>
|
419
|
+
<br>
|
420
|
+
|
383
421
|
- `v3.0.0`: Release of inset map and extent and detail indicator classes and functions.
|
384
422
|
|
385
423
|
- `v3.0.1`: Fixed a bug that led to an incorrect Scale Bar being rendered when using the function method (`scale_bar()`) on a plot containing raster data (see [here](https://github.com/moss-xyz/matplotlib-map-utils/issues/10) for details).
|
386
424
|
|
425
|
+
- `v3.1.0`: Overhauled the functionality for specifying the the length of a scale bar, including support for custom units/projections (similar to `matplotlib-scalebar`'s `dx` argument) and to specify the length of a major division instead of the entire scale bar, as requested [here](https://github.com/moss-xyz/matplotlib-map-utils/issues/10). Added ability to set artist-level `zorder` variables for all elements, with both the function and class method approaches, as requested [here](https://github.com/moss-xyz/matplotlib-map-utils/issues/9) and [here](https://github.com/moss-xyz/matplotlib-map-utils/issues/10). Also fixed a bug related to custom division labels on the scale bar.
|
426
|
+
|
387
427
|
#### Future Roadmap
|
388
428
|
|
389
429
|
With the release of `v3.x`, this project has achieved full coverage of the "main" map elements I think are necessary.
|
390
430
|
|
391
|
-
|
431
|
+
<details>
|
432
|
+
<summary><i>If I continue development of this project, I will be looking to add or fix the following features:</i></summary>
|
392
433
|
|
393
434
|
* For all: switch to a system based on Pydantic for easier type validation
|
394
435
|
|
@@ -424,14 +465,18 @@ If I continue development of this project, I will be looking to add or fix the f
|
|
424
465
|
|
425
466
|
Future releases (if the project is continued) will probably focus on other functions that I have created myself that give more control in the formatting of maps. I am also open to ideas for other extensions to create!
|
426
467
|
|
468
|
+
</details>
|
469
|
+
|
427
470
|
#### Support and Contributions
|
428
471
|
|
429
472
|
If you notice something is not working as intended or if you'd like to add a feature yourself, I welcome PRs - just be sure to be descriptive as to what you are changing and why, including code examples!
|
430
473
|
|
431
474
|
If you are having issues using this script, feel free to leave a post explaining your issue, and I will try and assist, though I have no guaranteed SLAs as this is just a hobby project.
|
432
475
|
|
476
|
+
I am open to contributions, especially to help tackle the roadmap above!
|
477
|
+
|
433
478
|
---
|
434
479
|
|
435
|
-
### License
|
480
|
+
### ⚖️ License
|
436
481
|
|
437
482
|
I know nothing about licensing, so I went with the GPL license. If that is incompatible with any of the dependencies, please let me know.
|
@@ -10,7 +10,7 @@
|
|
10
10
|
|
11
11
|
---
|
12
12
|
|
13
|
-
### Introduction
|
13
|
+
### 👋 Introduction
|
14
14
|
|
15
15
|
`matplotlib_map_utils` is intended to be a package that provides various functions and objects that assist with the the creation of maps using [`matplotlib`](https://matplotlib.org/stable/).
|
16
16
|
|
@@ -34,7 +34,7 @@ Together, these allow for the easy creation of a map such as the following:
|
|
34
34
|
|
35
35
|
---
|
36
36
|
|
37
|
-
### Installation
|
37
|
+
### 💾 Installation
|
38
38
|
|
39
39
|
This package is available on PyPi, and can be installed like so:
|
40
40
|
|
@@ -52,7 +52,7 @@ The requirements for this package are:
|
|
52
52
|
|
53
53
|
---
|
54
54
|
|
55
|
-
### Package Structure
|
55
|
+
### 📦 Package Structure
|
56
56
|
|
57
57
|
<details>
|
58
58
|
<summary><i>The package is arrayed in the following way:</i></summary>
|
@@ -241,6 +241,38 @@ This will create an output like the following:
|
|
241
241
|
|
242
242
|
Refer to `docs\howto_scale_bar` for details on how to customize each facet of the scale bar.
|
243
243
|
|
244
|
+
#### Specifying Length
|
245
|
+
|
246
|
+
There are three main ways of specifying the length of a scale bar:
|
247
|
+
|
248
|
+
- `length` is used to set the total length of the bar, either in _inches_ (for values >= 1) or as a _fraction of the axis_ (for values < 1).
|
249
|
+
- The default value of the scale bar utilizes this method, with a `length` value of `0.25` (meaning 25% of the axis).
|
250
|
+
- It will automatically orient itself against the horizontal or vertical axis when calculating its fraction, based on the value supplied for `rotation`.
|
251
|
+
- Note that any values here will be rounded to a "nice" whole integer, so the length will *always be approximate*; ex., if two inches is 9,128 units, your scale bar will end up being 9,000 units, and therefore a little less than two inches.
|
252
|
+
- Values `major_div` and `minor_div` are ignored, while a value for `max` will _override_ `length`.
|
253
|
+
|
254
|
+
- `max` is used to define the total length of the bar, _in the same units as your map_, as determined by the value of `projection` and `unit`.
|
255
|
+
- Ex: If you are using a projection in feet, and give a `max` of `1000`, your scale bar will be representative of 1,000 feet.
|
256
|
+
- Ex: If you are using a projection in feet, but provide a value of `meter` to `unit`, and give a `max` of `1000`, your scale bar will be representative of 1,000 meters.
|
257
|
+
- Will _override_ any value provided for `length`, and give a warning that it is doing so!
|
258
|
+
- Values can be optionally be provided for `major_div` and `minor_div`, to subdivide the bar into major or minor segments as you desire; if left blank, values for these will be calculated automatically (see `preferred_divs` in `validation/scale_bar.py` for the values used).
|
259
|
+
|
260
|
+
- `major_mult` can be used alongside `major_div` to _derive_ the total length: `major_mult` is the _length of a **single** major division_, in the _same units as your map_ (as determined by the value of `projection` and `unit`), which is then multiplied out by `major_div` to arrive at the desired length of the bar.
|
261
|
+
- Ex: If you set `major_mult` to 1,000, and `major_div` to 3, your bar will be 3,000 units long, divided into three 1,000 segments.
|
262
|
+
- This is the _only_ use case for `major_mult` - using it anywhere else will result in warnings and/or errors!
|
263
|
+
- Specifying either `max` or `length` will override this method!
|
264
|
+
- `minor_div` can still be _optionally_ provided.
|
265
|
+
|
266
|
+
All of the above cases expect a valid CRS to be supplied to the `projection` parameter, to correctly calculate the relative size of the bar with respect to the map's underlying units. However, three _additional_ values may be passed to `projection`, to override this behavior entirely:
|
267
|
+
|
268
|
+
- If `projection` is set to `px`, `pixel`, or `pixels`, then values for `max` and `major_mult` are interpreted as being in _pixels_ (so a `max` of 1,000 will result in a bar 1,000 pixels long)
|
269
|
+
|
270
|
+
- If `projection` is set to `pt`, `point`, or `points`, then values for `max` and `major_mult` are interpreted as being in _points_ (so a `max` of 1,000 will result in a bar 1,000 points long (a point is 1/72 of an inch))
|
271
|
+
|
272
|
+
- If `projection` is set to `dx`, `custom`, or `axis`, then values for `max` and `major_mult` are interpreted as being in _the units of the x or y axis_ (so a `max` of 1,000 will result in a bar equal to 1,000 units of the x-axis (if orientated horizontally))
|
273
|
+
|
274
|
+
The intent of these additional methods is to provide an alternative interface for defining the bar, in the case of non-standard projections, or for non-cartographic use cases (in particular, this is inspired by the `dx` implementation of `matplotlib-scalebar`). However, this puts the onus on the user to know how big their bar should be - you also cannot pass a value to `unit` to convert! Note you can provide custom label text to the bar via the `labels` and `units` arguments (ex. if you need to label "inches" or something).
|
275
|
+
|
244
276
|
</details>
|
245
277
|
|
246
278
|
---
|
@@ -328,7 +360,7 @@ usa = USA()
|
|
328
360
|
# Getting a list FIPS codes for US States
|
329
361
|
usa.filter(states=True, to_return="fips")
|
330
362
|
# Getting a list of State Names for states in the South and Midwest regions
|
331
|
-
usa.filter(region=["South","
|
363
|
+
usa.filter(region=["South","Midwest"], to_return="name")
|
332
364
|
```
|
333
365
|
|
334
366
|
Refer to `docs\howto_utils` for details on how to use this class, including with `pandas.apply()`.
|
@@ -337,7 +369,7 @@ Refer to `docs\howto_utils` for details on how to use this class, including with
|
|
337
369
|
|
338
370
|
---
|
339
371
|
|
340
|
-
### Development Notes
|
372
|
+
### 📝 Development Notes
|
341
373
|
|
342
374
|
#### Inspiration and Thanks
|
343
375
|
|
@@ -351,6 +383,9 @@ Two more projects assisted with the creation of this script:
|
|
351
383
|
|
352
384
|
#### Releases
|
353
385
|
|
386
|
+
<details>
|
387
|
+
<summary><i>See prior release notes</i></summary>
|
388
|
+
|
354
389
|
- `v1.0.x`: Initial releases featuring the North Arrow element, along with some minor bug fixes.
|
355
390
|
|
356
391
|
- `v2.0.0`: Initial release of the Scale Bar element.
|
@@ -361,15 +396,21 @@ Two more projects assisted with the creation of this script:
|
|
361
396
|
|
362
397
|
- `v2.1.0`: Added a utility class, `USA`, for filtering subsets of US states and territories based on FIPS code, name, abbreviation, region, division, and more. This is considered a beta release, and might be subject to change later on.
|
363
398
|
|
399
|
+
</details>
|
400
|
+
<br>
|
401
|
+
|
364
402
|
- `v3.0.0`: Release of inset map and extent and detail indicator classes and functions.
|
365
403
|
|
366
404
|
- `v3.0.1`: Fixed a bug that led to an incorrect Scale Bar being rendered when using the function method (`scale_bar()`) on a plot containing raster data (see [here](https://github.com/moss-xyz/matplotlib-map-utils/issues/10) for details).
|
367
405
|
|
406
|
+
- `v3.1.0`: Overhauled the functionality for specifying the the length of a scale bar, including support for custom units/projections (similar to `matplotlib-scalebar`'s `dx` argument) and to specify the length of a major division instead of the entire scale bar, as requested [here](https://github.com/moss-xyz/matplotlib-map-utils/issues/10). Added ability to set artist-level `zorder` variables for all elements, with both the function and class method approaches, as requested [here](https://github.com/moss-xyz/matplotlib-map-utils/issues/9) and [here](https://github.com/moss-xyz/matplotlib-map-utils/issues/10). Also fixed a bug related to custom division labels on the scale bar.
|
407
|
+
|
368
408
|
#### Future Roadmap
|
369
409
|
|
370
410
|
With the release of `v3.x`, this project has achieved full coverage of the "main" map elements I think are necessary.
|
371
411
|
|
372
|
-
|
412
|
+
<details>
|
413
|
+
<summary><i>If I continue development of this project, I will be looking to add or fix the following features:</i></summary>
|
373
414
|
|
374
415
|
* For all: switch to a system based on Pydantic for easier type validation
|
375
416
|
|
@@ -405,14 +446,18 @@ If I continue development of this project, I will be looking to add or fix the f
|
|
405
446
|
|
406
447
|
Future releases (if the project is continued) will probably focus on other functions that I have created myself that give more control in the formatting of maps. I am also open to ideas for other extensions to create!
|
407
448
|
|
449
|
+
</details>
|
450
|
+
|
408
451
|
#### Support and Contributions
|
409
452
|
|
410
453
|
If you notice something is not working as intended or if you'd like to add a feature yourself, I welcome PRs - just be sure to be descriptive as to what you are changing and why, including code examples!
|
411
454
|
|
412
455
|
If you are having issues using this script, feel free to leave a post explaining your issue, and I will try and assist, though I have no guaranteed SLAs as this is just a hobby project.
|
413
456
|
|
457
|
+
I am open to contributions, especially to help tackle the roadmap above!
|
458
|
+
|
414
459
|
---
|
415
460
|
|
416
|
-
### License
|
461
|
+
### ⚖️ License
|
417
462
|
|
418
463
|
I know nothing about licensing, so I went with the GPL license. If that is incompatible with any of the dependencies, please let me know.
|
{matplotlib_map_utils-3.0.1 → matplotlib_map_utils-3.1.0}/matplotlib_map_utils/core/inset_map.py
RENAMED
@@ -46,6 +46,7 @@ class InsetMap(matplotlib.artist.Artist):
|
|
46
46
|
coords: imt._TYPE_INSET["coords"]=None,
|
47
47
|
transform=None,
|
48
48
|
to_plot=None,
|
49
|
+
zorder: int=99,
|
49
50
|
**kwargs):
|
50
51
|
# Starting up the object with the base properties of a matplotlib Artist
|
51
52
|
matplotlib.artist.Artist.__init__(self)
|
@@ -56,6 +57,7 @@ class InsetMap(matplotlib.artist.Artist):
|
|
56
57
|
self._pad = imf._validate(imt._VALIDATE_INSET, "pad", pad)
|
57
58
|
self._coords = imf._validate(imt._VALIDATE_INSET, "coords", coords)
|
58
59
|
self._to_plot = imf._validate(imt._VALIDATE_INSET, "to_plot", to_plot)
|
60
|
+
self._zorder = imf._validate(imt._VALIDATE_INSET, "zorder", zorder)
|
59
61
|
|
60
62
|
# Checking if we need to override values for size and pad
|
61
63
|
if self._size is None:
|
@@ -65,11 +67,6 @@ class InsetMap(matplotlib.artist.Artist):
|
|
65
67
|
|
66
68
|
self._transform = transform # not validated!
|
67
69
|
self._kwargs = kwargs # not validated!
|
68
|
-
|
69
|
-
# We do set the zorder for our objects individually,
|
70
|
-
# but we ALSO set it for the entire artist, here
|
71
|
-
# Thank you to matplotlib-scalebar for this tip
|
72
|
-
zorder = 99
|
73
70
|
|
74
71
|
## INTERNAL PROPERTIES ##
|
75
72
|
# This allows for easy-updating of properties
|
@@ -162,6 +159,16 @@ class InsetMap(matplotlib.artist.Artist):
|
|
162
159
|
def to_plot(self, val):
|
163
160
|
val = imf._validate(imt._VALIDATE_INSET, "to_plot", val)
|
164
161
|
self._to_plot = val
|
162
|
+
|
163
|
+
# zorder
|
164
|
+
@property
|
165
|
+
def zorder(self):
|
166
|
+
return self._zorder
|
167
|
+
|
168
|
+
@zorder.setter
|
169
|
+
def zorder(self, val):
|
170
|
+
val = imf._validate(imt._VALIDATE_INSET, "zorder", val)
|
171
|
+
self._zorder = val
|
165
172
|
|
166
173
|
## COPY FUNCTION ##
|
167
174
|
# This is solely to get around matplotlib's restrictions around re-using an artist across multiple axes
|
@@ -176,7 +183,7 @@ class InsetMap(matplotlib.artist.Artist):
|
|
176
183
|
def create(self, pax, **kwargs):
|
177
184
|
# Can re-use the drawing function we already established, but return the object instead
|
178
185
|
iax = inset_map(ax=pax, location=self._location, size=self._size,
|
179
|
-
pad=self._pad, coords=self._coords, transform=self._transform,
|
186
|
+
pad=self._pad, coords=self._coords, transform=self._transform, zorder=self._zorder,
|
180
187
|
**self._kwargs, **kwargs)
|
181
188
|
|
182
189
|
# If data is passed to to_plot, then we plot that on the newly created axis as well
|
@@ -226,6 +233,7 @@ class ExtentIndicator(matplotlib.artist.Artist):
|
|
226
233
|
linecolor: imt._TYPE_EXTENT["linecolor"]="red",
|
227
234
|
alpha: imt._TYPE_EXTENT["alpha"]=0.5,
|
228
235
|
linewidth: imt._TYPE_EXTENT["linewidth"]=1,
|
236
|
+
zorder: int=99,
|
229
237
|
**kwargs):
|
230
238
|
# Starting up the object with the base properties of a matplotlib Artist
|
231
239
|
matplotlib.artist.Artist.__init__(self)
|
@@ -239,13 +247,9 @@ class ExtentIndicator(matplotlib.artist.Artist):
|
|
239
247
|
self._linecolor = imf._validate(imt._VALIDATE_EXTENT, "linecolor", linecolor)
|
240
248
|
self._alpha = imf._validate(imt._VALIDATE_EXTENT, "alpha", alpha)
|
241
249
|
self._linewidth = imf._validate(imt._VALIDATE_EXTENT, "linewidth", linewidth)
|
250
|
+
self._zorder = imf._validate(imt._VALIDATE_EXTENT, "zorder", zorder)
|
242
251
|
|
243
252
|
self._kwargs = kwargs # not validated!
|
244
|
-
|
245
|
-
# We do set the zorder for our objects individually,
|
246
|
-
# but we ALSO set it for the entire artist, here
|
247
|
-
# Thank you to matplotlib-scalebar for this tip
|
248
|
-
zorder = 99
|
249
253
|
|
250
254
|
## INTERNAL PROPERTIES ##
|
251
255
|
# This allows for easy-updating of properties
|
@@ -332,6 +336,16 @@ class ExtentIndicator(matplotlib.artist.Artist):
|
|
332
336
|
def linewidth(self, val):
|
333
337
|
val = imf._validate(imt._VALIDATE_EXTENT, "linewidth", val)
|
334
338
|
self._linewidth = val
|
339
|
+
|
340
|
+
# zorder
|
341
|
+
@property
|
342
|
+
def zorder(self):
|
343
|
+
return self._zorder
|
344
|
+
|
345
|
+
@zorder.setter
|
346
|
+
def zorder(self, val):
|
347
|
+
val = imf._validate(imt._VALIDATE_EXTENT, "zorder", val)
|
348
|
+
self._zorder = val
|
335
349
|
|
336
350
|
# kwargs
|
337
351
|
@property
|
@@ -366,7 +380,7 @@ class ExtentIndicator(matplotlib.artist.Artist):
|
|
366
380
|
to_return=self._to_return, straighten=self._straighten,
|
367
381
|
pad=self._pad, plot=self._plot,
|
368
382
|
facecolor=self._facecolor, linecolor=self._linecolor,
|
369
|
-
alpha=self._alpha, linewidth=self._linewidth,
|
383
|
+
alpha=self._alpha, linewidth=self._linewidth, zorder=self._zorder,
|
370
384
|
**self._kwargs, **kwargs)
|
371
385
|
|
372
386
|
# The indicator will be drawn automatically if plot is True
|
@@ -389,6 +403,7 @@ class DetailIndicator(matplotlib.artist.Artist):
|
|
389
403
|
linewidth: imt._TYPE_EXTENT["linewidth"]=1,
|
390
404
|
connector_color: imt._TYPE_DETAIL["connector_color"]="black",
|
391
405
|
connector_width: imt._TYPE_DETAIL["connector_width"]=1,
|
406
|
+
zorder: int=99,
|
392
407
|
**kwargs):
|
393
408
|
# Starting up the object with the base properties of a matplotlib Artist
|
394
409
|
matplotlib.artist.Artist.__init__(self)
|
@@ -404,13 +419,9 @@ class DetailIndicator(matplotlib.artist.Artist):
|
|
404
419
|
self._to_return = imf._validate(imt._VALIDATE_DETAIL, "to_return", to_return)
|
405
420
|
self._connector_color = imf._validate(imt._VALIDATE_DETAIL, "connector_color", connector_color)
|
406
421
|
self._connector_width = imf._validate(imt._VALIDATE_DETAIL, "connector_width", connector_width)
|
422
|
+
self._zorder = imf._validate(imt._VALIDATE_DETAIL, "zorder", zorder)
|
407
423
|
|
408
424
|
self._kwargs = kwargs # not validated!
|
409
|
-
|
410
|
-
# We do set the zorder for our objects individually,
|
411
|
-
# but we ALSO set it for the entire artist, here
|
412
|
-
# Thank you to matplotlib-scalebar for this tip
|
413
|
-
zorder = 99
|
414
425
|
|
415
426
|
## INTERNAL PROPERTIES ##
|
416
427
|
# This allows for easy-updating of properties
|
@@ -517,6 +528,16 @@ class DetailIndicator(matplotlib.artist.Artist):
|
|
517
528
|
def connector_width(self, val):
|
518
529
|
val = imf._validate(imt._VALIDATE_DETAIL, "connector_width", val)
|
519
530
|
self._connector_width = val
|
531
|
+
|
532
|
+
# zorder
|
533
|
+
@property
|
534
|
+
def zorder(self):
|
535
|
+
return self._zorder
|
536
|
+
|
537
|
+
@zorder.setter
|
538
|
+
def zorder(self, val):
|
539
|
+
val = imf._validate(imt._VALIDATE_DETAIL, "zorder", val)
|
540
|
+
self._zorder = val
|
520
541
|
|
521
542
|
# kwargs
|
522
543
|
@property
|
@@ -544,7 +565,8 @@ class DetailIndicator(matplotlib.artist.Artist):
|
|
544
565
|
pax: imt._TYPE_EXTENT["pax"],
|
545
566
|
iax: imt._TYPE_EXTENT["bax"],
|
546
567
|
pcrs: imt._TYPE_EXTENT["pcrs"],
|
547
|
-
icrs: imt._TYPE_EXTENT["bcrs"],
|
568
|
+
icrs: imt._TYPE_EXTENT["bcrs"],
|
569
|
+
**kwargs):
|
548
570
|
|
549
571
|
# Can re-use the drawing function we already established, but return the object instead
|
550
572
|
dti = indicate_detail(pax=pax, iax=iax, pcrs=pcrs, icrs=icrs,
|
@@ -554,6 +576,7 @@ class DetailIndicator(matplotlib.artist.Artist):
|
|
554
576
|
alpha=self._alpha, linewidth=self._linewidth,
|
555
577
|
connector_color=self._connector_color,
|
556
578
|
connector_width=self._connector_width,
|
579
|
+
zorder=self._zorder,
|
557
580
|
**self._kwargs, **kwargs)
|
558
581
|
|
559
582
|
# The indicator will be drawn automatically if plot is True
|
@@ -573,6 +596,7 @@ def inset_map(ax,
|
|
573
596
|
pad: imt._TYPE_INSET["pad"]=None,
|
574
597
|
coords: imt._TYPE_INSET["coords"]=None,
|
575
598
|
transform=None,
|
599
|
+
zorder: int=99,
|
576
600
|
**kwargs):
|
577
601
|
|
578
602
|
## VALIDATION ##
|
@@ -580,6 +604,7 @@ def inset_map(ax,
|
|
580
604
|
size = imf._validate(imt._VALIDATE_INSET, "size", size)
|
581
605
|
pad = imf._validate(imt._VALIDATE_INSET, "pad", pad)
|
582
606
|
coords = imf._validate(imt._VALIDATE_INSET, "coords", coords)
|
607
|
+
zorder = imf._validate(imt._VALIDATE_INSET, "zorder", zorder)
|
583
608
|
|
584
609
|
if size is None:
|
585
610
|
size = _DEFAULT_INSET_MAP["size"]
|
@@ -671,7 +696,7 @@ def inset_map(ax,
|
|
671
696
|
## DRAWING ##
|
672
697
|
# Creating the new inset map with the specified height, width, and location
|
673
698
|
# by default, inset_axes requires everything to be in ax.transAxes coordinates
|
674
|
-
iax = ax.inset_axes([x, y, inset_width, inset_height], **kwargs)
|
699
|
+
iax = ax.inset_axes([x, y, inset_width, inset_height], zorder=zorder, **kwargs)
|
675
700
|
|
676
701
|
# We also set the anchor here, such that it stays fixed when any resizing takes place
|
677
702
|
loc_anchors = {
|
@@ -701,6 +726,7 @@ def indicate_extent(pax: imt._TYPE_EXTENT["pax"],
|
|
701
726
|
linecolor: imt._TYPE_EXTENT["linecolor"]="red",
|
702
727
|
alpha: imt._TYPE_EXTENT["alpha"]=0.5,
|
703
728
|
linewidth: imt._TYPE_EXTENT["linewidth"]=1,
|
729
|
+
zorder: int=99,
|
704
730
|
**kwargs):
|
705
731
|
|
706
732
|
## VALIDATION ##
|
@@ -716,6 +742,7 @@ def indicate_extent(pax: imt._TYPE_EXTENT["pax"],
|
|
716
742
|
linecolor = imf._validate(imt._VALIDATE_EXTENT, "linecolor", linecolor)
|
717
743
|
alpha = imf._validate(imt._VALIDATE_EXTENT, "alpha", alpha)
|
718
744
|
linewidth = imf._validate(imt._VALIDATE_EXTENT, "linewidth", linewidth)
|
745
|
+
zorder = imf._validate(imt._VALIDATE_EXTENT, "zorder", zorder)
|
719
746
|
|
720
747
|
# Make sure the figure layout is calculated
|
721
748
|
fig = pax.get_figure()
|
@@ -748,15 +775,13 @@ def indicate_extent(pax: imt._TYPE_EXTENT["pax"],
|
|
748
775
|
# Straightening the points if desired
|
749
776
|
if straighten == True:
|
750
777
|
extent_shape = shapely.envelope(extent_shape)
|
751
|
-
|
752
|
-
# return extent_shape
|
753
|
-
|
778
|
+
|
754
779
|
# Plotting, if desired
|
755
780
|
if plot == True:
|
756
781
|
# Note that the alpha ONLY applies to the facecolor!
|
757
782
|
extent_patch = matplotlib.patches.Polygon(list(extent_shape.exterior.coords), transform=pax.transData,
|
758
783
|
facecolor=matplotlib.colors.to_rgba(facecolor, alpha=alpha),
|
759
|
-
edgecolor=linecolor, linewidth=linewidth, **kwargs)
|
784
|
+
edgecolor=linecolor, linewidth=linewidth, zorder=zorder, **kwargs)
|
760
785
|
pax.add_artist(extent_patch)
|
761
786
|
|
762
787
|
# Deciding what we need to return
|
@@ -789,8 +814,7 @@ def indicate_detail(pax: imt._TYPE_EXTENT["pax"],
|
|
789
814
|
alpha: imt._TYPE_EXTENT["alpha"]=1,
|
790
815
|
linecolor: imt._TYPE_EXTENT["linecolor"]="black",
|
791
816
|
linewidth: imt._TYPE_EXTENT["linewidth"]=1,
|
792
|
-
|
793
|
-
# connector_width: imt._TYPE_DETAIL["connector_width"]=1,
|
817
|
+
zorder: int=99,
|
794
818
|
**kwargs):
|
795
819
|
|
796
820
|
fig = pax.get_figure()
|
@@ -809,8 +833,7 @@ def indicate_detail(pax: imt._TYPE_EXTENT["pax"],
|
|
809
833
|
alpha = imf._validate(imt._VALIDATE_EXTENT, "alpha", alpha)
|
810
834
|
linecolor = imf._validate(imt._VALIDATE_EXTENT, "linecolor", linecolor)
|
811
835
|
linewidth = imf._validate(imt._VALIDATE_EXTENT, "linewidth", linewidth)
|
812
|
-
|
813
|
-
# connector_width = imf._validate(imt._VALIDATE_DETAIL, "connector_width", connector_width)
|
836
|
+
zorder = imf._validate(imt._VALIDATE_EXTENT, "zorder", zorder)
|
814
837
|
|
815
838
|
# Drawing the extent indicator on the main map
|
816
839
|
# Setting to_return="ax" gets us the corners of the patch in pax.transAxes coordinates
|
@@ -819,7 +842,7 @@ def indicate_detail(pax: imt._TYPE_EXTENT["pax"],
|
|
819
842
|
straighten=straighten, pad=pad, plot=plot,
|
820
843
|
facecolor=facecolor, linecolor=linecolor,
|
821
844
|
alpha=alpha, linewidth=linewidth*1.25,
|
822
|
-
to_return="ax", **kwargs)[:4]
|
845
|
+
to_return="ax", zorder=zorder, **kwargs)[:4]
|
823
846
|
|
824
847
|
# Getting the inset axis points and transforming them to the parent axis CRS
|
825
848
|
corners_inset = _inset_corners_to_parent(pax, iax)
|
@@ -873,12 +896,13 @@ def indicate_detail(pax: imt._TYPE_EXTENT["pax"],
|
|
873
896
|
for c in connections:
|
874
897
|
# This is listed as [extent_x, inset_x], [extent_y, inset_y]
|
875
898
|
pax.plot([c[0][0], c[1][0]], [c[0][1], c[1][1]],
|
876
|
-
color=linecolor, linewidth=linewidth, transform=pax.transAxes)
|
899
|
+
color=linecolor, linewidth=linewidth, transform=pax.transAxes, zorder=zorder+1)
|
877
900
|
|
878
|
-
# Also updating the linewidth and color of the inset map
|
879
|
-
|
880
|
-
|
881
|
-
|
901
|
+
# Also updating the linewidth and color of the inset map itself, to match
|
902
|
+
iax.spines[:].set_linewidth(linewidth*1.2) # making this slightly thicker
|
903
|
+
iax.spines[:].set_edgecolor(linecolor)
|
904
|
+
iax.set_zorder(zorder+2)
|
905
|
+
iax.spines[:].set_zorder(zorder+2)
|
882
906
|
|
883
907
|
# Returning as requested
|
884
908
|
if to_return is None:
|
@@ -893,37 +917,37 @@ def indicate_detail(pax: imt._TYPE_EXTENT["pax"],
|
|
893
917
|
# This is a top-level helping function
|
894
918
|
# that will return an axis with inset maps drawn for Alaska, Hawaii, DC, and/or Puerto Rico
|
895
919
|
# NOTE that as of this initial release, it assumes your map is in CRS 3857 for positioning
|
896
|
-
def inset_usa(ax, alaska=True, hawaii=True, dc=True, puerto_rico=True, size=None, pad=None, **kwargs):
|
920
|
+
def inset_usa(ax, alaska=True, hawaii=True, dc=True, puerto_rico=True, size=None, pad=None, zorder: int=99, **kwargs):
|
897
921
|
# This will return all of the axes we create
|
898
922
|
to_return = []
|
899
923
|
|
900
924
|
# Alaska and Hawaii are positioned relative to each other
|
901
925
|
if alaska == True and hawaii == True:
|
902
|
-
aax = inset_map(ax, "lower left", size, pad, **kwargs)
|
926
|
+
aax = inset_map(ax, "lower left", size, pad, zorder=zorder, **kwargs)
|
903
927
|
to_return.append(aax)
|
904
928
|
# Need to shift over the hawaii axis by the size of the alaska axis
|
905
929
|
# Note that we add xmax and xmin together here, to account for the padding (xmin is the amount of padding)
|
906
930
|
shift_right = float(aax.get_window_extent().transformed(ax.transAxes.inverted()).xmax) + float(aax.get_window_extent().transformed(ax.transAxes.inverted()).xmin)
|
907
931
|
# also need to shift it up, by the amount of the padding (which we can crib from ymin)
|
908
932
|
shift_up = float(aax.get_window_extent().transformed(ax.transAxes.inverted()).ymin)
|
909
|
-
hax = inset_map(ax, "lower left", size, pad, coords=(shift_right, shift_up), **kwargs)
|
933
|
+
hax = inset_map(ax, "lower left", size, pad, zorder=zorder, coords=(shift_right, shift_up), **kwargs)
|
910
934
|
to_return.append(hax)
|
911
935
|
else:
|
912
936
|
if alaska == True:
|
913
|
-
aax = inset_map(ax, "lower_left", size, pad, **kwargs)
|
937
|
+
aax = inset_map(ax, "lower_left", size, pad, zorder=zorder, **kwargs)
|
914
938
|
to_return.append(aax)
|
915
939
|
if hawaii == True:
|
916
|
-
hax = inset_map(ax, "lower left", size, pad, **kwargs)
|
940
|
+
hax = inset_map(ax, "lower left", size, pad, zorder=zorder, **kwargs)
|
917
941
|
to_return.append(hax)
|
918
942
|
|
919
943
|
# Puerto Rico is positioned off the coast of Florida
|
920
944
|
if puerto_rico == True:
|
921
|
-
pax = inset_map(ax, "lower right", size, pad, **kwargs)
|
945
|
+
pax = inset_map(ax, "lower right", size, pad, zorder=zorder, **kwargs)
|
922
946
|
to_return.append(pax)
|
923
947
|
|
924
948
|
# DC is off the coast of DC
|
925
949
|
if dc == True:
|
926
|
-
dax = inset_map(ax, "center right", size, pad, **kwargs)
|
950
|
+
dax = inset_map(ax, "center right", size, pad, zorder=zorder, **kwargs)
|
927
951
|
to_return.append(dax)
|
928
952
|
|
929
953
|
# Finally, returning everything
|