A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/moss-xyz/matplotlib-map-utils below:

moss-xyz/matplotlib-map-utils: Tooling for creating maps with matplotlib

Documentation: See docs folder

Source Code: Available on GitHub

Feedback: I welcome any and all feedback! See the Development Notes below for more details.

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.

As of v3.x (the current version), this includes three-ish elements:

The three elements listed above are all intended to be high-resolution, easily modifiable, and context-aware, relative to your specific plot.

This package also contains a single utility object:

Together, these allow for the easy creation of a map such as the following:

This package is available on PyPi, and can be installed like so:

pip install matplotlib-map-utils

The requirements for this package are:

The package is arrayed in the following way:
package_name/
├── __init__.py
│
├── core/
│   ├── __init__.py
│   ├── inset_map.py
│   ├── north_arrow.py
│   ├── scale_bar.py
├── validation/
│   ├── __init__.py
│   ├── functions.py
│   └── inset_map.py
│   ├── north_arrow.py
│   └── scale_bar.py
├── defaults/
│   ├── __init__.py
│   ├── north_arrow.py
│   └── scale_bar.py
│   └── inset_map.py
├── utils/
│   ├── __init__.py
│   ├── usa.py
│   └── usa.json

Where:

Expand instructions

Importing the North Arrow functions and classes can be done like so:

from matplotlib_map_utils.core.north_arrow import NorthArrow, north_arrow
from matplotlib_map_utils.core import NorthArrow, north_arrow # also valid
from matplotlib_map_utils import NorthArrow, north_arrow # also valid

The quickest way to add a single north arrow to a single plot is to use the north_arrow function:

# Setting up a plot
fig, ax = matplotlib.pyplot.subplots(1,1, figsize=(5,5), dpi=150)
# Adding a north arrow to the upper-right corner of the axis, without any rotation (see Rotation under Formatting Components for details)
north_arrow.north_arrow(ax=ax, location="upper right", rotation={"degrees":0})

An object-oriented approach is also supported:

# Setting up a plot
fig, ax = matplotlib.pyplot.subplots(1,1, figsize=(5,5), dpi=150)
# Creating a north arrow for the upper-right corner of the axis, without any rotation (see Rotation under Formatting Components for details)
na = north_arrow.NorthArrow(location="upper right", rotation={"degrees":0})
# Adding the artist to the plot
ax.add_artist(na)

Both of these will create an output like the following:

Both the object-oriented and functional approaches can be customized to allow for fine-grained control over formatting:

north_arrow(
    ax,
    location = "upper right", # accepts a valid string from the list of locations
    scale = 0.5, # accepts a valid positive float or integer
    # each of the follow accepts arguments from a customized style dictionary
    base = {"facecolor":"green"},
    fancy = False,
    label = {"text":"North"},
    shadow = {"alpha":0.8},
    pack = {"sep":6},
    aob = {"pad":2},
    rotation = {"degrees": 35}
)

This will create an output like the following:

Refer to docs\howto_north_arrow for details on how to customize each facet of the north arrow.

The north arrow object is also capable of pointing towards "true north", given a CRS and reference point:

Instructions for how to do so can be found in docs\howto_north_arrow.

Expand instructions

Importing the Scale Bar functions and classes can be done like so:

from matplotlib_map_utils.core.scale_bar import ScaleBar, scale_bar
from matplotlib_map_utils.core import ScaleBar, scale_bar # also valid
from matplotlib_map_utils import ScaleBar, scale_bar # also valid

There are two available styles for the scale bars: boxes and ticks. The quickest way to add one to a single plot is to use the scale_bar function:

# Setting up a plot
# NOTE: you MUST set the desired DPI here, when the subplots are created
# so that the scale_bar's DPI matches!
fig, ax = matplotlib.pyplot.subplots(1,1, figsize=(5,5), dpi=150)
# Adding a scale bar to the upper-right corner of the axis, in the same projection as whatever geodata you plotted
# Here, this scale bar will have the "boxes" style
scale_bar(ax=ax, location="upper right", style="boxes", bar={"projection":3857})

An object-oriented approach is also supported:

# Setting up a plot
# NOTE: you MUST set the desired DPI here, when the subplots are created
# so that the scale_bar's DPI matches!
fig, ax = matplotlib.pyplot.subplots(1,1, figsize=(5,5), dpi=150)
# Adding a scale bar to the upper-right corner of the axis, in the same projection as whatever geodata you plotted
# Here, we change the boxes to "ticks"
sb = ScaleBar(location="upper right", style="ticks", bar={"projection":3857})
# Adding the artist to the plot
ax.add_artist(sb)

Both of these will create an output like the following (function is left, class is right):

Both the object-oriented and functional approaches can be customized to allow for fine-grained control over formatting:

scale_bar(
    ax,
    location = "upper right", # accepts a valid string from the list of locations
    style = "boxes", # accepts a valid positive float or integer
    # each of the follow accepts arguments from a customized style dictionary
    bar = {"unit":"mi", "length":2}, # converting the units to miles, and changing the length of the bar (in inches)
    labels = {"style":"major", "loc":"below"}, # placing a label on each major division, and moving them below the bar
    units = {"loc":"text"}, # changing the location of the units text to the major division labels
    text = {"fontfamily":"monospace"}, # changing the font family of all the text to monospace
)

This will create an output like the following:

Refer to docs\howto_scale_bar for details on how to customize each facet of the scale bar.

Expand instructions

Importing the Inset Map functions and classes can be done like so:

from matplotlib_map_utils.core.inset_map import InsetMap, inset_map, ExtentIndicator, indicate_extent, DetailIndicator, indicate_detail
from matplotlib_map_utils.core import InsetMap, inset_map, ExtentIndicator, indicate_extent, DetailIndicator, indicate_detail # also valid
from matplotlib_map_utils import InsetMap, inset_map, ExtentIndicator, indicate_extent, DetailIndicator, indicate_detail # also valid

The quickest way to add a single inset map to an existing plot is the inset_map function:

# Setting up a plot
fig, ax = matplotlib.pyplot.subplots(1,1, figsize=(5,5), dpi=150)
# Adding an inset map to the upper-right corner of the axis
iax = inset_map(ax=ax, location="upper right", size=0.75, pad=0, xticks=[], yticks=[])
# You can now plot additional data to iax as desired

An object-oriented approach is also supported:

# Setting up a plot
fig, ax = matplotlib.pyplot.subplots(1,1, figsize=(5,5), dpi=150)
# Creating an object for the inset map
im = InsetMap(location="upper right", size=0.75, pad=0, xticks=[], yticks=[])
# Adding the inset map template to the plot
iax = im.create(ax=ax)
# You can now plot additional data to iax as desired

Both of these will create an output like the following:

Extent and Detail Indicators

Inset maps can be paired with either an extent or detail indicator, to provide additional geographic context to the inset map

indicate_extent(inset_axis, parent_axis, inset_crs, parent_crs, ...)
indicate_detail(parent_axis, inset_axis, parent_crs, inset_crs, ...)

This will create an output like the following (extent indicator on the left, detail indicator on the right):

Refer to docs\howto_inset_map for details on how to customize the inset map and indicators to your liking.

Expand instructions

Importing the bundled utility functions and classes can be done like so:

from matplotlib_map_utils.utils import USA

As of v2.1.0, there is only one utility class available: USA, an object to help quickly filter for subsets of US states and territories. This utility class is still in beta, and might change.

An example:

# Loading the object
usa = USA()
# Getting a list FIPS codes for US States
usa.filter(states=True, to_return="fips")
# Getting a list of State Names for states in the South and Midwest regions
usa.filter(region=["South","Midtwest"], to_return="name")

Refer to docs\howto_utils for details on how to use this class, including with pandas.apply().

This project was heavily inspired by matplotlib-scalebar, and much of the code is either directly copied or a derivative of that project, since it uses the same "artist"-based approach.

Two more projects assisted with the creation of this script:

With the release of v3.x, this project has achieved full coverage of the "main" map elements I think are necessary.

If I continue development of this project, I will be looking to add or fix the following features:

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!

Support and Contributions

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!

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.

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.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4