在地图上的阴谋Python的Matplotlib底图覆盖小图像(Python Matplotlib

2019-06-26 07:40发布

我从飞机在地图上绘制的数据,我想通过飞机的29px PNG图像在对剧情的最新数据点的坐标插入此960x75像素。

飞机http://i45.tinypic.com/mslr86.jpg

据我所知,并已阅读, pyplot.imshow()是实现这一目标的最佳途径。 不过,我收到挂在步骤1中,得到了图像,甚至显示。 使用普通的情节,而不是底图,这是很容易获得的图像使用imshow出现,但使用时底图,我不能让它显示在所有。 见示例代码。

如果我能得到显示在地图上的图像,我假设我能,通过试验和错误,设置其位置,并且使用对于它的一些适当尺寸extent的属性imshow()随着剧情坐标从地图转换坐标x,y = m(lons,lats)

下面是示例代码(尝试它,你可能要下载上方的飞行器图像)。

from matplotlib import pyplot as plt
from mpl_toolkits.basemap import Basemap
import Image
from numpy import arange

lats = arange(26,29,0.5)
lons = arange(-90,-87,0.5)

m = Basemap(projection='cyl',llcrnrlon=min(lons)-2,llcrnrlat=min(lats)-2,
            urcrnrlon=max(lons)+2,urcrnrlat=max(lats)+2,resolution='i')

x,y = m(lons,lats)
u,v, = arange(0,51,10),arange(0,51,10)
barbs = m.barbs(x,y,u,v)
m.drawcoastlines(); m.drawcountries(); m.drawstates()

img = Image.open('c130j_75px.png')
im = plt.imshow(img, extent=(x[-1],x[-1]+50000,y[-1],y[-1]+50000))
plt.show()

这里的最终图像,不包含飞机的踪迹。 我已经尝试使用几个不同大小extent ,想我可能只是做它太小了,但没有成功。 我也试着设置zorder=10 ,也没有运气。 任何帮助,将不胜感激。

导致http://i45.tinypic.com/35mgnev.jpg

更新:我现在可以得到的图像通过使用至少出现m.imshow代替plt.imshow ,因为地图的坐标轴例如前传球,但extent说法似乎对图像的尺寸没有影响,因为它总是充满了整个情节不管我怎么做小extent的尺寸,即使我把它们设置为零。 我怎样才能恰当地缩放图像的飞机,它的最后一个数据点附近的位置?

im = m.imshow(img, extent=(x[-1],x[-1]+5,y[-1],y[-1]+2))

RESULT2 http://i50.tinypic.com/2ntdy0o.jpg

Answer 1:

其实,这要使用matplotlib的有些无证的特点: matplotlib.offsetbox模块。 这里有一个例子: http://matplotlib.sourceforge.net/trunk-docs/examples/pylab_examples/demo_annotation_box.html

在你的情况,你会做这样的事情:

import matplotlib.pyplot as plt
import numpy as np
import Image

from mpl_toolkits.basemap import Basemap
from matplotlib.offsetbox import OffsetImage, AnnotationBbox

# Set up the basemap and plot the markers.
lats = np.arange(26, 29, 0.5)
lons = np.arange(-90, -87, 0.5)

m = Basemap(projection='cyl',
            llcrnrlon=min(lons) - 2, llcrnrlat=min(lats) - 2,
            urcrnrlon=max(lons) + 2, urcrnrlat=max(lats) + 2,
            resolution='i')

x,y = m(lons,lats)
u,v, = np.arange(0,51,10), np.arange(0,51,10)
barbs = m.barbs(x,y,u,v)

m.drawcoastlines()
m.drawcountries()
m.drawstates()

# Add the plane marker at the last point.
plane = np.array(Image.open('plane.jpg'))
im = OffsetImage(plane, zoom=1)
ab = AnnotationBbox(im, (x[-1],y[-1]), xycoords='data', frameon=False)

# Get the axes object from the basemap and add the AnnotationBbox artist
m._check_ax().add_artist(ab)

plt.show()

其优点是,这架飞机是在轴坐标和变焦时的相对同样大小将留到图形的大小。



Answer 2:

随着底图,一般来说您可以正常使用pyplot风格的命令,如果你翻译首先使用地图实例的坐标。 在这种情况下,你可以转换成程度与UV坐标:

x0, y0 = m(x[-1], y[-1])
x1, y1 = m(x[-1] + 0.5, y[-1] + 0.5)

而随后你就可以做到:

im = plt.imshow(img, extent=(x0, x1, y0, y1))

我充分的解决了这个样子:

import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
import numpy as np


lats = np.arange(26, 29, 0.5)
lons = np.arange(-90, -87, 0.5)

m = Basemap(projection='cyl', llcrnrlon=min(lons)-2, llcrnrlat=min(lats)-2,
            urcrnrlon=max(lons)+2, urcrnrlat=max(lats)+2, resolution='h')

x, y = m(lons,lats)
u, v = np.arange(0, 51, 10), np.arange(0, 51, 10)
barbs = m.barbs(x, y, u, v)

m.drawcoastlines()
m.fillcontinents()

x_size, y_size = 0.8, 0.4
x0, y0 = m(x[-1] - x_size/2., y[-1] - y_size/2.)
x1, y1 = m(x[-1] + x_size/2., y[-1] + y_size/2.)
im = plt.imshow(plt.imread('mslr86.png'), extent=(x0, x1, y0, y1))

plt.show()

其产生看起来像一个图像

更新:如果你想要的形象仍然是一个固定大小的,独立的变焦,看到乔的回答。



文章来源: Python Matplotlib Basemap overlay small image on map plot