Python Matplotlib底图在地图上覆盖小图像 [英] Python Matplotlib Basemap overlay small image on map plot

查看:1614
本文介绍了Python Matplotlib底图在地图上覆盖小图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在地图上绘制飞机上的数据,我想在地图上最新数据点的坐标处插入这张75px乘29px的飞机PNG图像。

I am plotting data from an aircraft on a map and I would like to insert this 75px by 29px PNG image of an airplane at the coordinates of the latest data point on the plot.

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

据我所知并已阅读, pyplot.imshow()是最好的方式完成这个。但是,我在第1步被挂起,让图像均匀显示。使用普通图而不是Basemap,使用imshow很容易让图像显示,但是当使用Basemap时,我根本无法显示它。请参阅示例代码。

As far as I know and have read, pyplot.imshow() is the best way to accomplish this. However, I am getting hung up on step 1, getting the image to even display. Using a normal plot instead of Basemap, it is easy enough to get the image to appear using imshow, but when using Basemap, I can't get it to show up at all. See the example code.

如果我可以在地图上显示图像,我假设我可以通过反复试验确定其位置和一些正确的使用 imshow()范围属性的尺寸,其中绘图坐标从地图坐标<$ c转换而来$ c> x,y = m(lons,lats)。

If I can get the image to display on the map, I am assuming that I can, by trial and error, set its position and some proper dimensions for it using the extent attribute of imshow(), with the plot coordinates converted from the map coordinates x,y = m(lons,lats).

以下是示例代码(尝试一下,您可能要下载上面的飞机图片。

Here is the example code (to try it you may want to download the airplane image above).

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 ,但也没有运气。任何帮助将不胜感激。

Here's the resulting image, which doesn't contain a trace of the airplane. I have tried several different sizes using extent, thinking I may have just made it too small, but with no success. I also tried setting zorder=10, but also with no luck. Any help would be appreciated.

结果http://i45.tinypic。 com / 35mgnev.jpg

更新:我现在可以使用 m.imshow 而不是 plt.imshow ,因为前者传入地图的轴实例,但范围参数似乎对图像的尺寸没有任何影响,因为它总是填满整个图,无论我做多小,范围尺寸,即使我将它们设置为零。如何适当缩放飞机图像并将其定位在最后一个数据点附近?

Update: I can now get the image to at least appear by using m.imshow instead of plt.imshow, since the former passes in the map's axes instance, but the extent argument seems to have no effect on the dimensions of the image, as it always fills up the entire plot no matter how small I make extent dimensions, even if I set them to zero. How can I scale the airplane image appropriately and position it near the last data point?

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

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

推荐答案

实际上,为此您要使用matplotlib的一些未记录的功能: matplotlib.offsetbox 模块。这里有一个例子: http://matplotlib.sourceforge.net/trunk- docs / examples / pylab_examples / demo_annotation_box.html

Actually, for this you want to use a somewhat undocumented feature of matplotlib: the matplotlib.offsetbox module. There's an example here: http://matplotlib.sourceforge.net/trunk-docs/examples/pylab_examples/demo_annotation_box.html

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

In your case, you'd do something like this:

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

这样做的好处是飞机是在轴坐标中,相对于放大时的图形大小,它将保持相同的大小。

The advantage to this is that the plane is in axes coordinates and will stay the same size relative to the size of the figure when zooming in.

这篇关于Python Matplotlib底图在地图上覆盖小图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆