Python 使用matplotlib在地图图片顶部绘制轨迹

Python 使用matplotlib在地图图片顶部绘制轨迹,python,matplotlib,plot,Python,Matplotlib,Plot,我有一个[x,y]对点的集合,代表一些坐标,还有一张代表地图的图片。我想在图片的顶部绘制由坐标对构成的轨迹。我试着使用imshow、figimage、新的axesoffsetimage、annotationBBox等等,但没有什么效果。例如,annotationBBox似乎是最佳选择,但出于某种原因,它总是在绘图顶部绘制,如果我将偏移设置得太高,它将从最终绘图中完全消失。我无法让imshow在不手动操作的情况下裁剪图像,这是一件痛苦的事情,而且figimage也不支持任何类型的缩放功能 我可以手

我有一个[x,y]对点的集合,代表一些坐标,还有一张代表地图的图片。我想在图片的顶部绘制由坐标对构成的轨迹。我试着使用imshow、figimage、新的axesoffsetimage、annotationBBox等等,但没有什么效果。例如,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()
示例地图:

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


在不同的坐标系中有两对相互对应的点可以定义系统之间的变换。可以将此变换添加到线的数据变换中,以获得图像坐标中的线

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()
或者如果只想在线自动缩放

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()

您需要有一些关系,将图像范围映射到数据坐标,或者将数据映射到图像坐标。如果你有这些,我建议用Pygmap在地图上绘图。您可以定义由具有纬度、经度坐标的点组成的路径。您可以使用plotly或其他类似的库。可能我在这里不清楚。只需两个坐标对即可明确确定线数据和图像数据之间的坐标变换。不需要任何特殊的库或其他外部源。但如果没有坐标对,就无法正确定位线wrt。图像,反之亦然。我已经有了,例如[0,0]在图片上是[475187],[1,0]是[437194]等等。我不知道的是如何实际绘制这个-为了绘制图片的一部分,使用matplotlib中的什么功能,然后在上面绘制一些东西。plotly库使用GIS/latlong坐标,所以我不确定它在这种情况下是否有用。回答很好,谢谢!有没有办法放大包含数据的图像部分,使其看起来像我问题中的图片?