使用matplotlib在地图图片上绘制轨迹

时间:2018-12-06 12:51:39

标签: python matplotlib plot

我有[x,y]对点的集合,这些点代表某些坐标,而照片则表示地图。我想在图片上画出由坐标对构成的轨迹。我尝试使用imshowfigimage,新轴offsetImageannotationBBox等,但是没有什么效果很好。例如,annotationBBox似乎是最好的选择,但是由于某种原因,它总是绘制在绘图的顶部,如果我将偏移量设置得太高,它将从最终绘图中完全消失。我无法手动imshow来裁剪图像,这很痛苦,而且figimage也不支持任何缩放功能。

我可以手动调整地图的坐标/旋转,直到一切正常为止。

我不想要一些GIS解决方案-地图和坐标是自定义的,与真实世界/ GPS坐标没有联系。

绘制坐标的示例代码:

import matplotlib.pyplot as plt
waypoints = [[0, -1, -4, -6, -6], [0, 0, 4, 4, 3]]
plt.plot(waypoints[0], waypoints[1], 'o-')
plt.grid(False)
plt.tick_params(axis='x', which='both', bottom=False, top=False, labelbottom=False)
plt.tick_params(axis='y', which='both', left=False, right=False, labelleft=False)
plt.show()

Original plot

地图示例:

Map

最终结果组合应如下所示:

Map+plot

1 个答案:

答案 0 :(得分:1)

在不同的坐标系中具有彼此对应的两对点可以定义系统之间的变换。您可以将此变换添加到直线的数据变换中,以使直线位于图像的坐标中。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.transforms import Affine2D

def get_transform_2pts(q1, q2, p1, p2):
    """ create transform to transform from q to p, 
        such that q1 will point to p1, and q2 to p2 """
    ang = np.arctan((p2-p1)[1] /(p2-p1)[0])-np.arctan((q2-q1)[1] /(q2-q1)[0])
    s = np.abs(np.sqrt(np.sum((p2-p1)**2))/np.sqrt(np.sum((q2-q1)**2)))
    trans = Affine2D().translate(*-q1).rotate(ang).scale(s).translate(*p1)
    return trans


image = plt.imread("https://i.stack.imgur.com/ue5oH.png")
y0 = image.shape[0]
waypoints = [[0, -1, -4, -6, -6], [0, 0, 4, 4, 3]]

# Coordinates for transformation.
lc1 = np.array([0,0])
ic1 = np.array([475, y0-187])

lc2 = np.array([-1, 0])
ic2 = np.array([437, y0-194])

trans = get_transform_2pts(lc1, lc2, ic1, ic2)

fig, ax = plt.subplots()

ax.imshow(np.flipud(image), origin="lower")

plt.plot(waypoints[0], waypoints[1], 'o-', transform=trans+ax.transData)

ax.set_aspect("equal")
plt.show()

enter image description here

或者如果您只想在线自动缩放,

fig, ax = plt.subplots()
ax.set_aspect("equal")

plt.plot(waypoints[0], waypoints[1], 'o-', transform=trans+ax.transData)

ax.autoscale(False)
ax.imshow(np.flipud(image), origin="lower")

plt.show()

enter image description here