如何在Geopandas地图上添加“指北针”

6

我使用geopandas创建了一个地图,但是我无法在地图上添加“指北针”。

在创建地图后,我尝试使用matplotlib.image模块添加“指北针”,并尝试了不同的方法(见下面的示例),但它们都没有提供良好的结果。我正在寻找更好的代码,可以在地图上添加好的“指北针”。

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)


我们无法看到您的图片。您需要在此处发布图片(不是第三方链接、Dropbox等)。 - smci
类似于这个技术 https://dev59.com/4VsW5IYBdhLWcg3w66qH#34459284 - Paul H
https://www.net-analysis.com/blog/cartopylayout.html - steven
3个回答

11

如果只需要添加一个简单的箭头,您也可以考虑使用annotate()方法

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

注意:当您传递xycoords=ax.transAxes时,x、y坐标将被标准化,x, y = 0.5, 0.5表示您将箭头放在地图中心。


这是否会尊重地图投影呢?我想只有当xycoords设置为"data"时才会。 - jasmit
这是否会尊重地图投影呢?我猜只有当xycoords设置为"data"时才会。 - undefined
xycoords只影响箭头的位置,不与形状数据交互。我相信如果您使用圆柱投影,无论坐标参考系统如何,北方仍将保持为北方。然而,如果您旋转地图,当然,情况就不同了。 - steven
xycoords 只影响箭头的位置,不会影响形状数据。我相信如果你使用柱面投影,无论坐标参考系统如何,北方都会保持不变。但是,如果你旋转地图,当然情况就不同了。 - undefined

1
如果还有人需要,EOmaps v3.1现在有一个合适的指北针,并且可以与geopandas互动!
from eomaps import Maps
m = Maps()
m.add_feature.preset.ocean()
m.add_compass(style="north arrow")

EOmaps - compass


1
另一种可能性是创建一个优雅的多边形,并将其绘制到你的matplotlib图表中(在这个stackoverflow问题中有一些类似的解决方案)。
注意:你必须自己定义实际的北方方向。

enter image description hereenter image description here

以下是用于转换/缩放多边形的代码。
import shapely.plotting
from shapely.geometry import Polygon

def plot_north_arrow( ax, xT=0, yT=0, scale=1 ):
    def t_s(t,xT,yT,s):
        x,y = t
        return (xT+(x*s),yT+(y*s))
    a = [(0, 5), (0, 1), (2, 0)]
    b = [(0, 5), (0, 1), (-2, 0)]
    t_pos = (0.25,6)
    t_pos_x,t_pos_y = t_s(t_pos,xT,yT,scale)
    polygon1 = Polygon( [t_s(t,xT,yT,scale) for t in a] )
    polygon2 = Polygon( [t_s(t,xT,yT,scale) for t in b] )
    shapely.plotting.plot_polygon(polygon1, add_points=False, ax=ax, color=None, facecolor='None', edgecolor='k', linewidth=2)
    shapely.plotting.plot_polygon(polygon2, add_points=False, ax=ax, color=None, facecolor='k', edgecolor='k', linewidth=None)
    ax.text(x=t_pos_x,y=t_pos_y,s='N', fontsize='medium',
            ha='center',
            va='center',weight='bold')
    
fig, ax = plt.subplots(figsize=(2,3))
#...
#... your mapping code...
#...
plot_north_arrow( ax, xT=10, yT=25, scale=2 )

# 
# -- Just for the sample plots.
_ = ax.set_xlim(0,50)
_ = ax.set_ylim(0,50)
ax.set_facecolor((1.0, 0.47, 0.42))

我相信 Shapely.plotting 是在 v2.0.1 版本中添加的,所以你需要执行 pip install shapely==2.0.1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接