Reputation: 71
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
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"})
See docs\howto_north_arrow
in the GitHub repo for more details on customizing the arrow to suit your needs.
Upvotes: 0
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)
* 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
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")
Upvotes: 1
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)
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