Regis
Regis

Reputation: 71

how to add a "North Arrow" on a geopandas map

I created a map using geopandas, but I am unable to add a "North Arrow" on the map.

After creating the map, I have tried to add the "north arrow" using matplotlib.image module and tried different ways (see example below) but none of them provided a good result. I am looking for better code that can add a good "North Arrow to the map"

import matplotlib.image as img

from matplotlib.offsetbox import TextArea, DrawingArea, OffsetImage, 
    AnnotationBbox

im=img.imread(r'C:\Users\jnisengw\Dropbox\2019\Data 
    Science\QGIS\north_arrow1.png')

imagebox = OffsetImage(im,zoom=0.27)

ab = AnnotationBbox(imagebox, (598500,4699000))

ax.add_artist(ab)

Upvotes: 7

Views: 11732

Answers (4)

moss_xyz
moss_xyz

Reputation: 29

(Disclosure: I am the owner of the linked repo)

For those coming across this question via a search engine of some sort, a new package exists to help with this: matplotlib-map-utils.

It features a dedicated function (north_arrow()) and class (NorthArrow) for creating these objects, with the ability to customize many aspects of its appearance. It can also account for a projected coordinate system, if one is passed as an argument, by rotating the arrow to point to "true" north.

By way of example:

# Importing
from matplotlib_map_utils.core.north_arrow import NorthArrow, north_arrow
# 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, 
# in the same projection as whatever geodata you plotted
north_arrow(ax=ax, location="upper right", rotation={"crs":3857, "reference":"center"})

rendered north arrow on a plot

See docs\howto_north_arrow in the GitHub repo for more details on customizing the arrow to suit your needs.

Upvotes: 0

pds
pds

Reputation: 2582

Another possibility is create a Polygon, and plot it into your matplotlib ax (there are some other solutions like this in this SO question and here).

The geo_northarrow library (GNUv3) does this by plotting the north arrow polygons to the matplotlib axes.

import geopandas
import geodatasets
from geo_northarrow import add_north_arrow

chicago = geopandas.read_file(geodatasets.get_path("geoda.chicago_commpop"))
groceries = geopandas.read_file(geodatasets.get_path("geoda.groceries"))
display(chicago.head())
ax = chicago.plot(column="POP2010");

add_north_arrow(ax, scale=.75, xlim_pos=.9025, ylim_pos=.965, color='#000', text_scaler=4, text_yT=-1.25)

enter image description here

* NB: Limitation - This library is only suitable for maps with north-south axis alignment exactly to the y-axis; as it lacks a north-orientation lookup and rotation.

Upvotes: 1

raphael
raphael

Reputation: 2970

In case somebody still needs this...
EOmaps v3.1 now has a proper north-arrow and interacts nicely with geopandas!

from eomaps import Maps
m = Maps()
m.add_feature.preset.ocean()
m.add_compass(style="north arrow")

EOmaps - compass

Upvotes: 1

steven
steven

Reputation: 2519

If you only need to add a simple arrow, you can also consider the annotate() method.

import geopandas as gpd
import matplotlib.pyplot as plt

gdf = gpd.read_file(gpd.datasets.get_path('nybb'))

fig, ax = plt.subplots(figsize=(6, 6))
gdf.plot(ax=ax)

x, y, arrow_length = 0.5, 0.5, 0.1
ax.annotate('N', xy=(x, y), xytext=(x, y-arrow_length),
            arrowprops=dict(facecolor='black', width=5, headwidth=15),
            ha='center', va='center', fontsize=20,
            xycoords=ax.transAxes)

enter image description here

Notes: When you pass xycoords=ax.transAxes, the x, y coordinate is normalized, and x, y = 0.5, 0.5 means you put the arrowhead in the middle of your map.

Upvotes: 12

Related Questions